🎯 学习目标

  • 理解自动求导的基本原理和计算图
  • 掌握requires_grad属性的使用方法
  • 熟练运用backward()进行反向传播
  • 了解梯度计算的注意事项和常见问题
计算图概念

Autograd简介

Autograd是PyTorch的自动微分引擎,它能够自动追踪所有操作并构建计算图, 在反向传播时自动计算梯度。这使得我们无需手动推导和编写复杂的梯度计算代码, 大大简化了深度学习模型的训练过程。

📊 计算图原理

前向传播

从输入到输出,记录所有操作

# 构建计算图 x = torch.tensor([2.0], requires_grad=True) y = x ** 2 # y = x² z = y + 3 # z = x² + 3

反向传播

从输出到输入,自动计算梯度

# 反向传播计算梯度 z.backward() print(x.grad) # dz/dx = 2x = 4 # 计算链: dz/dy=1, dy/dx=2x # dz/dx = dz/dy * dy/dx = 4

🔑 requires_grad属性

import torch # 设置requires_grad=True追踪梯度 x = torch.tensor([1.0, 2.0, 3.0], requires_grad=True) print(x.requires_grad) # True # 任何对x的操作都会被追踪 y = x * 2 z = y.mean() print(z.requires_grad) # True (继承自x) # 在不需要梯度时禁用追踪 with torch.no_grad(): w = x * 3 print(w.requires_grad) # False # 使用detach()分离张量 detached = x.detach() print(detached.requires_grad) # False

backward()方法详解

# 标量输出的反向传播 x = torch.randn(3, requires_grad=True) y = x.sum() y.backward() # 自动计算梯度 print(x.grad) # tensor([1., 1., 1.]) # 向量输出的反向传播(需要传入gradient参数) x = torch.randn(3, requires_grad=True) y = x * 2 # 传入与y形状相同的权重向量 y.backward(torch.tensor([1.0, 1.0, 1.0])) print(x.grad) # tensor([2., 2., 2.]) # 梯度累加问题 x = torch.tensor([1.0], requires_grad=True) y = x * 2 y.backward() print(x.grad) # tensor([2.]) z = x * 3 z.backward() print(x.grad) # tensor([5.]) 梯度累加! # 需要清零梯度 x.grad.zero_()

⚖️ 常用梯度操作对比

操作 作用 使用场景
backward() 执行反向传播计算梯度 训练时计算损失对参数的梯度
grad.zero_() 清零梯度值 每次迭代前清空上轮梯度
torch.no_grad() 禁用梯度追踪上下文 模型评估、推理阶段
detach() 返回不需要梯度的新张量 将张量从计算图中分离
requires_grad_() 原地修改requires_grad属性 动态启用/禁用梯度追踪

🧮 实战示例:线性回归

import torch # 准备数据 x_train = torch.tensor([[1.0], [2.0], [3.0], [4.0]]) y_train = torch.tensor([[2.0], [4.0], [6.0], [8.0]]) # 初始化参数(需要梯度) W = torch.randn(1, 1, requires_grad=True) b = torch.randn(1, requires_grad=True) # 超参数 learning_rate = 0.01 epochs = 1000 for epoch in range(epochs): # 前向传播 y_pred = x_train @ W + b loss = ((y_pred - y_train) ** 2).mean() # 反向传播 loss.backward() # 更新参数(不追踪梯度) with torch.no_grad(): W -= learning_rate * W.grad b -= learning_rate * b.grad # 清零梯度 W.grad.zero_() b.grad.zero_() print(f'W = {W.item():.4f}, b = {b.item():.4f}') # W ≈ 2.0, b ≈ 0.0
⚠️
注意事项

PyTorch默认会累加梯度,每次backward()后需要手动清零梯度。忘记清零会导致梯度累积,影响训练效果。

神经网络计算图
图:计算图是自动求导的基础数据结构

📝 本节小结

  • • Autograd自动追踪Tensor操作并构建计算图
  • • requires_grad=True启用梯度追踪
  • • backward()执行反向传播计算梯度
  • • torch.no_grad()用于禁用梯度追踪
  • • 梯度会累加,需要手动调用grad.zero_()清零