前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >提高模型性能,你可以尝试这几招...

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

作者头像
云水木石
发布2019-07-01 17:28:24
9800
发布2019-07-01 17:28:24
举报

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个手写数字中只有不到一个没有被正确识别,一个不错的起点。

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

增加隐藏层

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

代码语言:javascript
复制
NB_CLASSES = 10  # 输出类别数量
N_HIDDEN = 128
# X_train是60000个28*28的数据,窄化为60000*784
RESHAPE = 784model = Sequential()
model.add(Dense(N_HIDDEN, input_shape=(RESHAPE, )))
model.add(Activation('relu'))
model.add(Dense(N_HIDDEN))
model.add(Activation('relu'))
model.add(Dense(NB_CLASSES))
model.add(Activation('softmax'))

完整代码请参阅:

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层:

代码语言:javascript
复制
model = Sequential()
model.add(Dense(N_HIDDEN, input_shape=(RESHAPE, )))
model.add(Activation('relu'))
model.add(Dropout(DROPOUT))
model.add(Dense(N_HIDDEN))
model.add(Activation('relu'))
model.add(Dropout(DROPOUT))
model.add(Dense(NB_CLASSES))
model.add(Activation('softmax'))

进行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中,只是一行代码的事情:

代码语言:javascript
复制
OPTIMIZER = RMSprop()

代码语言:javascript
复制
OPTIMIZER = Adam()

这是使用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
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-09-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 云水木石 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 增加隐藏层
  • 增加神经元的数量
  • 使用dropout策略
  • 选择不同的优化器
  • 调整批次大小(BATCH_SIZE)
  • 采用更合适的模型结构
  • 总结
  • 参考
相关产品与服务
语音识别
腾讯云语音识别(Automatic Speech Recognition,ASR)是将语音转化成文字的PaaS产品,为企业提供精准而极具性价比的识别服务。被微信、王者荣耀、腾讯视频等大量业务使用,适用于录音质检、会议实时转写、语音输入法等多个场景。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档