深度学习常用优化器有哪些?SGD、Momentum、Adam 有什么区别?
简化版
优化器决定「拿到梯度后怎么更新参数」。演进主线:SGD(随机梯度下降)——最基础,沿负梯度走一小步,简单但收敛慢、易在沟壑里震荡、对学习率敏感;Momentum(动量)——给更新加「惯性」,累积历史梯度方向,加速收敛、减少震荡(像小球滚下坡越滚越快);AdaGrad/RMSProp(自适应学习率)——给每个参数按其历史梯度大小自动调学习率(梯度大的参数步子小、梯度小的步子大);Adam——同时结合 Momentum(一阶动量)和 RMSProp(二阶自适应学习率),还带偏差校正,通常较快且易作为基线,但仍需调基础学习率、权重衰减和调度。精调追求最佳泛化时有人用 SGD+Momentum。
详细版
优化器演进:
| 优化器 | 核心思想 | 特点 |
|---|---|---|
| SGD | w ← w - η·g | 状态少、对学习率与调度敏感 |
| Momentum | 累积历史梯度(一阶动量) | 平滑方向,可能加速也可能过冲 |
| AdaGrad | 按累积梯度平方缩放学习率 | 自适应,但学习率单调衰减到过小 |
| RMSProp | 用指数移动平均替代累积(修正 AdaGrad) | 避免 AdaGrad 分母永久累积;有效步长仍取决于近期梯度与 ε |
| Adam | Momentum + RMSProp + 偏差校正 | 常用基线,仍需调参 |
Adam 更新(核心):
m = β₁·m + (1-β₁)·g (一阶动量:梯度的移动平均 = Momentum)
v = β₂·v + (1-β₂)·g² (二阶动量:梯度平方的移动平均 = RMSProp)
m̂, v̂ = 偏差校正(m, v) (修正初期偏向 0)
w ← w - η · m̂ / (√v̂ + ε) (方向用 m̂、步长按 v̂ 自适应)
两条改进主线: ① 动量(利用历史方向加速);② 自适应学习率(每参数各自调步长)。Adam 把两条合一。
完整版教学
一、优化器解决什么:怎么用梯度更新参数
反向传播算出了梯度,优化器再决定如何把梯度转换成参数更新:步长多大、是否平滑历史方向、是否按坐标缩放。SGD、Momentum 与 Adam 不是简单的前后代替关系,它们有不同的状态成本、隐式偏置和调参方式。理解时可抓住两条设计轴:① 动量平滑历史梯度;② 自适应预条件为不同参数缩放更新。
二、SGD:最基础的一步一步走
随机梯度下降(SGD) 是最基本的优化器:
w ← w - η · g (η 是学习率,g 是当前梯度)
每次沿当前负梯度方向走一小步。实际用小批量(mini-batch) 算梯度——比全量快、比单样本稳。
问题:
- 收敛慢,尤其在损失面「又扁又长的沟壑」里会来回震荡(垂直于沟壑方向反复横跳,沿沟壑方向前进很慢)。
- 对学习率极敏感:太大发散、太小极慢。
- 容易卡在平坦区、鞍点。
三、Momentum:给更新加「惯性」
Momentum(动量) 借鉴物理里小球滚下坡的惯性:不只看当前梯度,还累积过去的梯度方向:
v ← β·v + g (速度 = 历史动量 + 当前梯度,β 常取 0.9)
w ← w - η·v
直觉:小球滚下坡时,一直往下的方向会越滚越快(累积加速),而来回摆动的方向会相互抵消(震荡被抑制)。
好处:
- 加速收敛:一致的下降方向被不断累积、越走越快。
- 减少震荡:沟壑里左右横跳的分量相互抵消,走得更直。
- 在一致方向上保留速度,可能穿过小范围平坦区,也可能造成过冲:靠惯性冲出平坦区和小坑。
这是第一条改进主线:利用历史梯度方向(一阶动量)。
四、AdaGrad / RMSProp:每个参数自适应学习率
另一条思路:不同参数应该用不同的学习率。频繁更新、梯度大的参数该走小步(别冲过头),稀疏、梯度小的参数该走大步(多学一点)。
- AdaGrad:累积每个参数历史梯度的平方和,用它的平方根去除学习率——梯度一直大的参数学习率被压小,梯度小的保持大。问题:平方和只增不减,学习率单调衰减到过小,后期几乎不动。
- RMSProp:修正 AdaGrad——用指数移动平均代替累积和(只看近期梯度),分母不会像 AdaGrad 那样因历史平方梯度永久累积而单调增大,但有效步长仍可能很小,适合非平稳目标和深层网络。
这是第二条改进主线:自适应学习率(按每个参数的梯度历史调步长,这里的“二阶矩”是梯度平方的指数平均,不是 Hessian 或二阶优化)。
五、Adam:结合一阶矩与平方梯度尺度
Adam(Adaptive Moment Estimation) 把上面两条主线结合起来——既用 Momentum 的动量方向,又用 RMSProp 的自适应学习率:
m ← β₁·m + (1-β₁)·g ① 一阶动量:梯度的移动平均(= Momentum,决定方向)
v ← β₂·v + (1-β₂)·g² ② 二阶动量:梯度平方的移动平均(= RMSProp,决定步长)
m̂ = m/(1-β₁ᵗ), v̂ = v/(1-β₂ᵗ) ③ 偏差校正(修正初期 m、v 偏向 0)
w ← w - η · m̂ / (√v̂ + ε) ④ 更新:方向用 m̂、步长按 √v̂ 自适应缩放
- m(一阶矩) 提供动量、加速、抗震荡。
- v(二阶矩) 提供每参数自适应学习率。
- 偏差校正 修正训练初期 m、v 从 0 起步的低估。
优点:常能较快得到可用结果并适应不同坐标的梯度尺度,但基础学习率、ε、β 和正则仍会显著影响训练。β₁=0.9、β₂=0.999 是常见实现默认值,不是所有任务的最优配置。
六、Adam vs SGD:泛化之争
Adam 和 SGD 的泛化比较依赖模型、正则、训练预算和各自调参。在部分视觉分类配方中,充分调优的 SGD+Momentum 很有竞争力;Transformer 等任务则常以 AdamW 为起点。不能用单个固定学习率公平比较二者。所以:
- 需要快速建立基线、NLP/Transformer → Adam 或更常见的 AdamW(解耦权重衰减)。
- 追求最佳泛化、愿意调学习率和调度 → SGD + Momentum + 学习率调度。
- AdamW 把权重衰减与自适应梯度更新解耦,是许多 Transformer 配方的常见选择,但仍要明确哪些参数不衰减。
七、算一次 Adam 更新,理解偏差校正与 AdamW
设第一步梯度 g=2,β₁=0.9,β₂=0.999,初始 m=v=0。则 m₁=0.2、v₁=0.004;偏差校正后 m̂₁=2、v̂₁=4,忽略 ε 时更新量约为 η×2/2=η。没有偏差校正,第一步会因 m、v 从零起步而尺度失真。
m1 = 0.9*0 + 0.1*2 = 0.2 -> m_hat=0.2/(1-0.9)=2
v1 = 0.999*0 + 0.001*4 = .004 -> v_hat=.004/(1-.999)=4
Δw = -η * 2/(sqrt(4)+ε) ≈ -η
| 方法 | 历史方向 | 每参数缩放 | 权重衰减建议 |
|---|---|---|---|
| SGD | 否 | 否 | 可配 L2 |
| Momentum | 是 | 否 | 可配 L2 |
| Adam | 是 | 是 | L2 与自适应缩放耦合 |
| AdamW | 是 | 是 | 解耦 weight decay |
记忆钩子:Adam 的 v 是梯度平方的移动平均,不是损失曲率;AdamW 的 W 强调解耦权重衰减。
八、常见误区与追问
- 误区:Adam 使用了真正的二阶导数。 它使用梯度平方的一阶统计,不计算 Hessian。
- 误区:Adam 默认参数在所有任务上都无需调整。 基础学习率和权重衰减常是决定性超参数。
- 追问:为什么 Adam 要偏差校正? 零初始化使早期移动平均偏向零,除以
1-β^t可校正期望。 - 追问:AdamW 与 Adam 加 L2 为什么不完全等价? 自适应预条件会改变 L2 梯度,AdamW 则把参数衰减从梯度更新中解耦。
- 追问:如何公平比较 SGD 与 AdamW? 统一数据、训练预算和评估协议,并分别调各自学习率与调度,不能只用同一 η。
九、加强记忆
优化器把梯度转成参数更新。Momentum 用一阶指数移动平均平滑方向;AdaGrad 累积平方梯度,使有效步长单调不增;RMSProp 改用平方梯度的指数移动平均,不再永久累积全部历史;Adam 同时维护一阶矩和平方梯度矩,并做零初始化偏差修正。Adam 的 v 不是梯度方差,也不是 Hessian。AdamW 再把权重衰减从预条件梯度中解耦。选型时分别调优学习率、调度、momentum/betas 和 decay,并在相同数据与预算下比较收敛、泛化和状态内存。