You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在PyTorch中获取向量输入函数的Jacobian及正确使用torch.autograd.grad

如何用torch.autograd.grad获取张量输出对输入的梯度/雅可比矩阵

问题背景

自定义的derivative函数仅在输出为标量或多个独立标量时能返回梯度之和,但当输出是张量时,无法得到完整的雅可比矩阵(输出每个分量对输入每个分量的梯度构成的矩阵)。

核心原因

torch.autograd.grad默认会将所有输出元素的梯度求和后返回,而非保留每个输出分量对应的梯度信息。要获取完整雅可比,需要针对每个输出分量单独计算梯度,或利用grad_outputs参数批量处理。


方法1:循环计算每个输出分量的梯度

通过遍历输出张量的每个元素,单独计算其对输入的梯度,最后堆叠成雅可比矩阵。注意需要设置retain_graph=True以保留计算图,避免后续求导失败。

示例代码:

import torch

def f(x):
    # 定义一个输出为3维张量的函数
    return torch.stack([x[0]**2, x[0]+x[1], x[1]*x[2]])

def compute_jacobian(y, x):
    jacobian_list = []
    # 遍历每个输出分量
    for i in range(y.shape[0]):
        # 单独计算第i个输出分量对输入x的梯度
        grad = torch.autograd.grad(y[i], x, retain_graph=True)[0]
        jacobian_list.append(grad)
    # 堆叠为(output_dim, input_dim)形状的雅可比矩阵
    return torch.stack(jacobian_list)

# 测试
x = torch.tensor([1.0, 2.0, 3.0], requires_grad=True)
y = f(x)
jacobian = compute_jacobian(y, x)
print(jacobian)

输出结果:

tensor([[2., 0., 0.],
        [1., 1., 0.],
        [0., 3., 2.]])

方法2:利用grad_outputs参数批量计算

通过设置grad_outputs为单位矩阵,让torch.autograd.grad一次性计算所有输出分量的梯度,避免循环。单位矩阵的每个行对应一个输出分量的权重,确保每个分量的梯度被单独保留。

示例代码:

def compute_jacobian_batch(y, x):
    # 创建与输出y同形状的单位矩阵
    grad_outputs = torch.eye(y.shape[0], device=y.device, dtype=y.dtype)
    # 计算梯度,返回结果为(input_dim, output_dim),转置后得到标准雅可比矩阵
    jacobian = torch.autograd.grad(y, x, grad_outputs=grad_outputs, retain_graph=True)[0].T
    return jacobian

# 测试
x = torch.tensor([1.0, 2.0, 3.0], requires_grad=True)
y = f(x)
jacobian = compute_jacobian_batch(y, x)
print(jacobian)

输出结果与方法1完全一致。


方法3:使用torch.func.jacfwd(PyTorch 2.0+)

PyTorch 2.0及以上版本提供了torch.func.jacfwd(前向模式自动微分),可以直接计算函数的雅可比矩阵,无需手动处理计算图或循环,代码更简洁高效。

示例代码:

from torch.func import jacfwd

def f(x):
    return torch.stack([x[0]**2, x[0]+x[1], x[1]*x[2]])

# 测试
x = torch.tensor([1.0, 2.0, 3.0])
jacobian = jacfwd(f)(x)
print(jacobian)

输出结果同样与前两种方法一致。


补充:原函数的行为说明

当输出y是张量时,直接调用torch.autograd.grad(y, x)会返回所有输出分量梯度的和。例如上述测试中,原derivative函数会返回tensor([3., 4., 2.]),这是2x0 +1 +0、0+1 +x2、0+0 +x1的结果,并非完整雅可比矩阵。

内容的提问来源于stack exchange,提问作者Rias Gremory

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 14:10:26