优化方法总结

Posted on
Algorithm

总结一下机器学习中常见的各种优化器。

Batch Gradient Descent(BGD)

BGD对整个数据集计算梯度,当数据集很大时所需要的计算资源就很大,如果目标函数是凸函数,则可以找到全局最优解,否则找到局部最优解。

Stochastic Gradient Descent (SGD)

和BGD相反,SGD一次只使用一个样本来对参数进行更新,速度很快,但是可能由于数据集中的噪声导致其每次更新并不一定能往最优的方向更新,准确度有所下降。并且因为更新频繁,导致损失函数会有很大的动荡

Mini-batch Stochastic Gradient Descent (MSGD)

MSGD是SGD和BGD的一个折中,每次使用一个小批量的数据来更新权重(批大小一般取50-256)。这样可以降低梯度更新时的方差,相对于SGD,有更稳定的效果;相对于BGD,又更加地高效。

但是MSGD需要对学习率有一个合理的设定,否则不能保证很好的收敛。当学习率太大时可能会导致震荡比较大,学习率小时会导致其被困在局部最优解。

当数据较为稀疏时,即每个样本中很多的特征取值为0或接近0。由于学习率对于所有的参数都是一致的,对于稀疏特征对应的参数,每次更新的幅度就很小。

Momentum

当曲面的某个方向比别的方向更陡时,SGD会倾向于往更陡的方向更新(因为负梯度的方向),而不是往一个更优的方向更新。

动量随机梯度下降在更新梯度的时候增加了一个动量项,表示上一次更新动量的改变值:

$$v_t=\gamma v_{t-1}+\eta\nabla_\theta f(\theta)$$

$$\theta_t=\theta_{t-1}-v_t$$

对于梯度的不同维度(即梯度向量的某个分量),每一次的更新都会有一定的积累。具体来说,梯度的每一次更新包括两部分,一是当前的梯度$\nabla_\theta f(\theta)$,另一个是之前所有更新的加权和$\gamma v_{t-1}$。由于$0<\gamma<1$的存在,之前的更新$v_1, v_2, v_3\dots$在$v_t$中所占的权重会不断减小,且下降的速度是指数级的。

若$v_{t-1}^{(i)}$是正值,表示梯度在往偏向这个分量的方向移动。定义$v_0=0$,则$v_1$就是第一次的梯度值。若梯度在某个分量上不断提供正值,那么这个分量的增幅就会越来越快,这就和自由落体运动中的加速度一样。若梯度不断提供负值,则其增幅就会不断减少,甚至会往负方向增加。若梯度的提供的值在正负间摇摆,即出现振荡的现象,则它们的动量部分会相互抵消,在此维度的更新步伐就会减缓。

回到曲面某个方向比别的方向更陡的情况,举个例子,就好像我们的损失函数的曲面是一根水管内部的面,如果我们的水管自然下垂到地面,那么沿着水流的方向就会比较能快速到达地面(也就是函数的最低点),然而因为两侧的水管壁比较陡峭,SGD方法就会倾向于在水管壁之间左右横跳。如果使用了Momentum,那么左右横跳的时候会抵消动量,让该方向的变换减小,而由于同时在一点点的往水流方向前进,水流方向的梯度变化就会不断增加,从而更快到达最低点。

按经验来说$\gamma=0.9$

Nesterov Accelerated Gradient

NAG不仅做了梯度的累积,而且还考虑到了未来可能方向上的情况,从而可以在将要遇到损失上升的地方时减缓速度。

NAG在计算梯度变化时,使用的是预估的梯度,也就是假设参数会往当前的累积量的方向变化

$v_t=\gamma v_{t-1}+\eta\nabla_\theta f(\theta-\gamma v_{t-1})$

Adagrad

Ada系的梯度更新方法,主要目的是对不同重要性的特征对应的权重,进行不同程度的更新。主旨思想是对低频特征的权重进行较大的更新,对高频特征的权重进行较小的更新,这样使得各个特征的影响力稍微平衡一些。其表现形式为:

$$\theta_{i,t}=\theta_{i,t-1}-\frac{\eta}{\sqrt{G_{ii}+\epsilon}}\nabla_{\theta_i}f(\theta)$$

其中$G$是一个主对角矩阵,$G_{ii}$表示参数的第i个分量在t之前的梯度平方和。当$G_{ii}$较小的时候,即之前梯度变换较少的特征,会逐渐增加其步长,反之减少步长。

Adagrad的优势是免去了超参数$\eta$的调节,在经验情况下$\eta=0.01$

但是在分母不断积累的过程中,其学习率就会收缩,最终变得非常小。

Adadelta

Adadelta对Adagrad的问题进行了改进,将分母转变为梯度的均方根,这样得到的就是更新过程中权重的平均变化。同时把学习率$\eta$换成了梯度值增量的均方根,所以也不用设置学习率了。对于均方根的更新,它设定为:

$$E[g^2]t=\gamma E[g^2]{t-1}+(1-\gamma)g_t^2$$

权重更新表示为:

$$\Delta \theta_t=-\frac{E[\Delta\theta^2]_{t-1}}{E[g^2]_t}$$

一般把$\gamma=0.9$

RMSprop

RMSprop表示为:

$$v_t=\gamma v_{t-1}+(1-\gamma)g_t^2$$

$$\Delta w_t=-\frac{\eta}{\sqrt{v_t+\epsilon}}g_t$$

注意到这里计算新的梯度变化量的时候使用了平方,当梯度朝不同方向动荡的时候,这个值一直会保持很大,相当于考虑了变化的大小,而不动荡的梯度方向就会产生很小的值。这在计算权重改变值的时候能发挥作用,当一个梯度变化动荡的时候分母值会很大,导致权重变化就减少了,就减少了该方向的动荡程度。

Adam

Adam结合了RMSprop和Momentum。RMSprop减弱了在震荡方向上的梯度变换,但是降低了该方向的搜索能力;Momentum则很好的累积了之前的梯度变换,在梯度方向变换不大的情况下能促使梯度往更优的方向变化。Adam综合了这两者的特性,有如下的定义:

$$v_t=\beta_1 v_{t-1}+(1-\beta_1)*g_t$$

$$s_t=\beta_2 s_{t-1}+(1-\beta_2)*g_t^2$$

$$\Delta w_t=-\eta \frac{v_t}{\sqrt{s_t+\epsilon}}*g_t$$

具体来说,当$v_t$很大且$s_t$很大时,说明梯度大致朝一个方向变化且变化率大,往正确方向前进;当$v_t$很小且$s_t$很大时,可能梯度的方向在不断的变换,以至于在方向上相互抵消,在变化值上却依然很大;当$v_t$很小且$s_t$很小时,可能到达一个较低点,这是两者的比值并不会很小,依然能给梯度带来一个变化,以至于能让梯度有机会脱离局部最优。

一般来说$\beta_1=0.9$,$\beta_2=0.99$,$\epsilon=10^{-10}$