反向传播及其用法

来自 千问

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

相关推荐
龙文浩_4 小时前
AI深度学习中的PyTorch与张量案例
人工智能·pytorch·深度学习
Storynone13 小时前
【踩坑笔记】Geforce RTX5060 显卡对应的 Pytorch 安装
人工智能·pytorch·笔记
我材不敲代码14 小时前
NLP 入门——PyTorch 从零实现 Word2Vec 之 CBOW 模型
pytorch·自然语言处理·word2vec
郝学胜-神的一滴15 小时前
PyTorch张量维度操控:transpose与permute深度拆解与实战指南
人工智能·pytorch·python·深度学习·算法·机器学习
星川皆无恙16 小时前
Transformer学习笔记:从 Attention 核心理论到机器翻译代码项目学习实战
大数据·pytorch·笔记·深度学习·神经网络·自然语言处理·transformer
dazzle18 小时前
机器学习算法原理与实践-入门(十一):基于PyTorch的房价预测实战
pytorch·算法·机器学习
白小筠1 天前
Pytorch之张量的基本操作
人工智能·pytorch·python
热爱生活的猴子2 天前
PyTorch导出ONNX报错(ShapeInferenceError)问题笔记(含dynamo=False作用解析)
人工智能·pytorch·笔记
YuanDaima20482 天前
解决Conda环境下RTX 50系列显卡PyTorch+Transformers+PEFT微调报错
人工智能·pytorch·笔记·python·深度学习·机器学习·conda
郝学胜-神的一滴2 天前
张量维度操控心法:从reshape到升维降维,吃透PyTorch形状操作的底层逻辑
人工智能·pytorch·python·深度学习·程序人生·算法·机器学习