在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
我想获得一个张量列表的梯度,w.r.t 另一个张量列表。输入参数的正确方法是什么?
正如 torch.autograd.grad 所提到的,torch.autograd.grad
计算并返回输入的输出梯度总和。由于c
和d
不是标量值,因此需要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]
.第二个输出的计算相同。
如果你只是想得到c
的梯度并d
输入,也许你可以这样做:
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 个元素的向量,因此您无法一次执行自动评分操作。
通常
loss = torch.sum(a + b)
torch.autograd.grad([loss], [a, b])
这将返回包含一个元素的损失张量的正确梯度值。 您可以将多个标量张量传递给torch.autograd.grad
方法的输出参数