提问者:小点点

Pytorch autograd. grad如何编写多个输出的参数?


torch. autograd.grad的留档中说明,对于参数,

参数:

输出(张量序列)-差异化函数的输出。

输入(张量序列)-输入w. r.t.梯度将被返回(并且不会累积到.grad中)。

我尝试以下操作:

a = torch.rand(2, requires_grad=True)
b = torch.rand(2, requires_grad=True)
c = a+b
d = a-b

torch.autograd.grad([c, d], [a, b]) #ValueError: only one element tensors can be converted to Python scalars
torch.autograd.grad(torch.tensor([c, d]), torch.tensor([a, b])) #RuntimeError: grad can be implicitly created only for scalar outputs

我想在另一个张量列表中获取张量列表的梯度。提供参数的正确方法是什么?


共2个答案

匿名用户

正如torch. autograd.grad提到的,torch.autograd.grad计算并返回输出与输入的梯度之和。由于您的cd不是标量值,因此需要grad_outputs

import torch

a = torch.rand(2,requires_grad=True)
b = torch.rand(2, requires_grad=True)

a
# tensor([0.2308, 0.2388], requires_grad=True)

b
# tensor([0.6314, 0.7867], requires_grad=True)

c = a*a + b*b
d = 2*a+4*b

torch.autograd.grad([c,d], inputs=[a,b], grad_outputs=[torch.Tensor([1.,1.]), torch.Tensor([1.,1.])])
# (tensor([2.4616, 2.4776]), tensor([5.2628, 5.5734]))

解释:dc/da=2*a=[0.2308*2,0.2388*2]dd/da=[2.,2.]所以第一个输出是dc/da*grad_outputs[0]dd/da*grad_outputs[1]=[2.4616,2.4776]。第二个输出的计算相同。

如果您只想获取cdw. r.t的渐变。输入,也许你可以这样做:

a = torch.rand(2,requires_grad=True)
b = torch.rand(2, requires_grad=True)

a
# tensor([0.9566, 0.6066], requires_grad=True)
b
# tensor([0.5248, 0.4833], requires_grad=True)

c = a*a + b*b
d = 2*a+4*b

[torch.autograd.grad(t, inputs=[a,b], grad_outputs=[torch.Tensor([1.,1.])]) for t in [c,d]]
# [(tensor([1.9133, 1.2132]), tensor([1.0496, 0.9666])),
# (tensor([2., 2.]), tensor([4., 4.]))]

匿名用户

干得好在你举的例子中:

a = torch.rand(2, requires_grad=True)
b = torch.rand(2, requires_grad=True)
loss = a + b

由于损失是包含2个元素的向量,因此您不能立即执行autograd操作。

通常,

loss = torch.sum(a + b)
torch.autograd.grad([loss], [a, b])

这将返回包含一个元素的损失张量的正确梯度值。您可以将多个标量张量传递给torch. autograd.grad方法的输出参数