如何将 autograd 用于独立于 PyTorch 中的反向传播的单独函数?

How do I use autograd for a separate function independent of backpropagate in PyTorch?

我有两个变量,xtheta。我试图仅将关于 theta 的损失降至最低,但作为损失函数的一部分,我需要关于 x 的不同函数 (f) 的导数。这个导数本身与最小化无关,只与它的输出有关。但是,在 PyTorch 中实现此功能时出现运行时错误。

一个最小的例子如下:

# minimal example of two different autograds
import torch

from torch.autograd.functional import jacobian
def f(theta, x):
    return torch.sum(theta * x ** 2)

def df(theta, x):
    J = jacobian(lambda x: f(theta, x), x)
    return J

# example evaluations of the autograd gradient
x = torch.tensor([1., 2.])
theta = torch.tensor([1., 1.], requires_grad = True)

# derivative should be 2*theta*x (same as an analytical)
with torch.no_grad():
    print(df(theta, x))
    print(2*theta*x)

tensor([2., 4.])

tensor([2., 4.])

# define some arbitrary loss as a fn of theta
loss = torch.sum(df(theta, x)**2)
loss.backward()

给出如下错误

RuntimeError: element 0 of tensors does not require grad and does not have a grad_fn

如果我提供解析导数 (2*theta*x),它工作正常:

loss = torch.sum((2*theta*x)**2)
loss.backward()

有没有办法在 PyTorch 中做到这一点?或者我在某些方面受到限制?

如果有人需要更多详细信息,请告诉我。

PS

我想这个解决方案类似于 JAX 进行 autograd 的方式,因为这是我更熟悉的。我的意思是,在 JAX 中,我相信您会这样做:

from jax import grad
df = grad(lambda x: f(theta, x))

然后 df 只是一个可以在任何时候调用的函数。但是 PyTorch 是一样的吗?或者 .backward() 中是否存在导致此错误的冲突?

除非您明确要求,否则 PyTorch 的 jacobian 不会创建计算图

J = jacobian(lambda x: f(theta, x), x, create_graph=True)

.. 带有 create_graph 参数。

文档说的很清楚

create_graph (bool, optional) – If True, the Jacobian will be computed in a differentiable manner