第 3 章 模型训练
模型训练的基本流程:
输入数据 -> 模型预测 -> 计算损失 -> 反向传播求梯度 -> 优化器更新参数本章整理训练模型时最核心的几个概念:损失函数、反向传播、梯度下降和常见优化器。
3.1 模型、参数和损失函数
模型负责把输入
其中
损失函数用来衡量预测值
整体目标通常写成:
其中:
| 符号 | 含义 |
|---|---|
| 单个样本的损失 | |
| 整个训练集上的平均损失 | |
| 训练样本数量 | |
| 模型参数 |
3.2 常见损失函数
不同任务使用不同损失函数。
均方误差
均方误差常用于回归任务:
对整个训练集:
前面的
平均绝对误差
平均绝对误差也用于回归:
它比均方误差对极端误差不那么敏感,但在 0 点附近不可导,优化时没有均方误差那么方便。
二分类交叉熵
二分类中,模型输出通常表示样本属于正类的概率:
二分类交叉熵:
如果真实标签是 1,损失主要看
多分类交叉熵
多分类中,模型通常先输出每个类别的 logit,再通过 Softmax 变成概率:
其中
这里
如果标签用 one-hot 向量表示,单个样本的多分类交叉熵为:
因为 one-hot 标签中只有真实类别的位置为 1,其他位置为 0,所以上式等价于:
其中
3.3 前向传播和反向传播
前向传播负责把输入样本代入模型,得到预测值,再把预测值和真实标签放进损失函数中计算误差。
反向传播负责计算损失函数对每个参数的梯度:
梯度表示:参数
反向传播主要依赖链式法则。假设:
那么:
复杂模型可以看成很多函数组合。反向传播就是从损失开始,沿计算图从后往前应用链式法则,把梯度传回每个参数。
需要区分:
| 概念 | 作用 |
|---|---|
| 前向传播 | 计算预测和损失 |
| 反向传播 | 计算梯度 |
| 优化器 | 根据梯度更新参数 |
PyTorch、TensorFlow 会自动完成反向传播,但本质仍然是链式法则。
3.4 梯度下降
有了梯度以后,就可以更新参数。梯度下降的基本更新公式是:
向量形式:
其中
| 部分 | 含义 |
|---|---|
| 损失上升最快的方向 | |
| 负号 | 沿损失下降方向更新 |
| 每次更新的步长 |
学习率太小,训练很慢;学习率太大,损失可能震荡甚至发散。
常见现象:
| 现象 | 可能原因 |
|---|---|
| 损失下降很慢 | 学习率太小 |
| 损失上下震荡 | 学习率太大 |
| 损失变成非数值 | 学习率过大、梯度爆炸、对 0 取对数、除以 0、数值溢出 |
| 训练几乎不动 | 学习率太小、梯度消失、模型实现错误 |
3.5 梯度估计方式
梯度下降的区别主要在于:每次用多少样本估计梯度。
批量梯度下降
批量梯度下降(Batch Gradient Descent, BGD)每次使用全部训练样本:
特点:
- 梯度方向稳定。
- 每次更新成本高。
- 数据量很大时训练慢。
随机梯度下降
随机梯度下降(Stochastic Gradient Descent, SGD)每次只使用一个样本:
特点:
- 每次更新很快。
- 梯度噪声大。
- 损失曲线震荡明显。
严格来说,SGD 是单样本更新。但实际深度学习中说 SGD,很多时候指 mini-batch SGD。
小批量梯度下降
小批量梯度下降(Mini-batch Gradient Descent)每次使用一小批样本。设 batch 为
特点:
- 比单样本 SGD 稳定。
- 比批量梯度下降更新频繁。
- 适合 GPU 并行计算。
- 是深度学习最常用的训练方式。
三者对比:
| 方法 | 每次用多少样本 | 梯度噪声 | 单次计算成本 | 更新频率 |
|---|---|---|---|---|
| 批量梯度下降 | 全部样本 | 小 | 高 | 低 |
| 随机梯度下降 | 1 个样本 | 大 | 低 | 高 |
| 小批量梯度下降 | 一批样本 | 中等 | 中等 | 中等 |
3.6 常见优化器
优化器决定如何使用梯度更新参数。
最朴素的梯度下降只看当前梯度,更复杂的优化器会利用历史梯度、自适应学习率或权重衰减。
本节统一使用以下符号:
| 符号 | 含义 |
|---|---|
| 当前更新步数 | |
| 第 | |
| Momentum 中的速度项;Adam 中的二阶矩估计 | |
| AdaGrad 和 RMSProp 中的梯度平方累计量 | |
| Adam 中的一阶矩估计 | |
| 防止分母为 0 的小常数 | |
| 控制历史信息保留比例的系数 | |
| AdamW 中的权重衰减系数 |
SGD
SGD 使用当前 batch 的梯度直接更新参数:
优点是简单、计算开销小;缺点是对学习率敏感,在狭长损失曲面中容易震荡。
Momentum
Momentum 在 SGD 基础上加入历史方向。
维护一个速度项:
更新参数:
其中 0.9。
Momentum 的作用:
| 情况 | 效果 |
|---|---|
| 梯度方向连续一致 | 加速下降 |
| 梯度方向来回摆动 | 抵消震荡 |
| 损失曲面狭长 | 更容易沿主方向前进 |
Momentum 对梯度做指数加权移动平均,用历史梯度方向平滑当前更新。
AdaGrad
AdaGrad 为每个参数维护历史梯度平方和:
更新:
它会让历史梯度大的参数学习率变小,适合稀疏特征。但
RMSProp
RMSProp 使用梯度平方的指数加权平均:
更新:
它缓解了 AdaGrad 后期学习率持续变小的问题。
Adam
Adam 同时使用一阶矩和二阶矩。
一阶矩是梯度的移动平均,类似 Momentum:
二阶矩是梯度平方的移动平均,类似 RMSProp:
更新大致为:
实际 Adam 还会做偏差修正。Adam 收敛通常较快,对学习率相对不那么敏感,但不代表一定比 SGD 泛化更好。
AdamW
AdamW 是 Adam 的常用改进。它把权重衰减从 Adam 的自适应梯度更新中解耦出来:
这样权重衰减直接作用在参数上。现代 Transformer 和大模型训练中常用 AdamW。
3.7 优化器区别
| 优化器 | 核心思想 | 主要优点 | 注意点 |
|---|---|---|---|
| SGD | 当前梯度直接更新 | 简单、稳定 | 对学习率敏感 |
| Momentum | 累积历史梯度方向 | 加速、减少震荡 | 需要设置动量系数 |
| AdaGrad | 每个参数自适应学习率 | 适合稀疏特征 | 学习率可能衰减过快 |
| RMSProp | 梯度平方移动平均 | 缓解 AdaGrad 后期变慢 | 多一个衰减系数 |
| Adam | Momentum + RMSProp | 收敛快,使用广泛 | 泛化不一定总优 |
| AdamW | Adam + 解耦权重衰减 | 适合深度模型 | 仍要调学习率和权重衰减 |
简单理解:
- 梯度下降解决“往哪个方向更新”。
- 学习率解决“每次走多远”。
- Momentum 解决“不要只看当前一步”。
- RMSProp / Adam 解决“不同参数更新幅度应该不同”。
- AdamW 解决“Adam 中权重衰减更清晰地作用在参数上”。
3.8 训练时需要观察什么
训练时不能只看最终准确率。至少要观察:
- 训练损失是否下降。
- 验证损失是否下降。
- 学习率是否合适。
- 梯度是否过大或过小。
- 损失是否变成非数值。
如果训练损失不下降,优先检查损失函数、学习率、数据标签、梯度和模型实现。
如果训练损失下降但验证损失上升,通常说明模型开始过拟合。对应处理方法见模型评估和正则化章节。