该函数实现自动求导梯度,函数如下:
torch.autograd.backward(tensors, grad_tensors=None, retain_graph=False, create_graph=False, inputs=None)
参数介绍:
import torch
# 定义张量并启用梯度计算
x = torch.tensor(2.0, requires_grad=True)
y = x ** 2 # y = x^2
# 使用 torch.autograd.backward() 触发反向传播
torch.autograd.backward(y)
# 查看梯度
print(x.grad) # 输出:4.0 (dy/dx = 2x, 当 x=2 时,dy/dx=4)
x = torch.tensor([1.0, 2.0, 3.0], requires_grad=True)
y = x ** 2 # y = [x1^2, x2^2, x3^2]
# 指定 grad_tensors 权重
grad_tensors = torch.tensor([1.0, 1.0, 1.0]) # 权重
torch.autograd.backward(y, grad_tensors=grad_tensors)
# 查看梯度
print(x.grad) # 输出:[2.0, 4.0, 6.0] (dy/dx = 2x)
如果需要多次调用反向传播,可以设置 retain_graph=True。
x = torch.tensor(2.0, requires_grad=True)
y = x ** 3 # y = x^3
# 第一次反向传播
torch.autograd.backward(y, retain_graph=True)
print(x.grad) # 输出:12.0 (dy/dx = 3x^2, 当 x=2 时,dy/dx=12)
# 第二次反向传播
torch.autograd.backward(y, retain_graph=True)
print(x.grad) # 输出:24.0 (梯度累积,12.0 + 12.0)
通过 inputs 参数,可以只计算指定张量的梯度,而忽略其他张量。
x = torch.tensor(2.0, requires_grad=True)
z = torch.tensor(3.0, requires_grad=True)
y = x ** 2 + z ** 3 # y = x^2 + z^3
# 只计算 x 的梯度
torch.autograd.backward(y, inputs=[x])
print(x.grad) # 输出:4.0 (dy/dx = 2x)
print(z.grad) # 输出:None (未计算 z 的梯度)
通过设置 create_graph=True,可以构建新的计算图,用于计算高阶梯度。
x = torch.tensor(2.0, requires_grad=True)
y = x ** 3 # y = x^3
# 第一次反向传播,创建新的计算图
torch.autograd.backward(y, create_graph=True)
print(x.grad) # 输出:12.0 (dy/dx = 3x^2)
# 计算二阶梯度
x_grad = x.grad
x_grad.backward()
print(x.grad) # 输出:18.0 (d^2y/dx^2 = 6x)
灵活性:
梯度权重:
输入控制:
torch.autograd.grad() 是 PyTorch 中用于计算张量梯度的函数,与 backward() 不同的是,它不会更新张量的 .grad 属性,而是直接返回计算的梯度值。它适用于需要手动获取梯度值而不修改计算图中张量的 .grad 属性的场景。
torch.autograd.grad(
outputs,
inputs,
grad_outputs=None,
retain_graph=False,
create_graph=False,
only_inputs=True,
allow_unused=False
)
参数介绍:
返回值:
import torch
# 定义张量并启用梯度计算
x = torch.tensor(2.0, requires_grad=True)
y = x ** 2 # y = x^2
# 使用 torch.autograd.grad() 计算梯度
grad = torch.autograd.grad(y, x)
print(grad) # 输出:(4.0,) (dy/dx = 2x, 当 x=2 时,dy/dx=4)
当目标张量是非标量时,需要提供 grad_outputs 参数:
x = torch.tensor([1.0, 2.0, 3.0], requires_grad=True)
y = x ** 2 # y = [x1^2, x2^2, x3^2]
# 指定 grad_outputs 权重
grad_outputs = torch.tensor([1.0, 1.0, 1.0]) # 权重
grad = torch.autograd.grad(y, x, grad_outputs=grad_outputs)
print(grad) # 输出:(tensor([2.0, 4.0, 6.0]),) (dy/dx = 2x)
通过设置 create_graph=True,可以计算高阶梯度:
x = torch.tensor(2.0, requires_grad=True)
y = x ** 3 # y = x^3
# 第一次计算梯度
grad = torch.autograd.grad(y, x, create_graph=True)
print(grad) # 输出:(12.0,) (dy/dx = 3x^2)
# 计算二阶梯度
grad2 = torch.autograd.grad(grad[0], x)
print(grad2) # 输出:(6.0,) (d^2y/dx^2 = 6x)
可以对多个输入和输出同时计算梯度:
x = torch.tensor(2.0, requires_grad=True)
z = torch.tensor(3.0, requires_grad=True)
y1 = x ** 2 + z ** 3 # y1 = x^2 + z^3
y2 = x * z # y2 = x * z
# 对多个输入计算梯度
grads = torch.autograd.grad([y1, y2], [x, z], grad_outputs=[torch.tensor(1.0), torch.tensor(1.0)])
print(grads) # 输出:(7.0, 11.0) (dy1/dx + dy2/dx, dy1/dz + dy2/dz)
如果某些输入张量未被目标张量使用,需设置 allow_unused=True:
x = torch.tensor(2.0, requires_grad=True)
z = torch.tensor(3.0, requires_grad=True)
y = x ** 2 # y = x^2
# z 未被 y 使用
grad = torch.autograd.grad(y, [x, z], allow_unused=True)
print(grad) # 输出:(4.0, None) (dy/dx = 4, z 未被使用,梯度为 None)
如果需要多次计算梯度,可以设置 retain_graph=True:
x = torch.tensor(2.0, requires_grad=True)
y = x ** 3 # y = x^3
# 第一次计算梯度
grad1 = torch.autograd.grad(y, x, retain_graph=True)
print(grad1) # 输出:(12.0,)
# 第二次计算梯度
grad2 = torch.autograd.grad(y, x)
print(grad2) # 输出:(12.0,)