优化器:SGD → Momentum → Adam
SGD、Momentum、Adam 完整推导与算例,AdamW 解耦正则,优化器竞赛演示。
对应课件:2.1 自然语言处理
本章对应课件:《2.1 自然语言处理》中的优化器部分。核心内容:SGD、Momentum、Adam、AdamW——如何更好地利用梯度来更新参数。
2.1 为什么需要优化器
先懂直觉
最朴素的更新是「沿梯度反方向走一步」。但真实损失面是崎岖的:有的方向陡、有的方向平、还有噪声。优化器就是「怎么走得更快更稳」的策略集合。
第 1 章学过最朴素的更新公式:
但真实训练中,梯度并不总是这么「听话」:
- 损失面可能是狭长的峡谷:陡峭方向来回震荡,平坦方向前进缓慢;
- mini-batch 梯度有噪声,方向抖动;
- 不同参数的梯度尺度差异巨大。
优化器就是如何更好地利用梯度来更新参数的工程方案。
2.2 SGD(随机梯度下降)
其中 是当前 batch 算出的梯度。
特点:只看当前梯度,实现简单、显存开销小。
缺点:
- 梯度方向有噪声,可能在峡谷形损失面上来回震荡;
- 在平坦方向前进很慢,在陡峭方向又冲得太猛;
- 对学习率非常敏感。
| 变体 | 每步用的数据 | 特点 |
|---|---|---|
| BGD(全批量) | 全部训练集 | 方向准,极慢 |
| SGD(单样本) | 1 条 | 快、噪声大 |
| Mini-batch SGD | 32~4096 条 | 实际使用的版本 |
深度学习里说的「SGD」通常指 mini-batch 版本。
2.3 Momentum:给优化加一点「惯性」
先懂直觉
像球下山:一直朝一个方向滚就积累速度;左右摇摆的方向会互相抵消。这样既抑制震荡,又加速稳定方向。
引入速度变量 :
直觉像一个球下山:前几步一直往一个方向走,就积累速度。
因此能:
- 减少左右震荡(方向相反的梯度互相抵消);
- 加速稳定方向(持续同向的梯度被累积放大)。
其中 通常取 0.9 左右,表示「保留多少历史速度」。
在陡峭方向,梯度正负交替,历史速度互相抵消 → 有效步长变小 → 不震荡; 在平坦方向,梯度方向一致,速度不断累积 → 有效步长变大 → 加速前进。
等效学习率约为 (γ=0.9 时约 10 倍),但只在方向一致时生效。
2.4 Adam:Momentum + 自适应学习率 ★
先懂直觉
Adam = 动量(记住方向)+ 自适应(每个参数自己调步长)。梯度大的参数步子缩小,梯度小的参数步子放大,所以对学习率没那么敏感。
Adam 同时维护两个统计量。
一阶矩(梯度的指数移动平均,类似 Momentum):
二阶矩(梯度平方的指数移动平均,衡量梯度尺度):
偏差修正(因为 ,训练初期估计偏小):
最终更新:
直觉:
- 分子 :往哪走(方向,带惯性);
- 分母 :梯度大的参数步子缩小,梯度小的参数步子放大——自适应学习率;
- :防止除零的小常数(通常 )。
训练开始时 ,第一步 (β₁=0.9 时),只有真实梯度的 1/10。如果不修正,前几十步的更新会严重偏小。
除以 : 时 ,——修正回真实尺度。随着 增大,,修正自然消失。
设 ,,,梯度序列 ,:
第 1 步:
- ,
- ,
- 更新量
第 2 步:
- ,
- ,
- 更新量
可以看到:梯度持续为 1 时,自适应分母让每步更新稳定在 附近。
2.5 常用超参数
| 参数 | 典型值 | 含义 |
|---|---|---|
| 1e-3 ~ 3e-4 | 学习率(大模型常用更小) | |
| 0.9 | 一阶矩衰减率 | |
| 0.95 ~ 0.999 | 二阶矩衰减率(LLM 常用 0.95) | |
| 1e-8 | 数值稳定项 |
同一起点、同一学习率,SGD(红)、Momentum(橙)、Adam(绿)在带波浪的非凸函数上赛跑。观察谁更快到达谷底、谁的轨迹更抖。
工程里怎么用(PyTorch 优化器配置)
# SGD + Momentum
opt = torch.optim.SGD(model.parameters(), lr=0.1, momentum=0.9)
# Adam(大模型训练默认用 AdamW)
opt = torch.optim.AdamW(
model.parameters(),
lr=3e-4, # 大模型常用 1e-4 ~ 3e-4
betas=(0.9, 0.95), # LLM 常用 β₂=0.95
weight_decay=0.1, # 解耦的 weight decay
eps=1e-8,
)
2.6 为什么大模型常见 AdamW
AdamW 是 Adam 的改进版:把 weight decay(L2 正则) 从梯度更新中解耦出来,直接作用于参数:
在原始 Adam 中把 L2 项 加进梯度:。
但 Adam 会用 归一化梯度——梯度大的参数,其 L2 项也被同比例缩小,导致正则化效果被自适应学习率扭曲:大梯度参数几乎不受正则约束。
AdamW 把 decay 从梯度里拿出来,直接乘在参数上:无论梯度大小,正则强度一致。
这也是为什么训练 Transformer、大模型时你经常会看到 AdamW(如 torch.optim.AdamW)。
2.7 三者对比
| 优化器 | 核心思想 | 优点 | 缺点 |
|---|---|---|---|
| SGD | 只用当前梯度 | 简单、省显存、泛化有时更好 | 震荡、收敛慢、对 lr 敏感 |
| Momentum | 累积速度 | 抑制震荡、加速 | 仍需手动调学习率 |
| Adam / AdamW | 一阶矩 + 二阶矩 + 偏差修正 | 自适应、收敛快、对超参不敏感 | 显存多(存 m、v)、有时泛化略差 |
Q1:Adam 的显存开销为什么这么大?
查看答案
除了权重本身,还要保存一阶矩 m 和二阶矩 v(各同参数量大小)。混合精度训练还要 FP32 master weights 和 FP32 梯度。合计约 18 bytes/参数(见第 13 章)。这是分布式训练需要 ZeRO/FSDP 分片优化器状态的原因。
Q2:Adam 和 AdamW 的区别?
查看答案
Adam 把 L2 正则加进梯度,会被自适应学习率缩放,正则效果不稳定;AdamW 把 weight decay 解耦,直接作用于参数,正则强度与梯度大小无关。现代 Transformer 训练默认 AdamW。
Q3:为什么大模型训练常用 β₂ = 0.95 而不是 0.999?
查看答案
β₂ 越大,二阶矩估计越平滑但越滞后。大模型训练梯度噪声大、训练步数少,0.95 让估计更快跟上梯度变化,训练更稳定(LLaMA 等模型的常见配置)。
| 优化器 | 一句话 |
|---|---|
| SGD | ,简单但震荡 |
| Momentum | 累积速度 ,抑制震荡 |
| Adam | 一阶矩 + 二阶矩 + 偏差修正,自适应步长 |
| AdamW | 解耦 weight decay,LLM 训练默认 |
| 显存 | Adam 额外存 m、v,共约 18 bytes/参数(混合精度) |
显示答案与解析
正确答案:B
m₀ = v₀ = 0,初期移动平均只有真实值的 (1−β) 比例。偏差修正把估计恢复到真实尺度,且随 t 增大自动消失。显示答案与解析
正确答案:B
在峡谷的陡峭方向,梯度正负交替,历史速度相互抵消;平坦方向梯度一致,速度累积加速。这就是「惯性」的效果。显示答案与解析
正确答案:B
原始 Adam 把 L2 加进梯度,会被自适应学习率缩放而失效;AdamW 解耦后正则强度与梯度大小无关,行为更一致,是 LLM 训练默认选择。