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

更快速的优化器

训练一个非常深的神经网络可能会慢得让人绝望。那么之前的文章已经介绍了四种加速训练(并得到更好结果)的方法:使用合适的初始化方法,合适的激活函数,使用批标准化,以及预训练模型的重用。本文想要介绍的是另一种能够极大加速训练的方法:用更快速的优化器替代普通的梯度下降优化器。那么我们将展示一些最常用的优化器。

动量优化,Nesterov加速梯度,AdaGrad,RMSProp以及Adam和Nadam优化。这里一下子列出好多专业词汇,由于它们大多是几个单词的缩略,或者是人名,又没有对应的很统一的中文说法,所以只能暂且搁置在这里。下面我们将对它们一一解释。

动量优化

让我们想象一个保龄球从一个斜坡上滚下来,它初速度并不大,但是它的动量会越来越大,直到最终达到最大速度(由于可能有摩擦力等等)。其实这就是Boris Polyak在1964年提出的动量优化背后的核心思想。而常规的梯度下降只会一步一步匀速地下坡,那么模型收敛就会需要消耗大量的时间。

让我们回顾一下梯度下降法,梯度下降更新权值θ的方法是权值θ直接减去学习率η与损失函数J(θ)对于权重的梯度的乘积。这个方法并不关心上一次计算的梯度是什么,那么如果局部的梯度很小,那么下降速度会非常缓慢。

那么动量优化就非常关心之前的梯度是什么:在每一轮训练中,它从动量向量m中减去局部梯度(乘以学习率),然后加权重,就完成了权重更新(见下式)。换句话说,梯度是用来加速的,并不是用来决定速度的。为了模拟摩擦力的存在,防止动量变得过大,这个算法引入了一个新的超参数β,称为动量。动量的值设置在0(代表高摩擦)和1(代表无摩擦)之间,一般设置为0.9。

我们可以验证,如果梯度保持不变,那么最终速度(也就是权重更新的最大速度)等于梯度乘以学习率再乘以1/(1-β)。比如设β=0.9,那么最终速度就等于梯度乘以学习率乘以10,也就是说动量优化最终会比梯度下降的速度快10倍。这使得动量优化能够比梯度下降更快速地逃离梯度较小的区域。当各特征输入值的数值范围很不同时,损失函数就会像是一个细长的碗。梯度下降在陡坡上下降的速度很快,但是要走下山谷需要很长的时间。相反,动量优化就会越来越快地沿着山谷向下滚动,直到达到底部最优。在深度神经网络中,如果没有使用批标准化方法,那么上层网络的输入数值范围可能差异很大,这种情况下使用动量优化可能会很有用。并且动量优化还可以很轻松地“滚”出局部最优点。

由于动量的存在,优化器可能会滚过最优点,然后再回来,然后在最优点附近震荡许多次。这也是需要在算法中加入一些阻力的原因之一,它可以减少震荡,使之快速收敛。

在Keras中使用动量优化是很傻瓜式的,只需要选择SGD优化器,然后设置momentum超参数,就可以了。就像这样:

optimizer = keras.optimizers.SGD(lr=0.001, momentum=0.9)

动量优化有一个缺点,那就是它多了一个超参数需要调整。不过,动量参数的默认值0.9一般都表现不错,并且比梯度下降快得多。

Nesterov加速梯度

Yurii Nesterov在1983年提出了动量优化的一个小的变体,并且总会比原本的方法要更快。Nesterov动量优化,或者叫Nesterov加速梯度(Nesterov Accelerated Gradient,NAG),并不根据当前权重点来计算损失函数的梯度,而是根据动量方向,在θ+βm点计算梯度,见下式:

这个小调整是有效的,因为一般动量矢量指向的是正确的方向(即最优点),所以使用动量方向上的一点的梯度会比使用原点的梯度稍微更准确一些。从图2.6中可以看出,∇1是在起始点θ处的损失函数梯度,∇2是在θ+βm处计算出的损失函数梯度。Nesterov动量法会比普通的动量优化方法要快一点点。另外,当动量将权重推过一个峡谷,∇1仍然会将权重来回推过峡谷,而∇2将权重直接推向峡谷的底部。这样会减少最后最终收敛的振动,因此NAG的收敛速度将更快。

NAG一般比常规的动量优化更快,那么在实际操作中,只需在创建SGD优化器时,设置nesterov=True即可:

optimizer = keras.optimizers.SGD(lr=0.001, momentum=0.9, nesterov=True)
图2.6 普通动量优化与Nesterov动量优化对比.jpg

AdaGrad

我们再次将梯度下降过程比喻成球从一个拉长的碗中滚下:梯度下降一开始会从最陡的斜坡快速滚下来,但是这个方向并不指向全局最优,然后再慢慢向峡谷底部滚去。

如果有一种算法能够更早修正梯度下降的方向,并朝向全局最优值,那就太好了。

AdaGrad算法通过将最陡峭的梯度方向进行缩小,来实现梯度方向修正的目的。

第一步将平方梯度积累至向量s。其中每一个si都积累了损失函数对参数θi的偏导数的平方。那么当损失函数在第i个维度上特别陡峭,则si就会增加地非常快速。

第二步与梯度下降方法几乎一致,但是 有一个区别:通过s+ϵ参数将梯度向量缩小(ϵ是为了避免矩阵被0除,一般设置为10^-10)。

简而言之,这个算法降低了学习率,但是它在陡峭地维度上比平缓地维度上要更快。这种方法被称为自适应学习率。它有助于更直接地将结果更新指向全局最优值(见图2.7).另外,这个算法对学习率参数的调优需求很低,这算是附加的优点。

图2.7 AdaGrad与梯度下降法对比.jpg

AdaGrad通常在处理简单的二次型问题时表现良好,但在训练神经网络时,它经常过早停止。因为学习率被减到太小,以至于算法在达到全局最优解之前就完全停止了。所以,虽然Keras提供了Adagrad优化器,但是我们不应该使用它来训练深度神经网络。不过我们仍然需要对它有所了解,因为它对于理解其他的自适应学习率优化器是有帮助的。

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