提高模型性能,你可以尝试这几招...

   日期:2024-12-19    作者:teligu 移动:http://3jjewl.riyuangf.com/mobile/quote/7777.html

在EZDL到底怎样,试试看…一文中,我尝试了百度推出的在线人工智能设计平台EZDL,其愿景是任何人不用编写一行代码就可以轻松地构建、设计和部署人工智能(AI)模型。从试用效果上看,确实不需要编写一行代码,也不需要什么人工智能知识。但对于一名程序员而言,将人工智能包装到一个黑盒子中,而自己毫无掌控感,总有那么一点不踏实。

提高模型性能,你可以尝试这几招...

如果是自己动手构建模型、训练、预测,哪些地方是我们可以掌控的呢?本文延续EZDL到底怎样,试试看…一文中最后提出的一个问题模型的准确率为88.82%,我要提高准确率该怎么做,来谈谈提高模型性能,我们能够采取哪些措施。在一步步提高手写数字的识别率系列文章中,我有简单的谈到如何优化模型,这篇文章将更进一步探讨优化模型的方法。

我们还是以手写数字识别为例,代码改为使用keras框架实现,这里不贴代码,有兴趣的话请至我的github: https://github.com/mogoweb/aiexamples 查看,本文的示例代码位于keras/multi_layer_perceptron目录下。

手写数字识别最简单的实现算法是采用逻辑回归,因为是多分类问题,最后的输出使用softmax代替sigmoid。当然,你也可以把它看做仅有一层的简单神经网络,代码请查看如下链接

https://github.com/mogoweb/aiexamples/blob/master/keras/multi_layer_perceptron/mlp.py

经过200次迭代,训练结束后,模型在训练集上的准确率为92.36%,验证集上的准确率为92.27%,测试集上的准确率为92.22%。这意味着10个手写数字中只有不到一个没有被正确识别,一个不错的起点。

下面以此作为基线精度,比较不同的优化方法对性能提升的效果。

增加隐藏层

很自然的,我们可以想到第一个改进方法,为模型添加更多的层:

完整代码请参阅

https://github.com/mogoweb/aiexamples/blob/master/keras/multi_layer_perceptron/mlp_v2.py

增加的中间层称为隐藏层(hidden layer),这里只添加了一个具有N_HIDDEN个神经元并使用ReLU激活函数的全连接层(Dense)。增加隐藏层,迭代20次之后,训练集上的准确率即可达到94.50%,验证集上为94.63%,测试集上为94.41%。虽然从准确率上看只提高了2.2%,但迭代次数可以大大减少。实际上如果同样迭代200次,准确率还可以提升。

那是不是我们增加更多的层,得到的准确率就会更高呢?事实上并非如此,经过尝试,比如在隐藏层数为5时,在训练集、验证集和测试集上的准确率分别为96.5%、95.99%、96.05%,而隐藏层数增加到10时的准确率依次为95.41%、95.47%、95.14%,准确率反而有所下降。所以神经网络的层数并非越多越好,层数过多,对提升准确率并没有什么帮助,由此还有可能带来模型复杂、训练时间增加等不良后果。

增加神经元的数量

从上面可以知道,适当增加隐藏层可以提升准确率,那增加神经元的数量,是否可以提升准确率?让我们以数据说话

从图中可以看出,神经元数量从32增加到128,准确率有非常明显的提升,但再往上增加神经元的数量,对准确率的提升就不那么明显了。与此同时,我们也需要了解到,增加模型的复杂性,运行时间也显著增加,因为有更多的参数需要优化。

这幅图显示了神经元数量与训练参数数量之间的关系。

从上图可以看到,随着神经元的增多,每次迭代所需的时间大幅增长。

小结一下,适当增加神经元的数量,对准确率提升有帮助,但也不是越大越好。

使用dropout策略

简单说,dropout策略就是随机丢弃一些神经元节点,不参与计算,为什么这种策略能够奏效,在Andrew NG的改善深层神经网络:超参数调试、正则化以及优化课程中有很清晰的讲解

在keras中实现dropout策略非常简单,只需在隐藏层后面增加一个Dropout层:

进行20次迭代,训练集上的准确率91.54%,验证集上为94.48%,测试集上为94.25%。注意这里训练集上的准确率低于测试集上的,说明训练的轮次不够。将训练轮次增加至250,准确率数据依次为98.1%、97.73%和97.7%。

由于引入了dropout策略,需要增加训练轮次,当然我们不能无限增加训练轮次,因为训练轮次增加,意味着训练时间的增加,还是用数据说话

从图中可以看到,两条曲线在约250轮时相交,而这一点之后就有必要进一步训练了。

选择不同的优化器

在上面的代码中,我们使用了SGD优化器,SGD称为随机梯度下降(Stochastic Gradient Descent,SGD)。除了SGD,还有RMSprop和Adam这两种更先进的优化技术,它们引入了动量(速度分量)的概念,当然实现上更加复杂。不过在keras中,只是一行代码的事情

这是使用RMSprop优化器的曲线图,可以看到RMSprop比SGD快,在20次迭代后,在训练集上达到97.97%的准确率,验证集上97.59%,测试集上为97.84%。

这是使用Adam优化器的曲线图,效果更好一些,训练20轮之后,在训练集上的准确率达到了98.28%,验证集上达到了98.03%,测试集上达到了97.93%。

调整批次大小(BATCH_SIZE)

让我们修改一下BATCH_SIZE的大小,然后看看对准确率有和影响

如图所示,BATCH_SIZE需要选择一个合适的值,对于本例而言,最优的准确率在BATCH_SIZE=128时取得。

采用更合适的模型结构

在一步步提高手写数字的识别率(3)中,我们提到了一种提升手写数字识别率的模型:卷积神经网络CNN。对于图像相关的神经网络,通常卷积神经网络可以取得比全连接网络更好的效果,而对于文本处理、语音识别等,则循环神经网络RNN更加有效。

总结

本文仅仅从工程的角度探讨了如何提高模型性能,并给出了示例代码,在实际项目中,关于模型调优是一个很复杂的工程,需要从很多方面考量。本文也没有对其中涉及的理论有过多的深入,有兴趣的朋友推荐大家看一看Andrew NG的深度学习课程改善深层神经网络:超参数调试、正则化以及优化,在网易云课堂上是免费的课程。

参考
  1. Keras深度学习实战,Antonio Gulli/Sujit Pal,人民邮电出版社
  2. 改善深层神经网络:超参数调试、正则化以及优化,Andrew NG
往期回顾

一步步提高手写数字的识别率(1)
keras中的数据集
理解keras中的sequential模型
百度推出EZDL,编程小白也可训练AI
EZDL到底怎样,试试看…


特别提示:本信息由相关用户自行提供,真实性未证实,仅供参考。请谨慎采用,风险自负。


举报收藏 0评论 0
0相关评论
相关最新动态
推荐最新动态
点击排行
{
网站首页  |  关于我们  |  联系方式  |  使用协议  |  隐私政策  |  版权隐私  |  网站地图  |  排名推广  |  广告服务  |  积分换礼  |  网站留言  |  RSS订阅  |  违规举报  |  鄂ICP备2020018471号