⚠️ Alpha内测版本警告:此为早期内部构建版本,尚不完整且可能存在错误,欢迎大家提Issue反馈问题或建议。
Skip to content

2.2 自适应优化器

版本: v2.0 最后更新: 2026-05-27

在线 Notebook

对应的交互式版本可在 Google Colab 打开,统一使用方式见 第0章说明

核心概念

梯度下降虽然简单有效,但在实际应用中存在问题:学习率难以选择,对所有参数使用相同的学习率不够灵活。自适应优化器通过动态调整每个参数的学习率,使优化过程更加高效和稳定。

梯度下降的局限性

基础梯度下降的更新规则:

wt+1=wtαL(wt)

问题:

  1. 学习率固定:对所有参数使用相同的学习率
  2. 学习率难以选择:太大导致发散,太小导致收敛缓慢
  3. 无法适应不同参数的特性:有些参数梯度大,有些小

动量(Momentum)

思想

想象一个球在山坡上滚动。不仅要考虑当前的坡度(梯度),还要考虑之前的运动方向(动量)。这样可以加速收敛,避免在平坦区域停留。

数学表达

速度更新:

vt=βvt1+L(wt)

参数更新:

wt+1=wtαvt

其中:

  • vt:速度(累积梯度)
  • β:动量系数(通常 β=0.9
  • α:学习率

优势

  • ✅ 加速收敛:利用历史梯度信息
  • ✅ 减少振荡:平滑更新方向
  • ✅ 改善病态曲率下的更新:动量有时能帮助跨过小幅震荡区域

RMSprop

思想

不同参数的梯度大小差异很大。RMSprop通过自适应学习率,让梯度大的参数使用较小的学习率,梯度小的参数使用较大的学习率。

数学表达

二阶矩估计:

st=β2st1+(1β2)(L(wt))2

参数更新:

wt+1=wtαst+ϵL(wt)

其中:

  • st:梯度平方的指数移动平均
  • β2:衰减系数(通常 β2=0.999
  • ϵ:小常数,防止除以零
  • :元素级乘法

优势

  • ✅ 自适应学习率:根据梯度大小调整
  • ✅ 处理稀疏梯度:对梯度小的参数使用较大学习率
  • ✅ 收敛更快:比基础梯度下降快得多

Adam优化器

思想

Adam = Adaptive Moment Estimation

结合动量和RMSprop的优点:

  • 使用一阶矩(动量)加速收敛
  • 使用二阶矩(RMSprop)自适应学习率

数学表达

一阶矩估计(动量):

mt=β1mt1+(1β1)L(wt)

二阶矩估计(RMSprop):

vt=β2vt1+(1β2)(L(wt))2

偏差修正:

m^t=mt1β1t,v^t=vt1β2t

参数更新:

wt+1=wtαm^tv^t+ϵ

其中:

  • β1=0.9:一阶矩衰减系数
  • β2=0.999:二阶矩衰减系数
  • α=0.001:学习率
  • ϵ=108:小常数

优势

  • ✅ 结合动量和自适应学习率
  • ✅ 默认参数常可作为起点:但学习率、权重衰减和调度仍需调试
  • ✅ 工程上容易得到可用收敛:在深度学习中是强基线
  • ✅ 处理稀疏梯度:对NLP和计算机视觉任务都有效

优化器对比

方面梯度下降动量RMSpropAdam
学习率固定固定自适应自适应
使用历史梯度
自适应学习率
收敛速度中等最快
稳定性一般最好
超参数敏感性中等中等
推荐使用教学中等规模大规模深度学习

代码实验

完整的代码示例位于:code/ch02_optimization/lms_vs_adam.py

运行方式:

bash
python code/ch02_optimization/lms_vs_adam.py

代码包含:

  • LMS算法的实现(在线学习)
  • Adam优化器的实现
  • 收敛曲线对比
  • 权重估计误差对比
  • 预测精度对比

关键输出:

  • LMS收敛速度 vs Adam收敛速度
  • 最终MSE对比
  • 权重估计误差对比

LMS vs Adam代码文件: code/ch02_optimization/lms_vs_adam.py
运行方式: python code/ch02_optimization/lms_vs_adam.py

图2.2:LMS与Adam在收敛速度、误差下降和参数估计上的对比。它把“自适应学习率”和“历史梯度累积”带来的实际收益直接可视化,是理解 Adam 为什么成为深度学习默认选择的最好入口。

与深度学习的联系

自适应优化器 → 神经网络训练

梯度下降(基础)
    ↓ (添加动量)
动量优化器(加速)
    ↓ (添加自适应学习率)
RMSprop(自适应)
    ↓ (结合两者)
Adam优化器(强基线)
    ↓ (应用到深度学习)
神经网络训练(高效)

为什么深度学习使用Adam

  1. 参数众多:神经网络有数百万个参数,需要自适应学习率
  2. 梯度差异大:不同层的梯度大小差异很大
  3. 收敛快:Adam在许多深度学习任务上比基础梯度下降更容易调到可用收敛
  4. 鲁棒性强:默认参数通常是可靠起点,但学习率和权重衰减仍需验证

学习率调度

虽然Adam相对基础梯度下降更容易调参,但在实际应用中仍然使用学习率调度

  • 开始时使用较大的学习率,快速探索
  • 后期逐渐减小学习率,精细调整

这在训练大型模型(如LLM)时特别重要。


在LLM中的应用

Adam → AdamW:LLM训练的标准优化器

LLM训练中使用的是AdamW(Adam with decoupled weight decay),而不是标准的Adam:

  1. 为什么是AdamW?

    • 标准Adam的权重衰减与学习率耦合
    • AdamW将权重衰减与学习率解耦
    • 对大模型训练更稳定
  2. LLM训练的典型配置

    优化器:AdamW
    学习率:1e-4 到 1e-3
    β₁(一阶矩衰减):0.9
    β₂(二阶矩衰减):0.999
    权重衰减:0.01

学习率调度在LLM训练中的关键作用

LLM训练中的学习率调度通常分为三个阶段:

  1. 预热阶段(Warmup)

    • 前1000-10000步线性增加学习率
    • 避免训练初期的不稳定
    • 对大模型特别重要
  2. 主训练阶段

    • 使用较大的学习率加快收敛
    • 通常持续大部分训练时间
  3. 衰减阶段

    • 使用余弦衰减或线性衰减
    • 逐步降低学习率以精细调整
    • 提高最终模型质量

梯度累积和混合精度训练

LLM训练中的两个关键技巧:

  1. 梯度累积

    • 多个小batch的梯度相加
    • 在其他训练细节不变时,近似模拟更大的有效 batch
    • 内存占用不增加
    • 对LLM训练至关重要
  2. 混合精度训练

    • 用float16计算,float32存储梯度
    • 速度快2-3倍
    • 内存占用减半
    • 精度基本不变

实际LLM训练中的优化器配置

python
# 典型的LLM训练配置
optimizer = AdamW(
    model.parameters(),
    lr=1e-4,
    betas=(0.9, 0.999),
    weight_decay=0.01
)

# 学习率调度
scheduler = get_cosine_schedule_with_warmup(
    optimizer,
    num_warmup_steps=10000,
    num_training_steps=total_steps
)

常见问题

Q: 为什么Adam通常比基础梯度下降更容易使用? A: Adam结合了动量(平滑更新方向)和自适应学习率(处理不同参数的梯度尺度),在很多深度学习任务上更容易得到稳定收敛。具体速度优势取决于任务、批大小、学习率和调度策略。

Q: 什么时候应该使用动量而不是Adam? A: 在小规模问题、教学示例或需要更强泛化控制的场景中,SGD+动量仍然常见。Adam/AdamW通常是深度学习工程的强基线,但不是唯一正确选择。

Q: Adam的超参数如何选择? A: Adam的默认参数(β1=0.9,β2=0.999,α=0.001)在大多数情况下都有效。通常只需要调整学习率 α

Q: 为什么需要偏差修正? A: 在训练初期,mtvt 都接近零(因为初始化为零)。偏差修正通过除以 (1βt) 来补偿这个偏差。

Q: Adam会陷入局部最优吗? A: 会。Adam仍然优化非凸目标,只是动量和自适应步长有助于改善收敛行为。实际训练中的主要难点还包括鞍点、梯度噪声、学习率调度和数值稳定性。

Q: 如何选择学习率? A: 常见的做法是从 α=0.001 开始,然后根据训练曲线调整。如果损失不下降,减小学习率;如果收敛缓慢,增大学习率。


下一步: 阅读 2.3 优化算法与传统机器学习

本教程采用 CC BY-NC-SA 4.0 许可协议