外观
动量(momentum)
Momentum

随着我们朝着构建越来越大模型的方向推进,每一处可能的优化都变得至关重要。
当然,有多种方法可以加速模型训练,例如:
- 批处理
- 借助 PySpark MLLib 等框架进行分布式训练。
- 使用更好的超参数优化方法,例如本章将讨论的贝叶斯优化(Bayesian Optimization)。
- 以及许多其他技术。
动量(momentum)是另一种可靠且有效的加速模型训练的技术。虽然动量相当流行,但许多人仍难以直观地理解它的工作原理和有效性。让我们在本章中一探究竟。
在梯度下降(gradient descent)中,每次参数更新都完全依赖于当前梯度。这一点从下面展示的梯度权重更新规则中可以清楚看出:

结果是,我们在优化过程中会产生许多不必要的振荡。让我们更直观地理解这一点。假设这是损失函数的等高线图,最优位置(损失函数最小的参数配置)标记在这里:

简单来说,这张图展示了梯度下降如何向最优解移动。在每次迭代中,算法计算当前参数值下损失函数的梯度,并更新权重。如下图所示:

请注意这里的两点:
- 它在垂直方向上进行了不必要的振荡。
- 经过若干 epoch 后,它最终停在了非最优解处。
理想情况下,我们本期望权重更新看起来是这样的:

- 它本应在水平方向上迈出更大的步子……
- ……并在垂直方向上迈出更小的步子,因为这个方向上的移动是不必要的。这一思路也如下图所示:

基于动量的优化对梯度下降的更新规则做了轻微修改。更具体地说,它还考虑了过去梯度的移动平均:

这有助于我们处理之前看到的不必要的垂直振荡。原理是什么?由于动量考虑的是过去梯度的移动平均,因此如果最近的梯度更新轨迹如下图所示,那么显然它在垂直方向上的平均值会很低,而在水平方向上的平均值会很大(这正是我们想要的):

由于这个移动平均会被加到梯度更新中,它有助于优化算法在期望方向上迈出更大的步子。

这样,我们就能:
平滑优化轨迹。
减少参数更新中不必要的振荡,这也加快了训练速度。从下图中也能明显看出这一点:
这一次,梯度更新轨迹在垂直方向上的振荡小得多,并且在相同 epoch 数下也能达到最优解。这就是动量背后的核心思想及其工作原理。当然,动量确实为模型引入了另一个超参数(动量系数),它应当像其他任何超参数一样被适当调优:
例如,考虑我们上面讨论的二维等高线:


- 将动量系数设置得过大,会显著加快水平方向上的梯度更新。这可能导致越过最小值,如下图所示:
- 此外,将动量设置得过小会拖慢最优的梯度更新,违背了动量的初衷。
- 如果你想获得更多实操体验,可以试试这个工具:https://bit.ly/4cOrJN1。

