共计 2469 个字符,预计需要花费 7 分钟才能阅读完成。
背景痛点:传统优化器的局限性
在深度学习模型训练中,随机梯度下降(SGD)及其变种(如 Momentum)长期作为主流优化器。然而面对现代神经网络的非凸优化问题时,它们暴露了明显缺陷:

- 学习率敏感:固定学习率需精心调参。过大导致震荡,过小则收敛缓慢。如图 1 所示,SGD 在 CIFAR-10 训练中学习率设为 0.1 时发散,0.01 时又收敛过慢。
- 梯度方向单一:Momentum 虽引入历史梯度加权(公式 $v_t = \beta v_{t-1} + (1-\beta)g_t$),但对所有参数使用相同学习率,忽视各维度梯度量级差异。
- 局部最优陷阱:非凸损失函数的鞍点问题使传统方法易陷入平庸解。实验显示 SGD 在 ResNet-18 上验证准确率卡在 82% 难以突破。
算法解析:Adam 的自适应机制
Adam 通过四大核心组件实现动态调整:
- 梯度矩估计
- 一阶矩(均值):$m_t = \beta_1 m_{t-1} + (1-\beta_1)g_t$
-
二阶矩(方差):$v_t = \beta_2 v_{t-1} + (1-\beta_2)g_t^2$
两者均采用指数移动平均(EMA),如图 2 所示,EMA 使历史梯度权重随时间指数衰减,平衡当前与长期梯度信息。 -
偏差校正
因初始 $m_0=v_0=0$ 导致估计偏小,需校正:
$$\hat{m}_t = \frac{m_t}{1-\beta_1^t}, \quad \hat{v}_t = \frac{v_t}{1-\beta_2^t}$$ -
参数更新
最终更新公式:
$$\theta_t = \theta_{t-1} – \eta \cdot \frac{\hat{m}_t}{\sqrt{\hat{v}_t} + \epsilon}$$
分母 $\sqrt{v_t}$ 实现逐参数自适应学习率,大幅缓解梯度量级差异问题。
PyTorch 实现关键技巧
import torch
from torch.optim import Optimizer
class AdamW(Optimizer): # 集成权重衰减的 Adam 变种
def __init__(self, params, lr=1e-3, betas=(0.9, 0.999), eps=1e-8, weight_decay=0.01):
defaults = dict(lr=lr, betas=betas, eps=eps, weight_decay=weight_decay)
super().__init__(params, defaults)
def step(self, closure=None):
loss = None
if closure is not None:
loss = closure()
for group in self.param_groups:
for p in group['params']:
if p.grad is None:
continue
grad = p.grad.data
# 梯度裁剪(防御性编程)torch.nn.utils.clip_grad_norm_(p, max_norm=2.0)
# 状态初始化
state = self.state[p]
if len(state) == 0:
state['step'] = 0
state['exp_avg'] = torch.zeros_like(p.data)
state['exp_avg_sq'] = torch.zeros_like(p.data)
# 更新矩估计
beta1, beta2 = group['betas']
state['step'] += 1
state['exp_avg'].mul_(beta1).add_(grad, alpha=1-beta1)
state['exp_avg_sq'].mul_(beta2).addcmul_(grad, grad, value=1-beta2)
# 偏差校正
bias_correction1 = 1 - beta1 ** state['step']
bias_correction2 = 1 - beta2 ** state['step']
step_size = group['lr'] / bias_correction1
# 参数更新(含 L2 正则)denom = (state['exp_avg_sq'].sqrt() / math.sqrt(bias_correction2)).add_(group['eps'])
p.data.addcdiv_(state['exp_avg'], denom, value=-step_size)
p.data.mul_(1 - group['lr'] * group['weight_decay']) # 解耦权重衰减
return loss
实验对比:CIFAR-10 上的性能表现
使用 ResNet-18 在 CIFAR-10 上对比三种优化器(图 3):
- 训练损失:Adam 在 100 epoch 时 loss 降至 0.15,显著快于 SGD 的 0.28 和 RMSprop 的 0.22
- 验证准确率:Adam 最终达到 89.3%,比 SGD 高 4.7 个百分点
- 收敛稳定性:Adam 的 acc 曲线平滑上升,而 SGD 出现多次震荡
生产环境最佳实践
参数调优指南
- β₁/β₂推荐值:
- 默认 β₁=0.9, β₂=0.999 适用于大多数场景
-
对稀疏梯度任务(如 NLP),可尝试 β₁=0.99 以延长历史梯度记忆
-
早停策略:
from torch.optim.lr_scheduler import ReduceLROnPlateau scheduler = ReduceLROnPlateau(optimizer, mode='max', patience=5) scheduler.step(val_acc) # 监控验证集指标
⚠️ 避坑指南
- 混合精度训练 :需设置
eps=1e-4避免数值下溢 - 学习率衰减:Adam 自带自适应学习率,通常无需额外衰减
- 权重衰减陷阱:使用 AdamW 而非原生 Adam+L2,避免参数更新耦合
延伸思考
- 联邦学习适应性:如何设计差分隐私友好的 Adam 变种?
- 二阶优化结合:能否用 Hessian 矩阵改进二阶矩估计?
通过系统实验可见,Adam 凭借其自适应学习率机制,在收敛速度和稳定性上显著优于传统优化器。合理调参后,它能成为大多数深度学习任务的首选方案。
正文完
