论文
[1].CSC321 Lecture 10: Automatic Differentiation
[2].Automatic Differentiation in Machine Learning:a Survey
关键点总结:
-
雅可比矩阵:对于多变量函数 y ⃗ = f ( x ⃗ ) \vec{y} = f(\vec{x}) y=f(x),其梯度矩阵(即雅可比矩阵) J J J 的每个元素表示为:
J i j = ∂ y i ∂ x j J_{ij} = \frac{\partial y_i}{\partial x_j} Jij=∂xj∂yi -
链式法则:在计算复合函数的梯度时,通过链式法则可以将中间变量的梯度与最终输出的梯度结合起来。例如,若 l = g ( y ⃗ ) l = g(\vec{y}) l=g(y) 是标量函数,其梯度 v v v 为:
v = ( ∂ l ∂ y 1 , ⋯ , ∂ l ∂ y m ) v = \left(\frac{\partial l}{\partial y_1}, \cdots, \frac{\partial l}{\partial y_m}\right) v=(∂y1∂l,⋯,∂ym∂l)
则 l l l 关于 x ⃗ \vec{x} x 的梯度可以通过计算 v v v 与 J J J 的乘积得到:
v J = ( ∂ l ∂ x 1 , ⋯ , ∂ l ∂ x n ) v J = \left(\frac{\partial l}{\partial x_1}, \cdots, \frac{\partial l}{\partial x_n}\right) vJ=(∂x1∂l,⋯,∂xn∂l) -
梯度累加:在 PyTorch 中,梯度在反向传播过程中是累加的。每次调用
.backward()
方法时,计算的梯度会累加到张量的.grad
属性中。因此,为了避免梯度累积导致计算错误,通常需要在每次反向传播之前手动将梯度清零,常用的方法是使用optimizer.zero_grad()
或者tensor.grad.zero_()
。
示例代码:
import torch
# 定义一个简单的多变量函数
x = torch.tensor([1.0, 2.0, 3.0], requires_grad=True)
y = torch.cat([x ** 2, x ** 3], dim=0)
# 定义一个标量函数
l = y.sum()
# 计算梯度
l.backward()
# 查看梯度
print(x.grad)
# 梯度清零
x.grad.zero_()
总结:
torch.autograd
通过自动计算雅可比矩阵的乘积来实现反向传播。- 每次反向传播后,梯度会累加,因此需要手动清零以避免梯度累积问题。
- 这种方法使得深度学习模型的训练过程更加高效和简洁。