自动求导

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)
关键步骤解析:
- 创建可求导张量:通过
requires_grad=True标记需要求导的变量。 - 构建计算图:执行运算(如
z = x**2 + y**3)时,PyTorch 会自动记录计算路径。 - 反向传播:调用
z.backward()触发自动求导,从z开始反向计算梯度。 - 获取梯度:通过
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)
六、注意事项
-
计算图的构建与释放:
- 当
requires_grad=True的张量参与运算时,PyTorch 会动态构建计算图。 - 调用
backward()后,默认会释放计算图(节省内存),若需多次反向传播,需设置retain_graph=True。
- 当
-
梯度累积:
- 多次调用
backward()会将梯度累积到.grad中,需在每次更新前调用optimizer.zero_grad()清零梯度。
- 多次调用
-
性能优化:
- 在推理阶段(无需求导),可使用
with torch.no_grad():上下文管理器禁用自动求导,节省内存和计算资源。
- 在推理阶段(无需求导),可使用
总结
自动求导是深度学习框架的核心技术,通过跟踪计算路径并应用链式法则,高效且精确地计算导数。其中,反向模式(即反向传播)特别适合神经网络训练,能在参数众多的情况下快速计算梯度。理解自动求导机制有助于更灵活地使用深度学习框架,优化模型训练过程。

浙公网安备 33010602011771号