自动求导

2. 反向模式(Reverse Mode)

  • 计算方向:从输出到输入,与函数计算方向相反(即 “反向传播”)。
  • 核心思想:先记录函数的计算路径(前向传播),再从输出端反向计算每个变量的梯度。
  • 示例:在神经网络中,先计算预测值(前向传播),再从损失函数出发,反向计算每个参数的梯度(反向传播)。

 

优点:适合输入维度远大于输出维度的场景(如神经网络,输入是大量参数,输出是一个损失值),只需一次反向传播即可计算所有参数的梯度。
缺点:需要额外存储中间变量(计算图),内存消耗较大。

三、自动求导 vs 其他求导方法

方法 优点 缺点
手动求导 精确,无误差 耗时,易出错,无法处理复杂函数
数值微分(有限差分) 实现简单 近似误差(如舍入误差),计算效率低
符号微分 精确,可生成导数表达式 表达式膨胀(如生成的公式过于复杂)
自动求导(反向模式) 精确,高效,适合大规模参数优化 需要存储计算图,内存消耗大

四、代码示例(PyTorch 自动求导)

以下是使用 PyTorch 自动求导的简单示例:
import torch

# 创建需要求导的张量,设置requires_grad=True
x = torch.tensor(3.0, requires_grad=True)
y = torch.tensor(2.0, requires_grad=True)

# 定义函数 z = x^2 + y^3
z = x**2 + y**3

# 计算 z 关于 x 和 y 的梯度
z.backward()  # 自动求导

# 输出梯度
print(f"dz/dx = {x.grad}")  # 输出: 6.0 (因为 dz/dx = 2x = 2*3 = 6)
print(f"dz/dy = {y.grad}")  # 输出: 12.0 (因为 dz/dy = 3y^2 = 3*2^2 = 12)
关键步骤解析

 

  1. 创建可求导张量:通过 requires_grad=True 标记需要求导的变量。
  2. 构建计算图:执行运算(如 z = x**2 + y**3)时,PyTorch 会自动记录计算路径。
  3. 反向传播:调用 z.backward() 触发自动求导,从 z 开始反向计算梯度。
  4. 获取梯度:通过 x.grad 和 y.grad 获取最终梯度值。

五、自动求导在深度学习中的应用

1. 神经网络训练

在训练神经网络时,自动求导与反向传播结合,可高效计算损失函数对所有参数的梯度:
import torch
import torch.nn as nn
import torch.optim as optim

# 定义简单神经网络
model = nn.Sequential(
    nn.Linear(10, 20),  # 输入层到隐藏层
    nn.ReLU(),
    nn.Linear(20, 1)   # 隐藏层到输出层
)

# 定义损失函数和优化器
criterion = nn.MSELoss()
optimizer = optim.SGD(model.parameters(), lr=0.01)

# 前向传播
inputs = torch.randn(32, 10)  # 32个样本,每个样本10个特征
outputs = model(inputs)
targets = torch.randn(32, 1)  # 目标值

# 计算损失
loss = criterion(outputs, targets)

# 反向传播(自动求导)
optimizer.zero_grad()  # 清零梯度
loss.backward()        # 计算梯度

# 更新参数
optimizer.step()       # 根据梯度更新参数

2. 高阶导数计算

自动求导可嵌套使用,计算高阶导数(如 Hessian 矩阵):
x = torch.tensor(2.0, requires_grad=True)
y = x**3

# 计算一阶导数
grad, = torch.autograd.grad(y, x, create_graph=True)  # create_graph=True允许继续求导
print(f"dy/dx = {grad}")  # 输出: 12.0 (因为 dy/dx = 3x^2 = 3*2^2 = 12)

# 计算二阶导数
hessian, = torch.autograd.grad(grad, x)
print(f"d²y/dx² = {hessian}")  # 输出: 12.0 (因为 d²y/dx² = 6x = 6*2 = 12)

六、注意事项

  1. 计算图的构建与释放
    • 当 requires_grad=True 的张量参与运算时,PyTorch 会动态构建计算图。
    • 调用 backward() 后,默认会释放计算图(节省内存),若需多次反向传播,需设置 retain_graph=True
  2. 梯度累积
    • 多次调用 backward() 会将梯度累积到 .grad 中,需在每次更新前调用 optimizer.zero_grad() 清零梯度。
  3. 性能优化
    • 在推理阶段(无需求导),可使用 with torch.no_grad(): 上下文管理器禁用自动求导,节省内存和计算资源。

总结

自动求导是深度学习框架的核心技术,通过跟踪计算路径并应用链式法则,高效且精确地计算导数。其中,反向模式(即反向传播)特别适合神经网络训练,能在参数众多的情况下快速计算梯度。理解自动求导机制有助于更灵活地使用深度学习框架,优化模型训练过程。
posted @ 2025-07-11 14:25  姚春辉  阅读(35)  评论(0)    收藏  举报