深度学习优化算法实战:从梯度下降到Adam的演进与避坑指南

1次阅读
没有评论

共计 1794 个字符,预计需要花费 5 分钟才能阅读完成。

image.webp

背景痛点:梯度下降的局限性

传统梯度下降(SGD)在深度学习训练中存在几个典型问题:

  1. 非凸函数优化困难 :神经网络的损失函数往往是非凸的,SGD 容易陷入局部最优或鞍点
  2. 学习率敏感 :固定学习率可能导致收敛缓慢(学习率太小)或震荡(学习率太大)
  3. 稀疏数据表现差 :对于稀疏特征(如 NLP 中的词向量),所有参数使用相同学习率会导致更新不均衡

一个直观的例子是当损失函数存在 ” 峡谷 ” 地形时(一个维度陡峭,另一个维度平缓),SGD 会沿着陡峭方向震荡前进。

优化算法对比

算法 内存占用 收敛速度 超参数敏感性 适用场景
SGD 小批量数据
Momentum 中等 中等 中等 需要突破局部最优
RMSprop 中等 非平稳目标函数
Adam 很快 很低 默认首选

Adam 算法原理

Adam 结合了动量(Momentum)和自适应学习率(RMSprop)的思想,核心公式:

  1. 计算梯度的一阶矩估计(动量项):
    $$m_t = \beta_1 m_{t-1} + (1-\beta_1)g_t$$
  2. 计算梯度的二阶矩估计(自适应项):
    $$v_t = \beta_2 v_{t-1} + (1-\beta_2)g_t^2$$
  3. 偏差修正(初始阶段补偿):
    $$\hat{m}_t = \frac{m_t}{1-\beta_1^t}$$
    $$\hat{v}_t = \frac{v_t}{1-\beta_2^t}$$
  4. 参数更新:
    $$\theta_t = \theta_{t-1} – \eta \frac{\hat{m}_t}{\sqrt{\hat{v}_t} + \epsilon}$$

其中 $\beta_1$ 通常取 0.9,$\beta_2$ 取 0.999,$\epsilon$ 为防止除零的小常数(1e-8)。

PyTorch 实现示例

import torch
from torch import nn
from torchvision import datasets, transforms

# 初始化模型和优化器
model = nn.Sequential(nn.Linear(784, 128),
    nn.ReLU(),
    nn.Linear(128, 10)
)

optimizer = torch.optim.Adam(model.parameters(),
    lr=0.001,
    betas=(0.9, 0.999),  # beta1 和 beta2
    eps=1e-8,
    weight_decay=0.01,  # L2 正则化
    amsgrad=False
)

# 梯度裁剪
max_norm = 1.0
torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm)

# 学习率预热
warmup_steps = 1000
scheduler = torch.optim.lr_scheduler.LambdaLR(
    optimizer,
    lr_lambda=lambda step: min(1.0, step / warmup_steps)
)

MNIST 实验对比

使用相同超参数(batch_size=128, lr=0.001)训练 3 层 MLP:

  1. SGD:loss 下降平稳但缓慢,100 epoch 后 test acc=97.2%
  2. Momentum:前期收敛快,后期有轻微震荡,test acc=97.8%
  3. Adam:最快收敛,test acc=98.1%

深度学习优化算法实战:从梯度下降到 Adam 的演进与避坑指南

常见问题解决方案

  1. 训练后期震荡
  2. 动态调整 beta1(如从 0.9 线性衰减到 0.8)
  3. 增加 epsilon 值(如从 1e- 8 调整到 1e-6)

  4. 显存溢出

  5. 使用梯度累积:每 N 个 batch 更新一次参数

    loss.backward()
    if (i+1) % 4 == 0:  # 每 4 个 batch 更新
        optimizer.step()
        optimizer.zero_grad()

  6. 过拟合

  7. 早停机制:验证集 loss 连续 3 次不下降时停止
  8. 模型检查点:保存验证集表现最好的模型

延伸思考

  1. Adam 是否适合所有任务?在强化学习等非平稳问题中,有研究指出 SGD 可能更稳定
  2. Transformer 训练为何常用 AdamW?因为传统的 weight decay 在 Adam 中实现不准确,AdamW 将其解耦

总结建议

对于大多数深度学习任务,Adam 是很好的默认选择。但在以下情况建议考虑其他方法:

  • 需要极致的模型精度时(如竞赛):尝试 SGD+Momentum
  • 训练资源非常有限时:使用 RMSprop
  • 处理特殊架构(如 GAN):可能需要混合不同优化器

调参时可以先用 Adam 快速验证模型可行性,再根据需求切换到更精细的优化策略。

正文完
 0
评论(没有评论)