SGD、BGD、MBGD

现在所说的SGD一般都指MBGD(小批量梯度下降法Mini-batch Gradient Descent)。

三种梯度下降的方法用于更新参数,也就是当前参数等于上一时刻参数减去学习率乘以梯度。

三种方法的不同体现在计算梯度上 假设损失函数为二次函数,那么参数θ的更新公式为

SGD(随机梯度下降法Stochastic Gradient Descent)

SGD:mini-batch gradient descent(随机梯度下降)
SGD就是每一次迭代每次只用一个样本计算mini-batch的梯度,然后对参数进行更新,是最常见的优化方法了。

<img src=“https://ftp.bmp.ovh/imgs/2021/07/742b1819c08ba909.png” style=“zoom: 67%;” /

优点是速度快,缺点是可能陷入局部最优,搜索起来比较盲目,并不是每次都朝着最优的方向(因为单个样本可能噪音比较多),走的路径比较曲折(震荡)。

BGD (批梯度下降算法 Batch Gradient Descent)

计算梯度时候使用所有的数据来计算,取平均值(最原始的梯度下降算法)。

BGD算法,每走一步(更新模型参数),为了计算original-loss上的梯度,就需要遍历整个数据集,在一般深度学习任务中,这是很不现实的。

好处在于收敛次数少,坏处就是每次迭代需要用到所有数据,占用内存大耗时大。

MBGD (小批量梯度下降法Mini-batch Gradient Descent)

SGD和BGD是两个极端, 而MBGD是两种方法的折中,每次选择一批数据(不是全部,也不是单个)来求梯度。
该方法也容易陷入局部最优。

现在所说的SGD基本都是MBGD。

g_{t}= \triangledown {\theta{t-1}}J(\theta_{t-1})

\triangle \theta _t = -\eta \ast g_t

\theta _t = \theta _{t-1}+\triangle \theta _t

其中\theta _t是模型参数,J(\theta _{t-1})是模型目标函数,g_t是目标函数的梯度,\eta是学习率。

SGD完全依赖于当前batch的梯度,所以η可理解为允许当前batch的梯度多大程度影响参数更新。

缺点:(正因为有这些缺点才让这么多大神发展出了后续的各种算法)

  • 选择合适的learning rate比较困难。
  • 对所有的参数更新使用同样的learning rate。对于稀疏数据或者特征,有时我们可能想更新快一些对于不经常出现的特征,对于常出现的特征更新慢一些,这时候SGD就不太能满足要求了。
  • SGD容易收敛到局部最优,在某些情况下可能被困在鞍点。【但是在合适的初始化和学习率设置下,鞍点的影响其实没这么大】
  • “之字形”的出现,即在陡谷(一种在一个方向的弯曲程度远大于其他方向的表面弯曲情况)处震荡。如下图所示

img

NAG(牛顿动量 Nesterov accelerated gradient)

1
2
3
4
5
1.Nesterov是Momentum的变种。
2.与Momentum唯一区别就是,计算梯度的不同,Nesterov先用当前的速度v更新一遍参数,在用更新的临时参数计算梯度。
3.相当于添加了矫正因子的Momentum。
4.在GD下,Nesterov将误差收敛从O(1/k),改进到O(1/k^2)
5.然而在SGD下,Nesterov并没有任何改进

在小球向下滚动的过程中,我们希望小球能够提前知道在哪些地方坡面会上升,这样在遇到上升坡面之前,小球就开始减速。这方法就是Nesterov Momentum,其在凸优化中有较强的理论保证收敛。并且,在实践中Nesterov Momentum也比单纯的 Momentum 的效果好:

img

其核心思想是:注意到 momentum 方法,如果只看 γ * v 项,那么当前的 θ经过 momentum 的作用会变成 θ-γ * v。因此可以把 θ-γ * v这个位置看做是当前优化的一个”展望”位置。所以,可以在 θ-γ * v求导, 而不是原始的θ。

img

我们使用img来移动,通过计算img,我们能够得到一个下次参数位置的近似值——也就是能告诉我们参数大致会变为多少。那么,通过基于未来参数的近似值(站的更远看看)而非当前的参数值计算相得应罚函数img并求偏导数,我们能让优化器高效地「前进」并收敛:

img

img

img

img

优点:
这种基于预测的更新方法,使我们避免过快地前进,并提高了算法地响应能力,大大改进了 RNN 在一些任务上的表现【为什么对RNN好呢,不懂啊】
没有对比就没有伤害,NAG方法收敛速度明显加快。波动也小了很多。实际上NAG方法用到了二阶信息,所以才会有这么好的结果。先按照原来的梯度走一步的时候已经求了一次梯度,后面再修正的时候又求了一次梯度,所以是二阶信息。

AdaGrad

AdaGrad 算法根据自变量在每个维度的梯度值调整各个维度的学习率,从而避免统一的维度难以适应所有维度的问题。

adagrad 方法是将每一个参数的每一次迭代的梯度取平方累加再开方,用基础学习率除以这个数,来做学习率的动态更新。【这样每一个参数的学习率就与他们的梯度有关系了,那么每一个参数的学习率就不一样了!也就是所谓的自适应学习率】。

Adagrad其实是对学习率进行了一个约束。即:

[公式]

[公式]

此处,对[公式]从1到[公式]进行一个递推形成一个约束项regularizer,[公式][公式]用来保证分母非0

特点:

  • 前期[公式]较小的时候, regularizer较大,能够放大梯度
  • 后期[公式]较大的时候,regularizer较小,能够约束梯度
  • 适合处理稀疏梯度

缺点:

  • 由公式可以看出,仍依赖于人工设置一个全局学习率
  • [公式]设置过大的话,会使regularizer过于敏感,对梯度的调节太大
  • 中后期,分母上梯度平方的累加将会越来越大,使[公式],使得训练提前结束

Adadelta

Adagrad会累加之前所有的梯度平方,而Adadelta只累加固定大小的项【其实就是相当于指数滑动平均,只用了前多少步的梯度平方平均值】,并且也不直接存储这些项,仅仅是近似计算对应的平均值【这也就是指数滑动平均的优点】

RMSprop依然需要自己设定全局学习率,因此Adadelta在RMSprop的基础上,用参数更新的平方来替代全局学习率的位置,这样就可以省略全局学习率了。

img

特点:

  • 训练初中期,加速效果不错,很快
  • 训练后期,反复在局部最小值附近抖动

momentum(动量梯度下降 Gradient Descent With Momentum)

img

RMSProp

由于AdaGrad单调递减的学习率变化过于激进,RMSprop只关注过去一段时间的梯度平均值,离的时间越远越不重要。

img

特点:

  • 其实RMSprop依然依赖于全局学习率
  • RMSprop算是Adagrad的一种发展,和Adadelta的变体,效果趋于二者之间
  • 适合处理非平稳目标(也就是与时间有关的)
  • 对于RNN效果很好,因为RMSprop的更新只依赖于上一时刻的更新,所以适合。???

Adam(Adaptive Moment Estimation)

Adam(Adaptive Moment Estimation)本质上是带有动量项的RMSprop,它利用梯度的一阶矩估计和二阶矩估计动态调整每个参数的学习率。Adam的优点主要在于经过偏置校正后,每一次迭代学习率都有个确定范围,使得参数比较平稳。公式如下:

img

img

img

img

img

其中,[公式][公式]分别是对梯度的一阶矩估计和二阶矩估计,可以看作对期望[公式][公式]的估计;[公式][公式]是对[公式][公式]的校正,这样可以近似为对期望的无偏估计。 可以看出,直接对梯度的矩估计对内存没有额外的要求,而且可以根据梯度进行动态调整,而[公式]对学习率形成一个动态约束,而且有明确的范围。

特点:

  • 结合了Adagrad善于处理稀疏梯度和RMSprop善于处理非平稳目标的优点
  • 对内存需求较小
  • 为不同的参数计算不同的自适应学习率
  • 也适用于大多非凸优化 - 适用于大数据集和高维空间

Adamax

Adamax是Adam的一种变体,此方法对学习率的上限提供了一个更简单的范围。公式上的变化如下:

[公式]

[公式]

可以看出,Adamax学习率的边界范围更简单

Nadam

Nadam类似于带有Nesterov动量项的Adam。公式如下:

[公式]

[公式]

[公式]

[公式]

[公式][公式]

[公式]

可以看出,Nadam对学习率有了更强的约束,同时对梯度的更新也有更直接的影响。一般而言,在想使用带动量的RMSprop,或者Adam的地方,大多可以使用Nadam取得更好的效果。

优化动画图

附录

img