先修知识
阅读本文前,建议先理解:
1. Adam = Momentum + RMSProp
| 组件 | 来源于 | 做什么 |
|---|---|---|
| 一阶矩 (梯度指数加权平均) | Momentum | 提供惯性,抑制振荡,冲过局部最优 |
| 二阶矩 (梯度平方指数加权平均) | RMSProp | 自适应学习率,梯度大的慢、梯度小的快 |
Adam 同时拥有两者的优点,是深度学习领域默认的优化器。
2. 计算过程
以参数 为例:
2.1 计算梯度
2.2 更新一阶矩和二阶矩
| 超参数 | 默认值 | 含义 |
|---|---|---|
| 0.9 | 一阶矩的衰减系数(动量) | |
| 0.999 | 二阶矩的衰减系数(梯度平方) |
2.3 偏差修正
和指数加权平均一样, 和 初始为 0,早期值偏小,需要修正:
是当前迭代步数。注意 Adam 需要偏差修正(RMSProp 和 Momentum 单独使用时一般不做),这是因为二阶矩也受冷启动影响,不做修正训练初期会很不稳定。
2.4 更新参数
- 分子 :动量的方向(往哪走)
- 分母 :自适应缩放(走多大步)
- :防止除零,默认
3. 完整公式一览
4. 三种优化器对比
| Momentum | RMSProp | Adam | |
|---|---|---|---|
| 一阶矩 | ✅ | — | ✅ |
| 二阶矩 | — | ✅ | ✅ |
| 偏差修正 | 一般不做 | 不做 | 做 |
| 自适应学习率 | — | ✅ | ✅ |
| 动量惯性 | ✅ | — | ✅ |
| 额外显存 | 1 倍参数量 | 1 倍参数量 | 2 倍参数量 |
5. 内存代价
Adam 需要为每个参数额外保存两个值: 和 。
- 假设模型有 1 亿个参数(每个参数是 4 字节 float32)
- 参数本身:400 MB
- 和 各占 400 MB → 额外 800 MB
- 参数与两个优化器状态合计 ≈ 参数存储的 3 倍;还未计入梯度、激活和临时张量
这是 Adam 的主要缺点。但对于大多数场景,这个显存代价是可以接受的;当显存紧张时,可以选择 SGD+Momentum(只额外存 1 份)。
6. PyTorch 中使用
optimizer = optim.Adam(model.parameters(), lr=0.001, betas=(0.9, 0.999), eps=1e-8)
# 绝大多数时候直接用默认参数即可
7. 总结
优化器演进路线:
SGD → + 指数加权平均 → Momentum (有惯性,抑制振荡)
SGD → + 自适应学习率 → RMSProp (梯度大→慢,梯度小→快)
Momentum + RMSProp → Adam (两者结合,默认选择)
Adam 的每一步:
g → V(动量) + S(自适应) → 偏差修正 → 更新
代价:每个参数多存 V 和 S(2 倍显存)
效果依任务而异,学习率、权重衰减与调度仍需验证
推荐:β₁=0.9, β₂=0.999, ε=1e-8, lr=1e-3 → 默认配置即可