这三者构成了 PyTorch 模型训练的核心闭环。如果把模型训练比作一次**“寻宝”**过程,那么它们的角色是这样的:
- 损失函数:扮演**“指南针/裁判”**。它告诉我们在当前位置距离宝藏有多远(计算误差)。
- 反向传播:扮演**“路线分析员”**。它根据指南针的反馈,分析出“往东走一步海拔会降低多少,往北走一步会降低多少”(计算梯度)。
- 优化器:扮演**“探险家”**。它根据分析员给出的方向和步长建议,迈出实际的步伐(更新参数)。
下面我将详细拆解它们之间的关系以及在 PyTorch 中的标准配合流程。
1. 三者之间的逻辑关系
2. PyTorch 中的标准使用流程
在 PyTorch 中,这三者的配合有着非常固定的**“五步走”**模式。请务必牢记这个模板:
第一步:定义组件
在训练开始前,你需要先准备好这三样工具。
import torch
import torch.nn as nn
import torch.optim as optim
# 假设 model 是你定义好的网络
model = MyModel()
# 1. 定义损失函数 (例如分类任务用交叉熵)
criterion = nn.CrossEntropyLoss()
# 2. 定义优化器 (告诉它要管理 model 的哪些参数,以及学习率)
optimizer = optim.Adam(model.parameters(), lr=0.001)
第二步:训练循环中的协作
这是最核心的部分,代码结构如下:
for data, target in dataloader: # 遍历数据
# — 1. 前向传播 —
# 数据通过模型,得到预测
output = model(data)
# — 2. 计算损失 —
# 使用损失函数,计算预测和真实的差距
loss = criterion(output, target)
# — 3. 反向传播前的准备:梯度清零 —
# ⚠️ 重要:必须在反向传播前清空上一轮的梯度
# 否则梯度会累加,导致爆炸或错误
optimizer.zero_grad()
# — 4. 反向传播:计算梯度 —
# ⚡ 核心:PyTorch 自动计算所有参数的梯度
# 计算图开始反向流动,填充 .grad 属性
loss.backward()
# — 5. 优化器:更新参数 —
# ⚙️ 核心:根据刚才算出的梯度,更新模型参数
optimizer.step()
3. 深入拆解:每一步发生了什么
为了让你更清楚底层发生了什么,我们结合代码看细节:
A. 损失函数的作用
loss = criterion(output, target)
- 输入:模型的原始输出(可能是 logits)和真实标签。
- 输出:一个标量数值(Scalar Tensor)。
- 关键:这个 loss 变量内部保存了计算图的引用。它记住了自己是怎么算出来的,这为下一步反向传播提供了路径。
B. 反向传播的作用
loss.backward()
- 执行:从 loss 开始,沿着计算图反向推导。
- 结果:此时,模型中的每一个参数(weight, bias)都会被计算出一个梯度,并存储在 param.grad 中。
- 注意:你通常不需要手动去取这些梯度,优化器会自动去读取它们。
C. 优化器的作用
optimizer.step()
- 读取:优化器会遍历它管理的所有参数,读取每个参数的 grad。
- 更新:
- 如果是 SGD:参数 = 参数 – 学习率 * 梯度
- 如果是 Adam:根据梯度的一阶矩和二阶矩,自适应地调整步长。
- 结果:模型的参数值被修改了,模型变得“更好”了一点。
4. 总结图谱
你可以把这三者的关系想象成**“工厂质检与改进”**:
在 PyTorch 中,你只需要按顺序写好 zero_grad() -> backward() -> step(),剩下的数学细节框架都帮你自动处理好了。





