共计 1743 个字符,预计需要花费 5 分钟才能阅读完成。
在深度学习模型训练中,优化算法的选择往往决定了模型能否快速收敛到理想性能。不同的优化器在复杂损失曲面上的表现差异显著——有的能高效逃离鞍点,有的对学习率敏感,还有的会因自适应调整过头而错过最优解。理解这些特性,才能在实际任务中合理选择并调优。

优化器原理深度对比
数学本质差异
-
SGD(随机梯度下降):
$$\theta_{t+1} = \theta_t – \eta \cdot \nabla_\theta J(\theta_t)$$
纯依赖当前 batch 梯度,简单但容易震荡 -
Momentum(动量法):
$$v_t = \gamma v_{t-1} + \eta \nabla_\theta J(\theta_t)$$
$$\theta_{t+1} = \theta_t – v_t$$
引入速度变量,缓解震荡(γ 通常取 0.9) -
Adam(自适应矩估计):
$$m_t = \beta_1 m_{t-1} + (1-\beta_1)\nabla_\theta J(\theta_t)$$
$$v_t = \beta_2 v_{t-1} + (1-\beta_2)(\nabla_\theta J(\theta_t))^2$$
$$\hat{m}t = m_t/(1-\beta_1^t), \hat{v}_t = v_t/(1-\beta_2^t)$$
$$\theta+\epsilon)$$
综合一阶矩和二阶矩估计(默认 β1=0.9, β2=0.999)} = \theta_t – \eta \cdot \hat{m}_t/(\sqrt{\hat{v}_t
计算与内存开销
以 ResNet50 为例:
– FLOPs:Adam 比 SGD 多约 25%(主要来自二阶矩计算)
– 显存占用 :
– SGD:仅需存储参数和梯度(约 200MB)
– Adam:额外保存 m 和 v(约 600MB)
PyTorch 实战代码
# 三种优化器初始化对比
model = ResNet18()
# SGD with momentum(传统王者)optim_sgd = torch.optim.SGD(model.parameters(),
lr=0.1, # 需精细调整
momentum=0.9, # 典型值
weight_decay=5e-4 # L2 正则
)
# Adam(现代默认选择)optim_adam = torch.optim.Adam(model.parameters(),
lr=3e-4, # 通常小于 SGD
betas=(0.9, 0.999), # 动量参数
eps=1e-8 # 数值稳定项
)
# 学习率 warmup 实现(前 5% 训练步线性增长)def adjust_lr(optimizer, step, total_steps):
warmup_steps = int(0.05 * total_steps)
if step < warmup_steps:
lr = base_lr * (step + 1) / warmup_steps
for param_group in optimizer.param_groups:
param_group['lr'] = lr
生产环境避坑指南
Adam 在 NLP 中的隐患
- 对 Transformer 类模型可能导致最终性能下降(相比 SGD)
- 解决方案:后期切换为 SGD(如用 Adam 训练 80% 轮次后)
梯度裁剪黄金法则
torch.nn.utils.clip_grad_norm_(model.parameters(),
max_norm=1.0 # RNN 建议 0.5-1.0,CNN 建议 1.0-5.0
)
混合精度训练要点
- 需配合 scaler 使用
- Adam 的 eps 要增大到 1e- 7 避免下溢
性能验证数据
在 CIFAR-10 上测试(batch_size=128):
– 收敛速度 :
– Adam:100 epoch 达到 92% 准确率
– SGD+Momentum:需 150 epoch 达同等水平
– 训练速度 :
– SGD:1200 samples/sec
– Adam:900 samples/sec(因计算开销更大)
开放性问题思考
- 动态切换策略 :当验证 loss 连续 3 轮不下降时,是否应切到 SGD 精细调优?
- 新兴优化器探索 :LAMB 优化器适合超大 batch(>8k)场景,但如何确定其 β 参数?
优化器的选择没有银弹,需要根据任务特性(损失曲面复杂度、数据规模、硬件条件)灵活调整。建议在项目初期用 Adam 快速验证,后期针对关键模型做 SGD 精细调优,并持续监控训练动态。
