《深度学习之图像识别核心技术与案例实战》—2.2.3 最优化方法
2.2.3 最优化方法
优化方法是深度学习中一个非常重要的话题,最常见的情形就是利用目标函数的导数通过多次迭代来求解无约束最优化问题。常见的最优化方法有梯度下降法、牛顿法、拟牛顿法和共轭梯度法等。
在介绍这些方法之前,首先要介绍一下学习率。深度学习模型通常由随机梯度下降算法进行训练。随机梯度下降算法有许多变种,如Adam、RMSProp、Adagrad等,这些算法都需要预先设置学习率。学习率决定了在一个小批量(mini-batch)中权重在梯度方向的移动步长,能够直接影响模型以多快的速度收敛到局部最小值(也就是达到最好的精度)。
如果学习率很低,训练过程会更加细致,结果更加可靠,但是优化过程会耗费较长的时间,因为逼近损失函数最小值的每个步长都很小。如果学习率过高,训练可能发散不会收敛,权重的改变量可能非常大,使得优化在最小值附近震荡。
一般来说,学习率太小,网络很可能会陷入局部最优。学习率越大,神经网络学习速度越快,但是如果太大,超过了极值,损失就会停止下降,在某一位置反复震荡。也就是说,如果选择了一个合适的学习率,不仅可以在更短的时间内训练好模型,还可以节省各种损耗。一般而言,当已经设定好学习速率并训练模型时,只有等学习速率随着时间的推移而下降,模型才能最终收敛。
接下来将详细介绍深度学习中常用的优化方法。
1.梯度下降法与动量法
梯度下降法是使用最广泛的最优化方法,在目标函数是凸函数的时候可以得到全局解。
我们知道,对于一个函数f(x),记为它的梯度,对于足够小的ε,是小于f(x)的,所以以x的反方向进行搜索,就能够减小f(x),而且这个方向还是减小f(x)的最快的方向,这就是所谓的梯度下降法,也被称为“最速下降法”。
最速下降法越接近目标值的时候,需要步长越小,前进越慢,否则就会越过最优点。通常在机器学习优化任务中,有两种常用的梯度下降方法,分别是随机梯度下降法和批量梯度下降法。
所谓批量梯度下降(Batch gradient descent),就是使用所有的训练样本计算梯度,梯度计算稳定,可以求得全局最优解,但问题是计算非常慢,往往因为资源问题不可能实现。
所谓随机梯度下降(Stochastic gradient descent),就是每次只取一个样本进行梯度的计算,它的问题是梯度计算相对不稳定,容易震荡,不过整体上还是趋近于全局最优解的,所以最终的结果往往是在全局最优解附近。
通常我们训练的时候会进行折中,即从训练集中取一部分样本进行迭代,这就是常说的mini-batch训练了。
为解决随机梯度下降有时会很慢的问题,在1964年,Polyak提出了动量项(Momentum)方法。动量算法积累了之前梯度的指数加权平均,并且继续沿该方向移动,将前几次的梯度计算量加进来一起进行运算。
为了表示动量,首先引入一个新的变量v(velocity),v是之前梯度计算量的累加,但是每回合都有一定的衰减。动量法的思想就是将历史步长更新向量的一个分量γ,增加到当前的更新向量中,其具体实现为在每次迭代过程中,计算梯度和误差,更新速度v和参数θ:
(2.10)
(2.11)
其中vn表示之前所有步骤所累积的动量和,加入动量项更新与普通SGD算法对比效果如图2.5所示。
图2.5中,幅值较小较集中的前进线为SGD+Momentum方法计算方向,幅值较大的为普通SGD计算方向。
我们可以看到幅值较大的前进线大幅度地徘徊着向最低点前进,优化效率较低,过程震荡。
而SGD+Momentum由于动量积攒了历史的梯度,如果前一刻的梯度与当前的梯度方向几乎相反,则因为受到前一时刻的影响,当前时刻的梯度幅度会减小,反之则会加强。
图2.5 基于动量项的SGD示意图
形象地说,动量法就像我们从山上推下一个球,在滚落过程中累积动量,速度越来越快,直到达到终极速度。在梯度更新过程中,对在梯度点处具有相同方向的维度,增大其动量项,对于在梯度点处改变方向的维度,减小其动量项。
Nesterov加速梯度下降法(Nesterov Accelerated Gradient,NAG)是动量算法的一个变种,同样是一阶优化算法,但在梯度评估方面有所不同。NAG能给动量项一个预知的能力,并且收敛速度更快。其更新算法如下:
(2.12)
(2.13)
我们利用动量项γvn更新参数θ,通过计算(θ - γvn)得到参数未来位置的一个近似值,计算关于参数未来的近似位置的梯度,而不是关于当前参数θ的梯度,这样NAG算法可以高效地求解。
我们可以将其抽象为球滚落的时候,一般是盲目地沿着某个斜率方向,结果并不一定能令人满意。于是我们希望有一个较为“智能”的球,能够自己判断下落的方向,这样在途中遇到斜率上升的时候能够知道减速,该思想对于RNN性能的提升有重要的意义。
2.牛顿法、拟牛顿法与共轭梯度法
梯度下降法是基于一阶的梯度进行优化的方法,牛顿法则是基于二阶梯度的方法,通常有更快的收敛速度。该算法利用局部一阶和二阶的偏导信息,推测整个函数的形状,进而求得近似函数的全局最小值,然后将当前最小值设定成近似函数的最小值。
不过牛顿法作为一种迭代算法,每一步都需要求解目标函数的Hessian矩阵的逆矩阵,计算比较复杂。当Hesseian矩阵不可逆时无法计算,矩阵的逆计算复杂度为n2,当问题规模比较大时,计算量很大。
拟牛顿法通过用正定矩阵来近似Hessian矩阵的逆,不需要二阶导数的信息,简化了运算的复杂度。
共轭梯度法是一种通过迭代下降的共轭方向来避免Hessian矩阵求逆计算的方法,介于最速下降法与牛顿法之间,感兴趣的读者可以去自行阅读更多的资料。
3.Adagrad算法
上述方法中对所有参数使用同一个更新速率,但是同一个更新速率不一定适合所有参数。比如有的参数可能已经到了仅需要微调的阶段,但又有些参数由于对应样本少等原因,还需要较大幅度的调动。Adagrad就是针对这一问题提出的,自适应地为各个参数分配不同学习率的算法。其公式如下:
(2.14)
(2.15)
其中,gt是当前的梯度,η是初始学习率,是一个比较小的数,用来保证分母非0。该算法的含义是,对于每个参数,随着其更新的总距离增多,其学习速率也随之变慢。
前期gt较小的时候,正则化项较大,能够放大梯度;后期gt较大的时候,正则化项较小,能够约束梯度,适合处理稀疏梯度。
但Adagrad算法同样依赖于人工设置一个全局学习率η,设置过大的话,会使正则化项过于敏感,对梯度的调节过大。
Adagrad算法存在的问题有:其学习率是单调递减的,训练后期学习率非常小,需要手工设置一个全局的初始学习率。
Adadelta算法的出现可较好地解决上述问题,其本质是对Adagrad算法的扩展,同样是对学习率进行自适应约束,但是计算上进行了简化。Adagrad算法会累加之前所有的梯度平方,而Adadelta算法只累加固定大小的项,并且仅存储这些项近似计算对应的平均值。其公式如下:
(2.16)
(2.17)
Adadelta不依赖于全局学习率,训练初、中期,加速效果理想化,训练后期,反复在局部最小值附近抖动。
RMSprop可以算作Adadelta的一个特例,依然依赖于全局学习率。RMSprop效果趋于Adagrad和Adadelta之间,适合处理非平稳目标,适用于RNN的优化。
4.Adam算法
Adam(Adaptive Moment Estimation)算法本质上是带有动量项的RMSprop算法,它利用梯度的一阶矩估计和二阶矩估计动态调整每个参数的学习率。其公式如下:
(2.18)
(2.19)
(2.20)
(2.21)
(2.22)
其中,mt和nt分别是对梯度的一阶和二阶矩估计,即对期望和的估计;、是对mt和nt的校正,近似为对期望的无偏估计。由公式可得,Adam算法可以根据梯度进行动态调整,对学习率有一个动态约束。
Adam算法的优点主要在于经过偏置校正后,每一次迭代学习率都有个确定的范围,使参数比较平稳;对内存需求较小,适用于大多数非凸优化问题,尤其适合处理大数据集和高维空间问题。
Adamax是Adam的一种变形,对学习率的上限提供了一个更简单的范围。公式如下:
(2.23)
(2.24)
Nadam类似于带有Nesterov动量项的Adam。对学习率有了更强的约束,同时对梯度的更新也有更直接的影响。一般而言,使用带动量的RMSprop或者Adam的情况下,大多可以使用Nadam取得更好的效果。
- 点赞
- 收藏
- 关注作者
评论(0)