人人都能懂的机器学习——训练深度神经网络——优化算法2

RMSProp

AdaGrad的学习率降低得太快,并且最终也不会收敛到全集最优值。而RMSProp算法16通过使用指数衰减,从而只会积累最近几次迭代的梯度,解决了上述AdaGrad的问题。

RMSProp算法是由Geoffrey Hinton和Tijmen Tieleman在2012年提出的,并且Geoffrey Hinton在Coursera上有一节关于神经网络的课程上展示了这种算法。有趣的是,由于作者没有写任何论文来描述这种算法,所以研究人员只能在论文中引用“第6讲中的第29页幻灯片”。

接下来让我们看一下这个算法的方程:

衰减指数β一般设置为0.9。是的,又是一个新的超参数,但是不用担心,这个默认值一般表现得都不错,所以你完全不需要调优。

当然对于RMSProp算法,Keras也有相应部署完成的功能:

optimizer = keras.optimizers.RMSprop(lr=0.001, rho=0.9)

除了一些非常简单的问题,RMSProp几乎总是表现得比AdaGrad更出色。实际上,在Adam优化器出现之前,RMSProp是很多研究人员的优先选择。

Adam 和Nadam优化器

Diederik P. Kingma和Jimmy Ba于2015年提出了Adam优化器。所谓Adam是指自适应矩估计(adaptive moment estimation),它结合了动量优化器和RMSProp的想法:就像动量优化,它跟踪了过去梯度的指数衰减平均值;同时又像RMSProp,它跟踪了梯度平方的指数衰减平均值。
m\leftarrow\beta_{1}m-(1-\beta_{1})\nabla_{\theta}J(\theta)\\\\ s\leftarrow\beta_{2}s+(1-\beta_{2})\nabla_{\theta}J(\theta)^2 \\\\ \hat{m}\leftarrow m/(1-\beta_{1}^{t}) \\\\ \hat{s}\leftarrow s/(1-\beta_{2}^{t}) \\\\ \theta \leftarrow \theta + \eta \hat{m} /(\hat{s}+\epsilon)
方程这些是对梯度的平均值和方差的估计。均值常称为一阶矩,而方差常称为二阶矩,这就是算法的名称由来。在上述方程中,t代表的是循环次数(从1开始)。

如果只看第1第2和第5步,其实Adam与动量优化和RMSProp都很相近。唯一的区别是在第1步中计算了指数衰减平均值,而不是指数衰减和,但是除了一个常数因子以外,它们实际上是等价的(衰减平均值等于1–β1乘以衰减和)。第3步和第4步有一些技术性细节:因为ms初始化为0,在训练开始时,它们将偏向于0,所以这两个步骤在训练开始加速ms

动量衰减超参数β1一般设置为0.9,缩小衰减超参数一般设置为0.999,平滑项ε一般设置为一个很小的数,比如10-7。这些都是Keras中Adam类的默认值(epsilon参数默认值为None,也就是使用keras.backend.epsilon(),它的默认值也就是10-7,如果需要更改值,则使用keras.backend.set_epsilon())。使用Keras创建Adam优化器也十分简单:

optimizer = keras.optimizers.Adam(lr=0.001, beta_1=0.9, beta_2=0.999)

Adam也是一种自适应学习率的算法(跟AdaGrad和RMSProp一样),所以它基本不需要对学习率η进行调优。一般学习率的默认值设为η=0.001,这样使用Adam会比使用普通的梯度下降更方便。

这里再介绍一种Adam的变体:Nadam。其实Nadam是Adam优化器与Nesterov方法的结合,这意味着Nadam会收敛地更快。作者Timothy Dozat在2016年发表的论文中比较了多种任务下多种优化器的表现,结果表明Nadam总是要比Adam表现更出色,但有时会被RMSProp超越。

自适应优化器(包括RMSProp,Adam和Nadam)往往表现得很出色,收敛得又快又准确。但是,Ashia C. Wilson在2017年发表的论文中指出,自适应优化器可能在某些数据集上会得到泛化能力很差的结果。所以,当你对你的模型表现很不满意时,可能是你的数据集对自适应梯度比较敏感,可以尝试一下使用Nesterov梯度加速法。

目前所有讨论的优化技术都只依赖于一阶偏导数(雅可比矩阵)。有些优化技术的文献提出了惊人的基于二阶偏导数(Hessians矩阵,这是雅可比矩阵的偏导数)的优化算法。不幸的是,这些算法都不适用于深度神经网络,因为每个输出神经元都有n2个Hessians (其中n是参数数量)。由于DNN通常有上万个参数,二阶优化算法经常无法完整读取进入内存,就算可以进入内存,Hessians的计算速度也实在太慢了。

前面介绍的所有的优化算法只是产生密集型的模型,这意味着大多数参数将是非零的。如果在运行时需要一个非常快的模型,或者如果需要它占用更少的内存,那么会需要使用稀疏模型。

一个简单的方法就是正常训练模型,然后将小的权重去掉(直接设置成0)。但是要注意,这一般不会导致生成一个非常稀疏的模型,并且这种做法会降低模型的性能。

另一个更好的做法是,使用一个强l1正则化训练(在未来的文章中会介绍),这个方法会让优化器将尽可能多的权重推向0。

如果上述的技术还是效率不高,可以尝试使用TensorFlow Model Optimization Toolkit (TF-MOT),这个优化工具包提供了模型修剪API可以迭代反复地基于权重量级删去权重连接。

最后,我们比较一下所有介绍过的优化器,一颗*表示不好,三个*表示优秀。

种类 收敛速度 收敛质量
SGD * ***
SGD(动量) ** ***
SGD(动量+Nesterov) ** ***
Adagrad *** *(早停)
RMSProp *** ***
Adam *** ***
Nadan *** ***
Adamax *** ***

以上就是对几乎所有常用优化器的介绍了,接下来的文章我们将会讲述学习率规划以及防止过拟合的手段。

敬请期待吧!

你可能感兴趣的:(人人都能懂的机器学习——训练深度神经网络——优化算法2)