跳转至

优化与训练技巧

网络架构决定了模型"能不能学",而优化策略和训练技巧决定了模型"学得好不好"。本文覆盖优化器、正则化、归一化和学习率调度等关键训练技术。


1. 优化器(Optimizer)

优化器的任务是根据梯度更新参数,使损失函数最小化。不同的优化器本质上是不同的参数更新策略

SGD(随机梯度下降)

最基础的优化器:

\[ \theta_{t+1} = \theta_t - \eta \cdot \nabla_\theta L(\theta_t) \]
  • ✅ 简单,理论性质好
  • ❌ 收敛慢,容易在鞍点/平坦区域停滞
  • ❌ 对学习率敏感

SGD + Momentum(动量)

引入"惯性":梯度不再只看当前方向,还会参考之前的运动趋势。

\[ \mathbf{v}_t = \beta \mathbf{v}_{t-1} + \nabla_\theta L(\theta_t) \]
\[ \theta_{t+1} = \theta_t - \eta \cdot \mathbf{v}_t \]

\(\beta\) 通常取 0.9。

直觉

想象一个球从山上滚下来。没有动量时,球遇到小坑就停了;有动量时,球靠着惯性能冲过小坑,更容易滚到谷底。

AdaGrad

自适应调整每个参数的学习率——梯度累积大的参数(更新频繁的),学习率变小;反之变大。

\[ \theta_{t+1,i} = \theta_{t,i} - \frac{\eta}{\sqrt{G_{t,ii} + \epsilon}} \cdot g_{t,i} \]

其中 \(G_t\) 是梯度平方的累积和。

  • ✅ 不同参数自适应学习率
  • ❌ 学习率单调递减,后期可能过小导致停止学习

RMSProp

修复 AdaGrad 的问题:用指数移动平均替代累积和,让学习率不会一直衰减。

\[ E[g^2]_t = \beta E[g^2]_{t-1} + (1-\beta) g_t^2 \]
\[ \theta_{t+1} = \theta_t - \frac{\eta}{\sqrt{E[g^2]_t + \epsilon}} \cdot g_t \]

Adam(Adaptive Moment Estimation)⭐

结合了 Momentum(一阶矩估计)和 RMSProp(二阶矩估计),是目前最常用的优化器

\[ \mathbf{m}_t = \beta_1 \mathbf{m}_{t-1} + (1-\beta_1) \mathbf{g}_t \quad \text{(一阶矩:梯度的均值)} \]
\[ \mathbf{v}_t = \beta_2 \mathbf{v}_{t-1} + (1-\beta_2) \mathbf{g}_t^2 \quad \text{(二阶矩:梯度的方差)} \]

偏差校正:

\[ \hat{\mathbf{m}}_t = \frac{\mathbf{m}_t}{1-\beta_1^t}, \quad \hat{\mathbf{v}}_t = \frac{\mathbf{v}_t}{1-\beta_2^t} \]

参数更新:

\[ \theta_{t+1} = \theta_t - \frac{\eta}{\sqrt{\hat{\mathbf{v}}_t} + \epsilon} \cdot \hat{\mathbf{m}}_t \]

默认超参数:\(\beta_1 = 0.9\)\(\beta_2 = 0.999\)\(\epsilon = 10^{-8}\)

AdamW

Adam 的改进版,将权重衰减(Weight Decay)从梯度计算中解耦出来:

\[ \theta_{t+1} = \theta_t - \eta \left( \frac{\hat{\mathbf{m}}_t}{\sqrt{\hat{\mathbf{v}}_t} + \epsilon} + \lambda \theta_t \right) \]

Adam vs AdamW

标准 Adam 中,L2 正则化和自适应学习率会相互干扰(正则化的梯度也会被自适应缩放)。AdamW 直接在参数上做衰减,效果更好,是 Transformer 训练的默认选择。

优化器对比总结

优化器 自适应学习率 动量 推荐场景
SGD 理论研究
SGD + Momentum 计算机视觉(配合调度器)
Adam ⭐ 通用默认选择
AdamW ⭐ Transformer / 大模型

2. 学习率调度(Learning Rate Schedule)

学习率是最重要的超参数之一。太大会导致震荡发散,太小会收敛过慢。学习率调度让学习率在训练过程中动态变化。

常见调度策略

Step Decay

每过固定步数,学习率乘以一个衰减因子:

\[ \eta_t = \eta_0 \cdot \gamma^{\lfloor t / T \rfloor} \]

Cosine Annealing(余弦退火)

学习率按余弦函数从初始值平滑下降到接近 0:

\[ \eta_t = \eta_{\min} + \frac{1}{2}(\eta_{\max} - \eta_{\min})\left(1 + \cos\frac{t\pi}{T}\right) \]

⭐ 现代训练中非常流行,尤其配合 Warmup。

Warmup + Cosine Decay

先用一小段时间线性增大学习率(Warmup),再用余弦退火下降。这是 Transformer 训练的标准范式:

学习率
  │    /\
  │   /  \
  │  /    ╲
  │ /      ╲
  │/        ╲___
  └──────────────→ 训练步数
  Warmup  Cosine Decay

为什么需要 Warmup?

训练初期,参数随机初始化,梯度方向不稳定。如果一开始学习率就很大,容易导致训练不稳定甚至发散。Warmup 让网络先"热身",等梯度方向稳定了再加速。

PyTorch 示例

from torch.optim import AdamW
from torch.optim.lr_scheduler import CosineAnnealingLR

optimizer = AdamW(model.parameters(), lr=1e-3, weight_decay=0.01)
scheduler = CosineAnnealingLR(optimizer, T_max=100, eta_min=1e-6)

for epoch in range(100):
    train_one_epoch(model, optimizer)
    scheduler.step()

3. 正则化技术

正则化的目标是防止过拟合,提高模型的泛化能力。

Dropout

训练时随机"关闭"一部分神经元(把输出置零),比例为 \(p\)(常见 \(p = 0.1 \sim 0.5\)):

\[ \hat{a}_i = \begin{cases} 0 & \text{with probability } p \\ \frac{a_i}{1-p} & \text{with probability } 1-p \end{cases} \]

除以 \((1-p)\) 是为了保证期望值不变(Inverted Dropout)。

为什么 Dropout 有效?

  • 防止神经元之间的共适应(co-adaptation):每个神经元不能依赖特定的其他神经元
  • 等效于训练了指数级多个子网络的集成
  • 推理时关闭 Dropout,使用完整网络

注意事项:

  • 通常加在全连接层,卷积层效果不显著
  • 推理时不用 Dropoutmodel.eval() 会自动关闭)
  • Transformer 中通常对 Attention 权重和前馈层都用 Dropout

L2 正则化 / Weight Decay

在损失函数中加入参数的平方和:

\[ L_{\text{total}} = L_{\text{data}} + \frac{\lambda}{2}\sum_i w_i^2 \]

效果:限制参数不要太大,防止模型太"激进"。

Label Smoothing

将 one-hot 硬标签变成软标签,避免模型对训练标签过度自信:

\[ y_i^{\text{smooth}} = (1-\alpha) \cdot y_i + \frac{\alpha}{K} \]

其中 \(\alpha\) 通常取 0.1,\(K\) 是类别数。比如将 \([0, 0, 1, 0]\) 变为 \([0.025, 0.025, 0.925, 0.025]\)

数据增强(Data Augmentation)

通过对训练数据做变换来扩充训练集,是最直接的正则化手段:

数据类型 常用增强方法
图像 翻转、旋转、裁剪、色彩抖动、Cutout、MixUp
文本 同义词替换、回译、随机删除/插入
音频 加噪、变速、SpecAugment

Early Stopping

监控验证集损失,当验证损失不再下降时提前终止训练

训练损失   ↘ 持续下降
验证损失   ↘ 先下降 → 触底 → 开始上升 ← 停在这里!

4. 归一化技术

归一化层稳定训练过程,加速收敛,是现代深度网络的标配。

Batch Normalization(BN)

对一个 mini-batch 内的数据,在每个通道上做归一化:

\[ \hat{x}_i = \frac{x_i - \mu_B}{\sqrt{\sigma_B^2 + \epsilon}}, \quad y_i = \gamma \hat{x}_i + \beta \]

其中 \(\mu_B\)\(\sigma_B^2\) 是 batch 内的均值和方差,\(\gamma\)\(\beta\) 是可学习的缩放和平移参数。

为什么 BN 有效?

  • 缓解内部协变量偏移(Internal Covariate Shift):前一层参数变化导致后一层输入分布变化
  • 允许使用更大的学习率
  • 有轻微正则化效果(batch 带来的随机性)

注意事项:

  • 对 batch size 敏感——batch 太小时统计量不稳定
  • 推理时使用训练阶段的移动平均统计量
  • 不适合序列模型(序列长度不固定)

Layer Normalization(LN)

单个样本的所有特征做归一化,不依赖 batch:

\[ \hat{x}_i = \frac{x_i - \mu}{\sqrt{\sigma^2 + \epsilon}}, \quad \mu = \frac{1}{D}\sum_{i=1}^{D} x_i \]
  • ✅ 不依赖 batch size
  • ✅ 适合序列模型和 Transformer
  • Transformer 的标准归一化方式

归一化方式对比

方法 归一化维度 适用场景 依赖 batch
Batch Norm batch 维度 CNN(图像) ✅ 是
Layer Norm 特征维度 Transformer、RNN ❌ 否
Instance Norm 单个样本的空间维度 风格迁移 ❌ 否
Group Norm 通道分组 小 batch CNN ❌ 否

5. 梯度相关问题与对策

梯度消失

现象:深层网络的浅层梯度极小,参数几乎不更新。

对策

技术 原理
ReLU 激活函数 正区间梯度恒为 1
残差连接(ResNet) 梯度可直接跳过层传递
Batch/Layer Norm 稳定各层输入分布
合理的权重初始化 He / Xavier 初始化

梯度爆炸

现象:梯度值异常大,参数更新剧烈,loss 变成 NaN。

对策

  • 梯度裁剪(Gradient Clipping):限制梯度范数上界
torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm=1.0)
  • 使用更小的学习率
  • 使用归一化层

6. 混合精度训练

使用 FP16(半精度浮点)代替 FP32 进行前向和反向传播,大幅降低显存占用和计算时间:

精度 位数 范围 用途
FP32 32 bit \(\sim 10^{-38} \sim 10^{38}\) 参数存储(主副本)
FP16 16 bit \(\sim 10^{-8} \sim 65504\) 前向/反向计算
BF16 16 bit 与 FP32 相同指数范围 更稳定的半精度训练

Loss Scaling

FP16 的精度较低,小梯度可能下溢为 0。解决方案:训练时将 loss 放大(如乘 1024),反向传播后再缩小梯度。

PyTorch 混合精度示例

from torch.amp import autocast, GradScaler

scaler = GradScaler()

for data, target in dataloader:
    optimizer.zero_grad()

    with autocast(device_type='cuda'):      # 自动选择 FP16 计算
        output = model(data)
        loss = criterion(output, target)

    scaler.scale(loss).backward()           # 缩放后的反向传播
    scaler.step(optimizer)                  # 还原缩放后更新参数
    scaler.update()

7. 训练流程 Checklist

一个典型的深度学习训练流程:

graph TD
    A[准备数据 & 增强] --> B[定义模型架构]
    B --> C[选择损失函数]
    C --> D[选择优化器 & 学习率调度]
    D --> E[训练循环]
    E --> F{验证集效果}
    F -->|过拟合| G[加正则化 / 减模型 / 加数据]
    F -->|欠拟合| H[加模型复杂度 / 减正则化]
    F -->|满意| I[测试集评估 & 部署]
    G --> E
    H --> E

常见训练配置参考

任务 优化器 学习率 调度器 正则化
图像分类(CNN) SGD + Momentum 0.1 Cosine / Step BN + 数据增强
NLP(Transformer) AdamW 1e-4 ~ 5e-4 Warmup + Cosine Dropout + LN
微调预训练模型 AdamW 1e-5 ~ 3e-5 Linear Warmup Dropout
小数据集 Adam 1e-3 ReduceOnPlateau Dropout + 数据增强 + Early Stop