梯度下降与优化器
梯度下降是深度学习训练的核心算法;Adam、AdamW 等现代优化器都在它的基础上改进。本页梳理从最朴素的批量梯度下降到当今主流优化器(包括 2024-2025 年兴起的 Muon 等)的完整谱系,并给出每个优化器的数学推导。前置阅读:数值优化与数学基础。
沿用在数值优化基础中建立的”蒙眼下山”比喻,各种优化器的改进方向一目了然:
- 批量梯度下降(GD)= 先把整座山精确测量一遍再走一步。方向准,但一步太贵(全量数据)。
- 随机梯度下降(SGD)= 蒙眼下山,每步只看脚下一个样本就走。方向有噪声但极快,而且噪声反而有助于跳出局部最优。
- 小批量 SGD(mini-batch)= 每步看一小撮样本(如 32 个)再走——兼顾速度和方向准确度,是实际训练的标准做法。
- Momentum(动量)= 带着惯性滚下山。球有质量,不会因为一个小坎就停下,能冲过浅坑(局部最优)。
- Adam= 自适应步长。每个参数方向用不同的有效学习率——梯度大的方向自动减速、梯度小的方向自动加速,像给每个方向装了独立变速箱。
原理详解:优化器的数学推导
Section titled “原理详解:优化器的数学推导”以下推导用数学符号表达。记 为参数, 为损失函数, 为梯度, 为学习率, 为时间步。
1. 基本梯度下降
Section titled “1. 基本梯度下降”批量梯度下降(Batch GD)用全部 N 个样本计算梯度:
随机梯度下降(SGD)只用一个样本:
小批量 SGD(Mini-batch)取折中,每次用 B 个样本:
2. Momentum(动量)
Section titled “2. Momentum(动量)”核心思想:累积历史梯度方向,像物理中的惯性一样平滑轨迹。
直观理解:如果连续几步梯度方向一致,速度 v 会越积越大(加速);如果方向反复震荡(如锯齿形路径),正负抵消后 v 的震荡分量被抑制——这就是动量”冲过浅坑”和”抹平抖动”的数学根源。
Nesterov 加速梯度(NAG)是 Momentum 的变体,先”往前看一步”再计算梯度:
3. AdaGrad:逐参数自适应学习率
Section titled “3. AdaGrad:逐参数自适应学习率”核心思想:对每个参数维护一个”历史梯度平方和”,梯度一直很大的参数说明它”跑太快”,给它更小的有效学习率。
问题: 单调递增,学习率会一直衰减直到趋零,训练后期”学不动了”。
4. RMSProp:指数衰减修复 AdaGrad
Section titled “4. RMSProp:指数衰减修复 AdaGrad”核心思想:用指数移动平均(EMA)代替无限累积,让学习率”忘掉远古历史”。
5. Adam:Momentum + RMSProp 合体
Section titled “5. Adam:Momentum + RMSProp 合体”Adam 同时维护梯度的一阶矩(均值,相当于 Momentum)和二阶矩(未中心化方差,相当于 RMSProp):
典型超参数:, , , 。
直观理解: 提供”平均方向”(类似 Momentum), 提供”每个参数的波动幅度”。除以 后,梯度幅度一直很大的参数被缩小、一直很小的参数被放大——这就是”逐参数自适应步长”。
6. AdamW:解耦权重衰减
Section titled “6. AdamW:解耦权重衰减”Adam 中的权重衰减(weight decay)实现有微妙问题:当权重衰减通过 L2 正则化(把 加到梯度里)实现时,它会和自适应学习率耦合,导致实际衰减量被 缩放——频繁更新的参数衰减不够,不频繁更新的参数衰减过多。
AdamW 的修复:把权重衰减从梯度中分离出来,直接对参数做衰减:
这个看似微小的改动对大模型训练影响巨大——AdamW 是当前 GPT、LLaMA 等所有主流大模型预训练的标准优化器。
从 1950s 的梯度下降到如今的 AdamW,每一步改进都解决前一代的痛点:
不同优化器在损失曲面上的行为
Section titled “不同优化器在损失曲面上的行为”同样是”下山”,不同优化器走出完全不同的轨迹:
PyTorch:SGD vs Adam 训练同一个模型
Section titled “PyTorch:SGD vs Adam 训练同一个模型”import torchimport torch.nn as nn
# 一个简单的线性模型 + 随机数据model = nn.Linear(10, 1)X = torch.randn(100, 10)y = X @ torch.randn(10, 1) + 0.1 * torch.randn(100, 1)criterion = nn.MSELoss()
# 分别用 SGD 和 Adam,对比同样步数下的收敛for name, opt in [("SGD", torch.optim.SGD(model.parameters(), lr=0.01)), ("Adam", torch.optim.Adam(model.parameters(), lr=0.01))]: # 每次重新初始化模型权重 torch.nn.init.normal_(model.weight); torch.nn.init.zeros_(model.bias) for epoch in range(100): loss = criterion(model(X), y) opt.zero_grad(); loss.backward(); opt.step() print(f"{name}: 最终 loss = {loss.item():.4f}")# Adam: 最终 loss ≈ 0.01(收敛更快)# SGD: 最终 loss ≈ 0.03(lr=0.01 下偏慢)numpy 手写 SGD 更新规则
Section titled “numpy 手写 SGD 更新规则”import numpy as np
# 权重更新公式:w ← w - lr * grad(这就是 SGD 的全部)w = np.array([3.0, -1.0]) # 初始权重lr = 0.1 # 学习率for step in range(20): grad = 2 * w # 假设梯度 = ∇(w²) = 2w w = w - lr * grad # 核心:往梯度反方向走一步print(w) # → [≈0, ≈0] 收敛到最优numpy 手写 Adam 更新规则
Section titled “numpy 手写 Adam 更新规则”理解 Adam 最简单的方式是从零实现——100 行不到就能复现 PyTorch 的 torch.optim.Adam:
import numpy as np
class SimpleAdam: """最小化 Adam 实现,展示核心逻辑""" def __init__(self, params, lr=1e-3, betas=(0.9, 0.999), eps=1e-8): self.lr, self.b1, self.b2, self.eps = lr, *betas, eps self.m = [np.zeros_like(p) for p in params] # 一阶矩 self.v = [np.zeros_like(p) for p in params] # 二阶矩 self.t = 0 # 时间步
def step(self, params, grads): self.t += 1 for i, (p, g) in enumerate(zip(params, grads)): # 一阶矩:梯度的指数移动平均(方向) self.m[i] = self.b1 * self.m[i] + (1 - self.b1) * g # 二阶矩:梯度平方的指数移动平均(幅度) self.v[i] = self.b2 * self.v[i] + (1 - self.b2) * g**2 # 偏差校正 m_hat = self.m[i] / (1 - self.b1 ** self.t) v_hat = self.v[i] / (1 - self.b2 ** self.t) # 更新参数:有效学习率 = η * m_hat / (√v_hat + ε) params[i] -= self.lr * m_hat / (np.sqrt(v_hat) + self.eps)
# 测试:优化 f(w) = w²(最优解 w=0)w = [np.array([3.0, -1.0])]opt = SimpleAdam(w, lr=0.1)for step in range(50): grads = [2 * w[0]] # ∇(w²) = 2w opt.step(w, grads)print(w[0]) # → [≈0, ≈0] 比 SGD 更快收敛学习率调度可视化
Section titled “学习率调度可视化”学习率不是固定的——好的调度(schedule)对训练效果影响极大。常见的策略:
import numpy as np
# Cosine Annealing(余弦退火):大模型训练最常用的调度def cosine_schedule(step, total_steps, lr_max=1e-3, lr_min=1e-5, warmup_steps=500): """warmup → cosine 衰减 → lr_min""" if step < warmup_steps: return lr_max * step / warmup_steps # 线性预热 progress = (step - warmup_steps) / (total_steps - warmup_steps) return lr_min + 0.5 * (lr_max - lr_min) * (1 + np.cos(np.pi * progress))
# 模拟 10000 步训练的学习率变化for s in [0, 250, 500, 5000, 9999]: print(f"step {s:5d}: lr = {cosine_schedule(s, 10000):.6f}")# step 0: lr = 0.000000 ← warmup 阶段# step 250: lr = 0.000500 ← warmup 中途# step 500: lr = 0.001000 ← warmup 结束,峰值# step 5000: lr = 0.000502 ← cosine 中途# step 9999: lr = 0.000010 ← 接近 lr_min- Adam 是默认首选:90% 的深度学习任务,第一选择就是 Adam(lr=1e-3),快速验证想法。如果 Adam 效果不够好,再尝试 SGD+Momentum(往往泛化更好,尤其在图像分类)。
- 学习率预热(warmup):Transformer 训练初期梯度极不稳定,先用很小的学习率线性升温到目标值,再正常训练——这是 GPT/BERT 训练的标配。
- 学习率衰减:训练后期降低学习率,让模型在最优解附近”精调”,避免在最优点附近来回震荡。
- 梯度裁剪(gradient clipping):RNN / Transformer 训练中,当梯度范数超过阈值就缩放——防止梯度爆炸导致 NaN。
- AdamW ≠ Adam + weight_decay:Adam 中的 L2 正则化和权重衰减在自适应学习率下不等价,AdamW 修正了这个问题,是当前大模型训练的标准选择。
- Muon 的适用范围:Muon 只对 2D 隐藏层权重有效,嵌入层、分类头、LayerNorm 参数仍用 AdamW。在训练 Transformer 时,Q/K/V 分别作为独立矩阵做正交化效果更好。详见上文”最新进展”中的 Muon 小节。
- 分布式训练用 LAMB:超大 batch(数万 token)训练时,LAMB(Layer-wise Adaptive Moments)为每层独立做自适应,比 AdamW 更稳定。
- 所有深度学习训练:PyTorch 的
optimizer.step()就是梯度下降——CNN、Transformer、扩散模型,无一例外。详见Transformer 架构。 - 逻辑回归求解:大规模广告 CTR 模型用 SGD/FTRL 在稀疏高维特征上训练,Google/Facebook 的核心广告系统即基于此。
- SVM 对偶优化:SMO 算法本质是坐标下降(一种特殊的优化策略),逐次优化两个拉格朗日乘子。详见SVM 支持向量机。
- 大语言模型预训练:GPT-4、LLaMA 等用 AdamW + cosine 学习率衰减 + warmup 在万亿 token 上训练。详见语言模型演进。
- 扩散模型训练:Stable Diffusion 等生成模型同样用 Adam 优化噪声预测网络。详见扩散模型。
典型类库与工具
Section titled “典型类库与工具”| 类库 | 语言 | 说明 |
|---|---|---|
| torch.optim | Python | PyTorch 优化器模块:SGD、Adam、AdamW、LAMB 等 |
| tf.keras.optimizers | Python | TensorFlow / Keras 优化器,接口与 PyTorch 类似 |
| optax | Python | JAX 生态的优化器库,Google 大模型训练首选 |
| apex | Python | NVIDIA 的混合精度训练库,提供 FusedAdam 等加速优化器 |
| accelerate | Python | HuggingFace 训练加速库,封装多种优化器与学习率调度策略 |
| Muon | Python | 新兴的正交化优化器(2024),用于隐藏层 2D 权重,Kimi.ai 大规模 LLM 训练采用 |
| schedulefree | Python | Schedule-Free SGD/Adam(Defazio et al. 2024),无需手动设计学习率调度 |
| 术语 | 英文 | 解释 |
|---|---|---|
| 随机梯度下降 | SGD | 每次只用一个(或一小批)样本计算梯度,引入随机噪声以加速训练 |
| 小批量 | Mini-batch | 每次迭代使用的一小撮样本(如 32/64/256 个),兼顾速度和稳定性 |
| 动量 | Momentum | 累积历史梯度方向,像惯性一样平滑更新轨迹,加速收敛并冲过浅坑 |
| 学习率衰减 | Learning Rate Decay | 训练后期逐步降低学习率,帮助模型在最优解附近稳定收敛 |
| AdaGrad | AdaGrad | 累积历史梯度平方,给频繁更新的参数更小的学习率(但会单调衰减) |
| RMSProp | RMSProp | 用指数移动平均代替累积,解决 AdaGrad 学习率过早趋零的问题 |
| Adam | Adam | 结合 Momentum(一阶矩)和 RMSProp(二阶矩),自适应学习率 + 动量 |
| AdamW | AdamW | Adam 的改进版,将权重衰减从梯度中解耦,正则化效果更好 |
| 学习率预热 | Warmup | 训练初期从极小学习率线性升温,防止早期梯度不稳定 |
| 梯度裁剪 | Gradient Clipping | 当梯度范数超过阈值时按比例缩放,防止梯度爆炸 |
| Muon | Muon | 正交化优化器(2024),对动量更新矩阵做 Newton-Schulz 正交化,放大”罕见方向” |
| Lion | Lion | 符号优化器(2023),只用梯度符号更新,比 Adam 少一个状态变量 |
| Sophia | Sophia | 二阶优化器(2023),用对角 Hessian 估计加速收敛 |
| Schedule-Free | Schedule-Free | 无需学习率调度的优化器(2024),自动在探索和精调间切换 |
| Cosine 退火 | Cosine Annealing | 学习率按余弦曲线从峰值衰减到最小值,大模型训练标配 |
最新进展(2024-2025)
Section titled “最新进展(2024-2025)”Muon:正交化更新矩阵的新范式
Section titled “Muon:正交化更新矩阵的新范式”Muon(MomentUm Orthogonalized by Newton-Schulz)是 2024 年底由 Keller Jordan 提出的优化器,迅速在社区引起轰动。它的核心创新是:对 SGD-Momentum 产生的更新矩阵做近似正交化处理,然后再更新参数。
设计思路:
为什么正交化有效?实证观察发现,SGD-Momentum 和 Adam 产生的 2D 更新矩阵(权重矩阵)通常条件数极高——即几乎所有更新能量集中在少数几个方向上,而其他”罕见方向”虽然重要但被淹没。正交化把所有奇异值拉到 1,相当于放大了那些被忽略的方向。
Muon 的突破性成果:
- 将 NanoGPT 训练速度记录提升 1.35 倍
- 将 1.5B 参数 Transformer 训练到 GPT-2 XL 水平,计算量仅需 AdamW 的 75%
- 被 Kimi.ai(月之暗面)用于大规模 LLM 训练,是前沿 AI 实验室首次采用非 Adam 系优化器
注意:Muon 只适用于隐藏层的 2D 权重矩阵;嵌入层、分类头、标量参数仍用 AdamW。当前最佳实践是 Muon + AdamW 混合使用。
Schedule-Free Optimizer:无需学习率调度
Section titled “Schedule-Free Optimizer:无需学习率调度”2024 年 Aaron Defazio 等人提出 Schedule-Free SGD/Adam,核心思想是把学习率调度内化到优化器中——不再需要手动设计 warmup + cosine 衰减等复杂调度策略。优化器自动在”探索”(大学习率)和”精调”(小学习率)之间切换,减少了需要调节的超参数数量。Meta 已将其集成到 PyTorch 生态。
Lion:符号优化器
Section titled “Lion:符号优化器”Lion(EvoLved Sign Momentum,2023,Google)由进化算法自动搜索发现,比 Adam 更简单:只用梯度的符号(sign),不需要计算二阶矩 。
优势:内存占用比 Adam 少约 50%(不需要存 ),在大模型训练中有意义。Google VeGVa(2025)进一步将 Lion 与 AdamW 在训练不同阶段切换,综合两者优势。
Sophia:二阶优化器的回归
Section titled “Sophia:二阶优化器的回归”Sophia(Second-order Clipped Stochastic Optimization,2023,Stanford)尝试用对角 Hessian(二阶导数)估计来加速训练,理论上比一阶方法(Adam 等)收敛更快。它用 Hutchinson 方法(随机估计)近似 Hessian 对角线,避免完整 Hessian 的 内存开销。在大语言模型上声称比 Adam 快 2 倍,但泛化性仍在验证中。
收敛理论的新进展
Section titled “收敛理论的新进展”- Adam 终于被证明收敛(Zhang et al., NeurIPS 2022):Reddi et al. (2018) 曾指出 Adam 在某些凸问题上不收敛,Zhang et al. 证明了在适当条件下 Adam 无需任何修改即可收敛,终结了这个长期争论。
- 过参数化(over-parameterized)下的隐式偏置:当参数维度远大于数据量时(大模型常态),SGD/Adam 隐式地找到最小范数解(minimum norm solution)——这解释了为什么过参数化的模型不一定会过拟合。
- Kingma & Ba,「Adam: A Method for Stochastic Optimization」(ICLR 2015):Adam 原始论文,提出自适应矩估计,引用量 10 万+,深度学习最重要的优化器论文之一。
- Loshchilov & Hutter,「Decoupled Weight Decay Regularization」(ICLR 2019):AdamW 论文,指出 Adam 中 L2 正则与权重衰减不等价,并提出解耦方案。
- Ruder,「An overview of gradient descent optimization algorithms」(2016):arXiv 综述,清晰梳理 GD→SGD→Momentum→AdaGrad→RMSProp→Adam 的演进,入门首选。
- Reddi et al.,「On the Convergence of Adam and Beyond」(ICLR 2018):指出 Adam 在某些凸问题上不收敛,提出 AMSGrad 修正——理解 Adam 局限性的关键文献。
- Jordan et al.,「Muon: An optimizer for hidden layers in neural networks」(2024):Muon 优化器原始博文,提出 Newton-Schulz 正交化方案,附带完整 PyTorch 实现和 NanoGPT 训练基准。
- Defazio et al.,「Schedule-Free Learning」(ICLR 2025):Schedule-Free 优化器论文,把学习率调度内化到优化器中,Meta 出品。
- Chen et al.,「Lion: Adapting Large Language Models with Only Sign」(ICLR 2024):Lion 符号优化器论文,由进化算法自动发现。
- Liu et al.,「Sophia: A Scalable Stochastic Second-order Optimizer for Language Model Pre-training」(2023):Sophia 二阶优化器,用对角 Hessian 估计加速 LLM 预训练。