本文总结了常用的优化器,以及优化器的优缺点等。

Batch Gradient Descent

批量梯度下降,每次更新整个数据集计算一次梯度,确定是每次迭代比较耗时,遇到比较大的数据集则比较棘手。BGD容易陷入局部极小值点。
$$
\theta=\theta-\eta \cdot \nabla_{\theta} J(\theta)
$$

Stochastic gradient Descent

随机梯度下降,每次更新时根据单个样本对梯度进行更新。SGD的优点是计算较快,缺点是会造成loss的剧烈震荡。
$$
\theta=\theta-\eta \cdot \nabla_{\theta} J\left(\theta ; x^{(i)} ; y^{(i)}\right)
$$
SGD剧烈震荡可能会使得最后loss降到一个比较小的局部极小值点上。

Mini-batch Gradient Descent

MBGD 小批样本的梯度下降,每次经过n个样本后才更新模型参数。这样的好处是可以降低参数更新时的方差,使得收敛更加稳定,另一方面可以利用矩阵计算来计算计算的速度。
$$
\theta=\theta-\eta \cdot \nabla_{\theta} J\left(\theta ; x^{(i: i+n)} ; y^{(i: i+n)}\right)
$$

普通梯度下降方法总结

  • 对于SGD方法来说,算法不能够保证很好的收敛性,如果learning rate选择太小,收敛速度比较慢,如果learning rate 选择过大则loss过分震荡无法收敛。
  • 学习率的一种策略是逐步的降低learning rate的大小,如果数据是稀疏的,我们希望对出现频率低的特征进行大一点的更新。

  • 此外对于非凸函数,当梯度下降时,loss陷入鞍点时,所有维度的梯度都为0,导致SGD方法无法更新参数。

Momentum

针对上面SGD容易陷入局部位置,可以利用前一次梯度更新的方向,作为一个动量,使当前loss脱离当前的位置。

加入前一次更新的动量,可以使得loss在梯度方向不变的方向上更新速度加快,在梯度方向变化的方向上,使更新速度变慢,可以起到收敛并减小震荡的作用。

缺点是动量完全取决于上一次的梯度方向,先验知识不足。
$$
\begin{array}{l}v_{t}=\gamma v_{t-1}+\eta \nabla_{\theta} J(\theta) \ \theta=\theta-v_{t}\end{array}
$$

Nesterov Accelerated Gradient

NAG在momentum的基础上,对网络下一步更新方向进行微调:
$$
\begin{array}{l}v_{t}=\gamma v_{t-1}+\eta \nabla_{\theta} J\left(\theta-\gamma v_{t-1}\right) \ \theta=\theta-v_{t}\end{array}
$$
利用动量调整网络下一步迭代的方向。

NAG 会先在前一步的累积梯度上有一个大的跳跃,然后衡量一下梯度做一下修正,这种预期的更新可以避免我们走的太快。

Adagrad

Adagrad在上面的基础上,改进了学习率,由于上诉的学习率无法自己调整,因此Adagrad通过累计梯度的方式,学习模型的学习率。
$$
\theta_{t+1, i}=\theta_{t, i}-\frac{\eta}{\sqrt{G_{t, i i}+\epsilon}} \cdot \nabla_{\theta} J\left(\theta_{i}\right)
$$
其中 $G_t$ 是个对角矩阵, (i,i) 元素就是 t 时刻参数 $θ_i$ 的梯度平方和。

我们累计每一次梯度的平方,接着让学习率除以它的开方。这个的作用是为了改变不同参数的学习率。假如一个参数的梯度一直很大,那么通过这个约束,它改变的就越少。假如一个参数的梯度一直很小,那么通过这个约束它,它变化的也就越快。

缺点是,随着梯度的累积,权重步长难免变得很小。

adadelta

adadelta使用梯度的均方根(先平方,在求平均,最后开方)作为分母,替代了所有t时刻的梯度平方,仅仅需要保留上一次的均方根和这一次的梯度值,减小了算法占用的空间。

相比于adagrad,分母使用了梯度平方的衰减平均值,公式如下:
$$
\Delta \theta_{t}=-\frac{\eta}{\sqrt{E\left[g^{2}\right]_{t}+\epsilon}}g_{t}
$$
其中:
$$
g_{t}=\nabla_{\theta} J\left(\theta\right)
$$
E的计算仅仅与上一次的E与这次的梯度有关:
$$
E\left[g^{2}\right]_{t}=\gamma E\left[g^{2}\right]_{t-1}+(1-\gamma) g_{t}^{2}
$$
更新公式为:
$$
\theta_t =\theta_{t-1} + \Delta \theta_{t-1}
$$
学习率初值为:RMS[Δθ]

RMSprop

这个方法与adadelta类似,是hinton在课上提出来的,建议将E的超参数设置为0.9:
$$
\begin{array}{l}E\left[g^{2}\right]_{t}=0.9 E\left[g^{2}\right]_{t-1}+0.1 g_{t}^{2} \ \theta_{t+1}=\theta_{t}-\frac{\eta}{\sqrt{E\left[g^{2}\right]_{t}+\epsilon}} g_{t}\end{array}
$$

adam

adam设计了一种新的参数自适应学习的方法,存储了梯度的平方等衰减值,更新公式如下:
$$
\begin{array}{l}m_{t}=\beta_{1} m_{t-1}+\left(1-\beta_{1}\right) g_{t} \ v_{t}=\beta_{2} v_{t-1}+\left(1-\beta_{2}\right) g_{t}^{2}\end{array}
$$
其中m,v初始化为0,初始化为0矫正检查之后即为:
$$
\begin{array}{l}\hat{m}_{t}=\frac{m_{t}}{1-\beta_{1}^{t}} \ \hat{v}_{t}=\frac{v_{t}}{1-\beta_{2}^{t}}\end{array}
$$
迭代公式如下:
$$
\theta_{t+1}=\theta_{t}-\frac{\eta}{\sqrt{\hat{v}_{t}}+\epsilon} \hat{m}_{t}
$$
即adam同时结合了momentum和adadelta的特点,对梯度和累积梯度做一个叠加。

参数设置为β1 = 0.9,β2 = 0.999,ϵ = 10e−8。

总结

BGD方法是最基础的梯度下降方法,每次遍历整个数据集

SGD方法对单个样本计算梯度,速度快,但是容易陷入鞍点

MBGD方法采用小样本更新梯度,loss震荡比较平缓

Momentum方法采用前一个梯度方向作为动量,使得梯度快速下降,能够脱离鞍点

NAG在动量的基础上,加上对梯度方向上的调整

adagrad方法通过累积梯度平方对学习率进行调整

adadelta方法通过计算每一时刻梯度的平方和的根,通过动量的方式调整平方根,从而调整梯度

RMSprop在adadelta的基础上,设定了动量的参数,是adadelta的一种

adam使用一种结合动量和动态调节学习率的方法

如果数据是稀疏的,就用自适用方法,即 Adagrad, Adadelta, RMSprop, Adam(动态调节loss)

Adam 就是在 RMSprop 的基础上加了 bias-correction 和 momentum

随着梯度变的稀疏,Adam 比 RMSprop 效果会好。

整体来讲,Adam 是最好的选择。