反向传播及其用法

来自 千问

在 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 -> 更新参数。这套机制让深度学习的实现变得异常简洁和直观。

相关推荐
AI技术增长9 分钟前
Pytorch图像去噪实战(二):用UNet解决DnCNN细节丢失问题(结构解析+完整代码+踩坑总结)
人工智能·pytorch·python
AI技术增长2 小时前
Pytorch图像去噪实战(五):FFDNet可控图像去噪实战,用噪声强度图解决不同噪声等级问题
pytorch·python·深度学习
AI技术增长3 小时前
Pytorch图像去噪实战(三):ResUNet图像去噪模型实战,解决UNet深层训练不稳定问题
人工智能·pytorch·深度学习
ting94520003 小时前
动手学深度学习(PyTorch版)深度详解(1)(含实操+避坑)
pytorch·深度学习·学习
nervermore9904 小时前
3. 人工智能学习-PyTorch框架学习
人工智能·pytorch·学习
数据牧羊人的成长笔记5 小时前
认识深度学习_PyTorch入门+神经网络基础+卷积神经网络+迁移学习+生成对抗网络_GAN+CNN目标检测+循环神经网络与NLP
pytorch·深度学习·神经网络
kishu_iOS&AI5 小时前
NLP —— 文本预处理
人工智能·pytorch·python·自然语言处理
AI技术增长6 小时前
Pytorch图像去噪实战(一):从0复现DnCNN并解决训练不收敛问题(附完整工程+踩坑总结)
人工智能·pytorch·python
bst@微胖子6 小时前
PyTorch深度学习框架之基于CNN的手机价格分类任务
pytorch·深度学习·cnn
Westward-sun.7 小时前
YOLOv5 最新版从零配置环境到训练自己的数据集
人工智能·pytorch·深度学习·yolo