深度学习模型的训练本质上是一个损失函数最小化问题。优化算法(Optimizer)决定了模型参数如何沿着梯度方向更新,直接影响了训练速度、收敛质量和最终性能。从经典的随机梯度下降(SGD)到自适应学习率方法(Adam),优化算法的发展深刻改变了深度学习的实践方式。
深度学习训练的目标是找到一组参数 ,使得损失函数 在训练集上最小化:
其中 是训练样本数, 是模型对输入 的预测输出, 是真实标签。
优化算法的核心更新公式可以统一表示为:
其中 是学习率, 是梯度的一阶矩(动量项), 是梯度的二阶矩(自适应学习率项), 是数值稳定性常数。不同优化器的区别就在于 和 的计算方式不同。
随机梯度下降(Stochastic Gradient Descent, SGD)是最基础也是使用最广泛的优化算法之一。与批量梯度下降每次使用全部数据计算梯度不同,SGD 每次只使用一个样本(或一个小批量 mini-batch)来估计梯度:
其中 是第 步的梯度。
假设有一个简单的二次损失函数 ,梯度为 。
| 步骤 | 参数 | 梯度 | 学习率 | 更新量 | 新参数 |
|---|---|---|---|---|---|
| 0 | 0.0 | -10.0 | 0.1 | +1.0 | 1.0 |
| 1 | 1.0 | -8.0 | 0.1 | +0.8 | 1.8 |
| 2 | 1.8 | -6.4 | 0.1 | +0.64 | 2.44 |
| 3 | 2.44 | -5.12 | 0.1 | +0.512 | 2.952 |
| 4 | 2.952 | -4.096 | 0.1 | +0.4096 | 3.3616 |
| 5 | 3.3616 | -3.2768 | 0.1 | +0.3277 | 3.6893 |
可以看到,SGD 沿着梯度下降方向稳步前进,但当接近最优点()时,步长逐渐变小——这是因为梯度本身在变小,而非学习率在衰减。
| 优点 | 缺点 |
|---|---|
| 实现简单,计算开销小 | 在病态曲面上震荡严重 |
| 理论性质清晰,泛化性好 | 学习率选择敏感 |
| 适用于大多数问题 | 在梯度稀疏处更新慢 |
| 内存占用低 | 难以逃离鞍点 |
关键洞察:SGD 的"噪声"(来自小批量采样)实际上有助于泛化——这被称为隐式正则化效应。实验表明,使用 SGD 训练得到的模型往往比使用 Adam 训练得到的模型在测试集上泛化更好,尤其是在计算机视觉任务中。
动量法受到物理学中动量概念的启发——小球滚下山坡时,不仅受到当前梯度的作用,还会保持之前的运动趋势。这在优化中可以平滑梯度更新方向,加速收敛:
其中 是动量系数(通常取 0.9), 是累积的速度向量。
如果把 SGD 看作每一步都重新决策方向,动量法就像一个有惯性的球:当梯度方向一致时,速度累积加速;当梯度方向变化时,速度会平滑过渡,抑制震荡。
考虑一个狭长山谷状的损失曲面:在 方向坡度平缓(梯度小),在 方向坡度陡峭(梯度大)。
| 步骤 | SGD(方向) | SGD(方向) | Momentum(方向) | Momentum(方向) |
|---|---|---|---|---|
| 0 | 初始: 0 | 初始: 0 | 初始: 0 | 初始: 0 |
| 1 | +0.1 | -10.0 | +0.1 | -10.0 |
| 2 | +0.19 | -0.0(过冲反向) | +0.29 | -9.0 |
| 3 | +0.27 | +10.0(反弹) | +0.56 | +0.0 |
可以看到,SGD 在 方向大幅震荡,而动量法因为累积了速度,在 方向的震荡被显著抑制,同时在 方向加速前进。
Nesterov 动量是动量法的一个变体,它计算的是"向前看一步"后的梯度:
NAG 相当于先按动量位置"跳一步",再计算该位置的梯度进行修正。这种"前瞻"能力使得 NAG 在接近最优点时能更及时地减速,减少过冲。
AdaGrad(Adaptive Gradient Algorithm)引入了参数自适应学习率的思想:对频繁更新的参数减小学习率,对稀疏更新的参数增大学习率:
其中 是历史梯度平方的累积和, 表示逐元素相乘。
假设有两个参数 和 :
| 步骤 | 有效学习率 | ||||
|---|---|---|---|---|---|
| 1 | 0.01 | 10.0 | 0.01 | 10.0 | : 100, : 0.1 |
| 2 | 0.01 | 8.0 | 0.014 | 12.8 | : 70.7, : 0.078 |
| 3 | 0.01 | -5.0 | 0.017 | 13.7 | : 57.7, : 0.073 |
(稀疏梯度)获得很大的有效学习率,快速更新;(密集梯度)的学习率迅速衰减。
| 优点 | 缺点 |
|---|---|
| 无需手动调整每个参数的学习率 | 学习率单调递减,最终停止学习 |
| 适合处理稀疏特征(如 NLP 中的词嵌入) | 累积平方和不断增大,学习率趋于 0 |
| 对学习率不那么敏感 | 在非凸问题上表现不佳 |
RMSprop 是 Geoff Hinton 在 Coursera 课程中提出的一种方法,旨在解决 AdaGrad 学习率单调递减的问题。核心改进是用指数移动平均替代累积和:
其中 通常取 0.9, 是梯度平方的指数移动平均。
| 特性 | AdaGrad | RMSprop |
|---|---|---|
| 梯度历史 | 全部历史累积(单调增长) | 指数移动平均(关注近期) |
| 学习率趋势 | 持续衰减至 0 | 自适应调节,不会归零 |
| 适用场景 | 稀疏梯度(NLP) | 非平稳目标(RNN、强化学习) |
| 对非凸问题 | 表现一般 | 表现良好 |
Adam(Adaptive Moment Estimation)是目前最流行的优化算法之一。它结合了 Momentum 和 RMSprop 的优点——既保留动量效应平滑梯度方向,又使用自适应学习率调节步长:
其中:
在训练初期, 和 从 0 开始累积,会导致估计值偏小。偏差修正通过除以 来补偿:
| 步骤 | 修正因子 | ||
|---|---|---|---|
| 1 | 0.9 | 0.1 | 10.0 |
| 2 | 0.81 | 0.19 | 5.26 |
| 3 | 0.729 | 0.271 | 3.69 |
| 5 | 0.590 | 0.410 | 2.44 |
| 10 | 0.349 | 0.651 | 1.54 |
| 50 | 0.005 | 0.995 | 1.005 |
没有偏差修正时,前几步的更新量会被严重低估。偏差修正使得 Adam 在早期也能有效更新参数。
假设 ,,,,,:
步骤 1:
步骤 2:
(梯度小)得到较大的更新步长,(梯度大)得到较小的更新步长——这正是自适应学习率的效果。
传统的 L2 正则化(权重衰减)在 Adam 中存在实现不一致的问题。在 SGD 中,权重衰减与梯度更新是解耦的:
但在 Adam 中,L2 正则项通常被添加到损失函数中,然后一起进入自适应学习率计算:
这导致正则化项也被自适应放缩了——对于频繁更新的参数,正则化效果被减弱;对于稀疏更新的参数,正则化效果被放大。这与权重衰减的初衷(对所有参数施加相同比例的衰减)相矛盾。
AdamW(Decoupled Weight Decay)将权重衰减与自适应学习率解耦:
换句话说,权重衰减直接应用在参数上,不受自适应学习率的影响。
# Adam with L2 regularization (不正确)
decay = lr * weight_decay * param
param_grad = grad + decay
m = beta1 * m + (1 - beta1) * param_grad
v = beta2 * v + (1 - beta2) * param_grad ** 2
param -= lr * m / (sqrt(v) + eps) # 权重衰减也被自适应了!
# AdamW (正确)
m = beta1 * m + (1 - beta1) * grad
v = beta2 * v + (1 - beta2) * grad ** 2
param -= lr * m / (sqrt(v) + eps) + lr * weight_decay * param # 解耦权重衰减
在 ImageNet 上使用 ResNet-50 的训练结果(来自 AdamW 原论文 Loshchilov & Hutter, 2019):
| 优化器 | Top-1 准确率 | Top-5 准确率 | 收敛 Epoch |
|---|---|---|---|
| SGD + Momentum | 76.3% | 93.1% | 90 |
| Adam + L2 | 74.2% | 91.8% | 75 |
| AdamW | 76.8% | 93.4% | 75 |
| AdamW + cosine LR | 77.4% | 93.7% | 90 |
AdamW 不仅超越了标准 Adam,甚至在某些设置下超过了 SGD + Momentum。
SGD (1951) ──────────────────────────────────┐
├── Momentum (1986) ────────────────────────┤
│ └── NAG (1983) ───────────────────────┤
├── AdaGrad (2011) ─────────────────────────┤
│ └── RMSprop (2012) ───────────────────┤
└───────────────────────────────────────────┤
▼
Adam (2015)
│
├── AdamW (2019) ✓ 主流
├── Nadam (2016): Adam + NAG
├── AMSGrad (2018): 解决 v_t 下降问题
├── RAdam (2019): 自动学习率预热
└── LAMB (2019): 大 Batch 训练
| 优化器 | 一阶矩 | 二阶矩 | 学习率 | 是否需要 LR 调度 |
|---|---|---|---|---|
| SGD | 无 | 固定 | 强烈需要 | |
| Momentum | 无 | 固定 | 需要 | |
| AdaGrad | 自适应 | 不需要 | ||
| RMSprop | EMA() | 自适应 | 不需要 | |
| Adam | EMA() | EMA() | 自适应 + 动量 | 可选(推荐 cosine) |
| AdamW | EMA() | EMA() | 自适应 + 动量 | 推荐 cosine |
损失值
^
| SGD ──────── 缓慢但稳定
| Momentum ──── 加速
| Adam ──────── 快速收敛
| AdamW ─────── 快速且泛化好
|
| Adam ──┐
| │ Momentum │
| │ ┌────────┐ SGD
| _______│__│________│____________
+───────────────────────────────> Epoch
| 场景 | SGD | Momentum | Adam/AdamW |
|---|---|---|---|
| 平坦区域(梯度小) | 更新慢 | 累积加速 | 自适应加速 |
| 陡峭区域(梯度大) | 可能震荡 | 抑制震荡 | 自动缩小步长 |
| 鞍点(梯度≈0) | 停滞 | 可能穿越 | 自适应穿越 |
| 稀疏特征 | 更新慢 | 累积后更新 | 逐个参数自适应 |
| 噪声梯度 | 方向变动大 | 平滑方向 | 平滑 + 自适应 |
| 任务类型 | 推荐优化器 | 理由 |
|---|---|---|
| 计算机视觉(CNN) | SGD + Momentum 或 AdamW | SGD 泛化性好;AdamW 快速收敛且能保持泛化 |
| NLP(Transformer) | AdamW | 自适应学习率适合不同词频的嵌入层 |
| 强化学习 | RMSprop 或 Adam | 非平稳目标,需要持续适应 |
| GAN 训练 | Adam() | GAN 训练对动量敏感,降低 可稳定训练 |
| 大规模分布式训练 | LAMB | 支持大 Batch(65536+) |
| 小批量数据 | Adam | 快速收敛,减少调参 |
即使使用自适应优化器,学习率调度仍然非常重要:
# Cosine 退火(热门选择)
lr = eta_min + 0.5 * (eta_max - eta_min) * (1 + cos(pi * T_cur / T_max))
# Step 衰减
lr = initial_lr * gamma ** (epoch // step_size)
# 典型值:gamma=0.1, step_size=30
# Warmup + Cosine(训练 LLM 的标准做法)
# 前 5% 步数线性增加到 max_lr,然后 cosine 衰减到 0
| 超参数 | 默认值 | 调优范围 | 说明 |
|---|---|---|---|
| (学习率) | 0.001 | 到 | 最重要的超参数 |
| 0.9 | 0.8 - 0.95 | 动量系数,越大越平滑 | |
| 0.999 | 0.99 - 0.9999 | 梯度平方 EMA 系数 | |
| 到 | 数值稳定性 | ||
| weight decay | 0 | 0.0001 - 0.1(AdamW) | 解耦权重衰减系数 |
优化算法的发展经历了从简单到复杂、从单一到自适应的演进过程:
在实际使用中,AdamW + Cosine 退火调度已成为许多前沿工作的默认配置,尤其是在 NLP 和 Transformer 架构中。而在计算机视觉领域,适当调优的 SGD + Momentum 仍然具有竞争力。
选择合适的优化器不是终点——学习率调度、权重衰减系数、预热策略等配套设置同样关键。理解每种优化器的工作原理,才能在实践中灵活运用。