Skip to content

优化与梯度下降

本页速览 训练机器学习模型就是解一个优化问题。本文系统拆解梯度下降家族——批/随机/小批量、动量、Adam/AdamW、学习率调度——以及梯度消失/爆炸、局部最优、loss 不收敛的排查方法。

优化与梯度下降 ​

概念定义:训练 = 最小化损失 ​

机器学习训练的本质是求解一个优化问题:找到参数 θ,使损失函数 L(θ) 最小。以线性回归为例,L(w,b) = 1/n·Σ(yᵢ - ŷᵢ)²,训练就是沿着"损失下降最快的方向"一步步调整 w、b,直到损失不再下降。

这个"沿下降最快的方向走"的方法就是梯度下降(Gradient Descent)——利用损失函数对参数的梯度(导数向量)指示方向,每次朝负梯度方向迈一步。梯度是"损失随参数变化的速度",负梯度就是"下降最快的方向"。

θ ← θ - η·∇L(θ)
     ↑    ↑
   参数  学习率(步长)× 梯度

一、梯度下降的三个变体 ​

按"每次用多少数据算梯度"划分:

变体每次更新用特点适用
批量梯度下降(BGD)全部样本梯度准确,但每步要遍历全量,慢、吃内存小数据集
随机梯度下降(SGD)1 个样本每步快、有随机性可跳出局部最优,但噪声大、收敛震荡中大数据集
小批量梯度下降(Mini-batch)一小批(32/64/128…)折中:梯度较准 + 向量化加速 + 噪声可控深度学习的默认

小批量是实践标准:批量大小(batch size)是重要超参数——太小噪声大收敛慢,太大梯度准但容易陷入尖锐极小值、且吃显存。

为什么"随机性"是优点

SGD 的噪声让它有机会跳出局部极小值(局部最优);批量越大梯度越平滑,越容易停在尖锐的局部极小点(泛化往往更差)。实践中常观察到:小批量训练的模型泛化更好。这是"噪声即正则化"的实例。

二、学习率:最重要的超参数 ​

学习率 η 决定每步走多远,是几乎所有模型的第一超参数:

学习率太大 → 震荡发散(loss 上升/NaN)
学习率适中 → 快速收敛
学习率太小 → 龟速收敛,还容易困在局部最优

学习率调度(Learning Rate Scheduling) ​

固定学习率很少是最优。常用调度策略:

策略做法特点
Step Decay每 N 轮乘 0.1简单,需要调衰减时机
Exponential Decay每轮乘 γ<1平滑衰减
Cosine Annealing余弦曲线降到接近 0训练后期精细收敛,配 warmup 效果好
Warmup + Decay前几轮线性升到峰值再衰减大模型标配(防止初始大梯度破坏预训练权重)

如何找初始学习率 ​

  • 经验范围:默认从 1e-3(Adam)或 1e-2(SGD+momentum)起步;
  • 学习率扫描(LR finder):从极小值指数增长跑几个 batch,画 loss-学习率曲线,选"loss 下降最快段的起点";
  • 大模型训练:warmup 到峰值 1e-4~1e-3 量级。

三、优化器:从 SGD 到 Adam 家族 ​

动量(Momentum):SGD 的改进——更新方向叠加历史梯度方向(像滚球积累动量),能加速收敛、抑制震荡、冲过局部极小值。Nesterov 动量进一步"看一步再走"。

自适应学习率:每个参数有各自的学习率,频繁更新的参数步长小,稀疏参数步长大:

优化器核心机制特点适用
Adagrad累积梯度平方做分母稀疏特征好,但学习率单调衰减到死稀疏特征
RMSProp滑动平均梯度平方修正 Adagrad 衰减问题通用
Adam动量 + RMSProp(一阶+二阶矩估计)默认选择,收敛快、稳、几乎免调深度学习默认
AdamWAdam + 解耦权重衰减正则化更正确,大模型/Transformer 标配大模型/Transformer
SGD+Momentum动量 + 固定学习率泛化常常更好,但要精细调学习率小模型、CV 经典

Adam 的两个注意点

  1. Adam 不是免费午餐:它收敛快但常停在"更宽的极小值",泛化有时不如调好的 SGD+Momentum;
  2. 权重衰减 ≠ L2 正则:Adam 里 L2 的梯度会被二阶矩归一化破坏,正确做法是用解耦的权重衰减(AdamW)——这是训练 Transformer 的必备知识。

四、梯度消失与梯度爆炸 ​

反向传播时梯度逐层相乘,深层网络极易出现:

  • 梯度消失(vanishing):梯度趋近 0,浅层参数几乎不更新 → 深层网络训练不动(2015 年前深度网络难训的根因);
  • 梯度爆炸(exploding):梯度指数增长 → 参数发散、loss 变 NaN。

成因与对策 ​

成因对策
激活函数饱和(sigmoid/tanh 两端导数≈0)换 ReLU/GELU 等非饱和激活
网络过深残差连接(ResNet)、归一化、跳连
初始化不当Xavier/He 初始化、配合激活函数
学习率过大调小学习率、warmup
梯度爆炸梯度裁剪(gradient clipping):超过阈值就缩放,Transformer/LLM 标配

诊断方法:训练时打印各层梯度范数,看是否指数级变小/变大。

五、loss 不收敛排查清单 ​

训练中最常见的求助场景"loss 不动/乱跳/NaN",按优先级排查:

① 检查数据:NaN/无穷值?标签错乱?shuffle 了吗?
② 检查学习率:太大(NaN/震荡)还是太小(不动)?
③ 检查损失函数:实现对吗?先过拟合 1 个 batch 验证可实现性
④ 检查归一化:输入标准化了吗?未归一化是梯度问题的头号来源
⑤ 检查初始化:Xavier/He 用了吗?
⑥ 检查模型:前向/反向有 bug 吗?过拟合一个样本测试
⑦ 检查梯度:打印梯度范数,消失还是爆炸?

最快验证模型正确性的技巧

先在一个 batch(甚至一个样本)上过拟合:如果模型连一个样本都拟合不了(loss 不降到接近 0),说明模型/损失/数据管道有 bug,而不是优化问题。这是深度学习调试的第一招。

六、与正则化的交互 ​

优化和正则化是一对:

  • 早停:监控验证集停止训练,本身就是一种"隐式正则化"(限制有效步数);
  • 权重衰减(L2):在损失里加惩罚项,等价于限制参数范数,也稳定优化;
  • 噪声即正则化:SGD 的随机性、Dropout 的随机丢弃,都在给优化路径注入噪声,换取更好泛化;
  • 学习率与泛化:过高学习率虽然收敛快但模型"记不牢"细节;cosine 衰减后期的小学习率常带来更好的泛化。

七、权衡与取舍 ​

  • Adam vs SGD:快速上线、省心用 Adam;追求最优泛化、有时间调参用 SGD+Momentum;大模型/Transformer 用 AdamW。
  • batch size:显存允许范围里,大 batch 训练快但可能牺牲泛化;配合学习率 warmup 可缓解。
  • 训练速度 vs 收敛质量:余弦退火 + warmup 牺牲一点前期速度换后期精度,大模型训练事实标准。
  • 自动微分框架:PyTorch/TensorFlow 已把梯度计算自动化,你要管的是学习率、优化器、调度器、裁剪这四个旋钮。

延伸阅读 ​

参考资料 ​