外观
优化与梯度下降
概念定义:训练 = 最小化损失
机器学习训练的本质是求解一个优化问题:找到参数 θ,使损失函数 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(一阶+二阶矩估计) | 默认选择,收敛快、稳、几乎免调 | 深度学习默认 |
| AdamW | Adam + 解耦权重衰减 | 正则化更正确,大模型/Transformer 标配 | 大模型/Transformer |
| SGD+Momentum | 动量 + 固定学习率 | 泛化常常更好,但要精细调学习率 | 小模型、CV 经典 |
Adam 的两个注意点
- Adam 不是免费午餐:它收敛快但常停在"更宽的极小值",泛化有时不如调好的 SGD+Momentum;
- 权重衰减 ≠ 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 已把梯度计算自动化,你要管的是学习率、优化器、调度器、裁剪这四个旋钮。
延伸阅读
- 深度学习基础——反向传播的数学机制
- 过拟合与正则化——早停、权重衰减的完整讨论
- 调参与超参数优化——学习率/批量/优化器联合搜索
- 常见陷阱与反模式——loss 不收敛的经典翻车现场
- 数学基础速查——梯度、凸优化的数学背景
参考资料
- Ruder. An overview of gradient descent optimization algorithms(2016/2017) —— 优化器全家桶权威综述
- Kingma & Ba. Adam: A Method for Stochastic Optimization(ICLR 2015) —— Adam 原始论文
- Loshchilov & Hutter. Decoupled Weight Decay Regularization(AdamW, ICLR 2019) —— AdamW 原始论文
- Smith. Cyclical Learning Rates for Training Neural Networks(2017) —— LR finder 原始论文
- Glorot & Bengio. Understanding the difficulty of training deep feedforward neural networks(2010) —— 初始化与梯度问题奠基
- He et al. Delving Deep into Rectifiers(2015) —— He 初始化