本文目录导读:

我们来详细解释一下 SGD动量(SGD with Momentum,带动量的随机梯度下降)。
这是一个在深度学习训练中非常重要的优化技术,它基本上解决了标准SGD(随机梯度下降)的两个主要问题:收敛速度慢和在高曲率、噪声梯度下容易震荡。
为什么需要动量?标准SGD的困境
想象一下,你在一个山谷中(代表损失函数表面),想要快速滑到最低点(代表最优解)。
-
标准SGD:就像一个盲人,每一步都只根据当前脚下的坡度(当前梯度)来决定下一步的方向和大小,如果山谷非常崎岖(比如有很多坑坑洼洼的局部极小值),或者山谷的走向很曲折(比如一个窄长的峡谷),SGD就会:
- 在平坦区域走得很慢:因为梯度很小。
- 在峡谷中左右震荡:因为垂直于峡谷壁的梯度很大,而沿着峡谷底部前进的梯度很小,这导致优化路径呈“之”字形,浪费时间。
-
带动量的SGD:就像一个从山顶滚下来的保龄球,它不仅仅看当前的坡度,还累计了它之前的速度和方向,即使当前脚下的坡度很小,它依然可以依靠之前的惯性快速穿过平坦区域,即使遇到峡谷壁的反向阻力,它也会因为巨大的冲量而更倾向于沿着原来的方向(峡谷底部)前进,大大减少了震荡。
核心思想与公式
动量的核心是引入了速度(Velocity)的概念,它是对过去梯度的一个指数加权平均(Exponential Moving Average)。
更新公式:
在标准的SGD中,权重更新为:
w = w - learning_rate * gradient
而带动量的SGD引入了两个步骤:
-
更新速度(动量项):
v_t = ρ * v_{t-1} + lr * ∇L(w_t) -
更新权重:
w_{t+1} = w_t - v_t
公式解释:
w: 模型的权重参数(我们要优化的东西)。v_t: 当前时刻的动量速度,它是一个向量,方向和大小都在变化。v_{t-1}: 上一时刻的动量速度,这是核心,体现了历史信息。lr(learning rate): 学习率,控制当前梯度的影响力。∇L(w_t): 在当前位置w_t计算出的当前梯度。ρ(rho): 动量衰减系数(Momentum decay term),通常也叫动量系数。ρ的值一般在[0, 1)之间,比较常见的默认值是 9。
物理意义与直觉
-
ρ 的作用:它决定了过去梯度的影响多久会“衰减”。
- 当
ρ = 0时,v_t = lr * ∇L,就退化成了标准的SGD,完全没有记忆。 - 当
ρ = 0.9时,速度向量会保留之前9步的梯度信息(因为 0.9^10 ≈ 0.35,影响力降到35%),每一步,历史速度会保留90%,并加上10%的当前梯度。 - 当
ρ = 0.99时,记忆会更长,惯性更大,但可能会“冲过头”而错过最小值。
- 当
-
通俗理解:
- 加速穿越平坦区域:在梯度几乎是0的平地上,标准SGD寸步难行,但动量依然有来自之前陡峭区域的速度,它会靠着这个惯性继续前进,直到找到下一个下降点。
- 抑制震荡:在峡谷中,每一步的梯度都会在垂直于峡谷的方向上左右交替,动量会对这些方向相反的力进行平均(抵消),使得这个方向的加速度很小,而沿着峡谷方向的梯度符号一致,动量会不断累加,使得在这个方向上的速度越来越快。
一个直观的类比
想象你在一个有摩擦力的冰面上推一个箱子。
- 标准SGD:你推一下(当前梯度),箱子动一下,然后摩擦力(学习率)让它停下来,下一次你又推一下,方向可能还变了,整个过程中箱子很难有持续的速度。
- 带动量的SGD:你不是直接推箱子,而是给箱子一个初始推力,并不断顺着它前进的方向补力,即使偶尔有侧风(噪声梯度),箱子也会因为巨大的惯性而保持主要方向,你积累的推力(速度)让它能更持续、更平滑地前进。
变体与改进
除了经典动量,还有另一种非常流行的动量变体,叫做 Nesterov 动量(Nesterov Accelerated Gradient,NAG)。
-
经典动量 (SGD with Momentum):先根据历史速度
v走一步,到了新位置w - ρ*v,再计算新位置的梯度∇L,然后用这个梯度去更新速度。- 好比:先凭惯性走,再根据新位置调整方向。
-
Nesterov 动量:先“眺望”一下,根据历史速度
v预测一个未来的位置w - ρ*v,然后在这个预测的位置上计算梯度∇L,再更新速度。- 好比:先往速度方向看一眼,看看前面是不是悬崖或陡坡,然后根据看到的“未来景象”再来调整这次推动的方向和力度。
Nesterov 的直观优势:它能够提前感知前方地形,从而做出更聪明的决策,避免冲过头,通常在收敛速度和准确性上略优于经典动量。
公式对比(直观形式,非标准实现):
- 经典动量:速度 = ρ 旧速度 + lr 当前梯度
- Nesterov 动量:速度 = ρ 旧速度 + lr 预测位置梯度
总结与建议
| 特性 | 标准 SGD | SGD + 动量 |
|---|---|---|
| 收敛速度 | 慢 | 快 |
| 稳定性 | 容易震荡,不稳定 | 平滑稳定 |
| 平坦区域 | 停滞不前 | 轻易穿过 |
| 局部最优 | 容易陷入浅的局部极小值 | 有潜力跳出浅的局部极小值 |
| 复杂度 | 简单 | 简单(增加一个向量存储) |
实践建议:
- 首选:在大多数现代深度学习任务中,强烈建议使用带动量的SGD(或Adam等自适应方法),而不是裸的SGD。
- 默认参数:动量系数
ρ默认设为9是一个非常经典且效果很好的选择。 - 与学习率配合:动量通常允许你使用稍大一点的学习率,因为它能有效抑制震荡。
- 替代方案:虽然带动量的SGD效果很好,但现在更常用的可能是 Adam 或 AdamW 优化器,它们结合了动量和自适应学习率的思想,通常对超参数不那么敏感,默认参数就能取得不错的效果,但在某些任务(如计算机视觉中的某些模型)上,精心调参的带动量SGD(结合学习率衰减)有时能取得比Adam更高的精度。