反向传播及其用法

来自 千问

在 PyTorch 中,反向传播是模型训练的核心环节。简单来说,它的作用就是**"自动算出每个参数(权重)对最终错误(损失)的影响有多大"**,从而指导优化器知道该往哪个方向调整参数才能让模型变得更好。

PyTorch 的核心优势在于它通过 torch.autograd 模块实现了自动微分,你不需要手动推导复杂的导数公式,只需要构建前向计算过程,PyTorch 就能自动帮你搞定反向传播。

核心原理:三步走

在 PyTorch 中实现反向传播通常遵循以下三个关键步骤:

  1. 前向传播:计算模型的预测值,并计算出损失(Loss)。
  2. 反向传播 :调用 loss.backward(),PyTorch 自动计算梯度。
  3. 更新参数:优化器根据计算出的梯度更新模型权重。

详细解析与代码示例

为了让你彻底理解,我们用一个最简单的线性回归例子来拆解这个过程。

1. 准备工作:标记需要追踪的变量

首先,我们需要告诉 PyTorch:"请帮我盯着这个变量,我要计算它的梯度。" 这是通过设置 requires_grad=True 来实现的。

python 复制代码
import torch

# 定义权重 w 和偏置 b,并标记 requires_grad=True
w = torch.tensor(2.0, requires_grad=True) 
b = torch.tensor(1.0, requires_grad=True) 
x = torch.tensor(3.0) # 输入数据,不需要计算梯度
y_true = torch.tensor(8.0) # 真实标签
2. 前向传播:构建计算图

我们进行正常的计算:y_pred = w * x + b。在这个过程中,PyTorch 不仅计算了结果,还在后台悄悄构建了一张计算图(Computational Graph)。这张图记录了数据是如何流动和变换的。

python 复制代码
# 前向传播
y_pred = w * x + b        # 预测值: 2*3 + 1 = 7
loss = (y_pred - y_true)**2  # 损失: (7-8)² = 1

# 此时,loss 是一个标量(Scalar),且它知道它是怎么算出来的
3. 反向传播:自动计算梯度

这是最关键的一步。我们调用 loss.backward()。PyTorch 会从 loss 开始,沿着刚才构建的计算图反向 遍历,利用链式法则 自动计算出 wb 的梯度,并把结果存储在 w.gradb.grad 中。

python 复制代码
# 反向传播
loss.backward()

# 查看计算出的梯度
print(f"w 的梯度: {w.grad}") # 输出: tensor(-6.)
print(f"b 的梯度: {b.grad}") # 输出: tensor(-2.)

发生了什么?(数学推导)

  • 对 w 求导d(loss)/d(w) = 2*(y_pred - y_true) * x = 2*(7-8)*3 = -6
  • 对 b 求导d(loss)/d(b) = 2*(y_pred - y_true) * 1 = 2*(7-8)*1 = -2
    PyTorch 帮你自动完成了这些复杂的求导计算。
4. 更新参数:梯度下降

拿到了梯度,我们就可以更新参数了。注意:更新参数的操作通常需要包裹在 torch.no_grad(),以防止更新操作被记录进计算图(否则会造成内存泄漏)。

python 复制代码
learning_rate = 0.1

with torch.no_grad(): # 暂时关闭梯度追踪
    # 梯度下降更新公式:参数 = 参数 - 学习率 * 梯度
    w -= learning_rate * w.grad
    b -= learning_rate * b.grad

# ⚠️ 重要:清空梯度
# 如果不清零,下次计算的梯度会和这次的累加在一起(变成累加器)
w.grad.zero_()
b.grad.zero_()

在真实模型训练中的完整流程

在实际使用 nn.ModuleDataLoader 时,代码结构通常是这样的:

python 复制代码
import torch
import torch.nn as nn
import torch.optim as optim

# 假设 model 是你的神经网络,criterion 是损失函数
model = nn.Linear(1, 1) # 示例模型
criterion = nn.MSELoss()
optimizer = optim.SGD(model.parameters(), lr=0.01)

# 训练循环
for epoch in range(100):
    # 1. 获取数据
    inputs, targets = get_data() 
    
    # 2. 前向传播
    outputs = model(inputs)
    loss = criterion(outputs, targets)
    
    # 3. 反向传播前,先清空上一轮的梯度(非常重要!)
    optimizer.zero_grad() # 或者 model.zero_grad()
    
    # 4. 反向传播:计算梯度
    loss.backward()
    
    # 5. 更新参数
    optimizer.step()

关键注意事项

  1. 梯度累加 :PyTorch 默认会将梯度累加 。这意味着如果你不手动调用 optimizer.zero_grad()w.grad.zero_(),每次 backward() 计算出的梯度都会加到之前的梯度上。这在某些场景(如梯度累积模拟大 batch)下是有用的,但在标准训练中必须清零。
  2. requires_grad :只有设置了 requires_grad=True 的张量,才会计算和存储梯度。
  3. no_grad :在推理(测试)阶段或更新参数时,使用 with torch.no_grad(): 可以节省内存并防止意外构建计算图。

总结来说,PyTorch 的反向传播机制就是:构建计算图 -> 调用 .backward() -> 获取 .grad -> 更新参数。这套机制让深度学习的实现变得异常简洁和直观。

相关推荐
抠头专注python环境配置2 小时前
基于Pytorch ResNet50 的珍稀野生动物识别系统(Python源码 + PyQt5 + 数据集)
pytorch·python
永恒的溪流6 小时前
环境出问题,再修改
pytorch·python·深度学习
工程师老罗7 小时前
Pytorch中的优化器及其用法
人工智能·pytorch·python
m0_462605229 小时前
第G4周:CGAN|生成手势图像 | 可控制生成
pytorch
工程师老罗11 小时前
Pytorch完整的模型训练流程
人工智能·pytorch·深度学习
工程师老罗11 小时前
优化器、反向传播、损失函数之间是什么关系,Pytorch中如何使用和设置?
人工智能·pytorch·python
果粒蹬i13 小时前
基于PyTorch的CNN-BiLSTM时序预测:从数据滑窗到模型部署
人工智能·pytorch·cnn
工程师老罗13 小时前
Pytorch新版本如何使用现有网络模型,怎么修改现有模型
人工智能·pytorch·深度学习
2301_7644413314 小时前
基于python与PyQt5对本地部署Qwen3-ASR的7B模型语音转文本
pytorch·python·qt