Python 3.x Pytorch autograd.grad如何写入多个输出的参数?
在torch.autograd.grad的中,说明了对于参数 参数: 输出(张量序列)–微分函数的输出 输入(张量序列)–输入w.r.t。 它将返回梯度(而不是累积到.grad) 我尝试以下方法:Python 3.x Pytorch autograd.grad如何写入多个输出的参数?,python-3.x,deep-learning,pytorch,Python 3.x,Deep Learning,Pytorch,在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
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另一系列张量。输入参数的正确方法是什么?给你
在您给出的示例中:
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
方法的输出参数,如上所述,torch.autograd.grad
计算并返回输出与输入的梯度之和。由于c
和d
不是标量值,因此需要grad\u输出
导入火炬
a=火炬.rand(2,需要_grad=True)
b=火炬.兰德(2,需要_grad=True)
A.
#张量([0.2308,0.2388],需要_grad=True)
B
#张量([0.6314,0.7867],需要_grad=True)
c=a*a+b*b
d=2*a+4*b
torch.autograd.grad([c,d],输入=[a,b],grad_输出=[torch.Tensor([1,1.]),torch.Tensor([1,1.]))
#(张量([2.4616,2.4776]),张量([5.2628,5.5734]))
说明:
dc/da=2*a=[0.2308*2,0.2388*2]
dd/da=[2,2.]
因此,第一个输出是dc/da*grad_输出[0]+dd/da*grad_输出[1]=[2.4616,2.4776]
。第二次输出的计算相同
如果您只想获得c
和d
w.r.t.输入的梯度,您可能可以这样做:
a=torch.rand(2,需要_grad=True)
b=火炬.兰德(2,需要_grad=True)
A.
#张量([0.9566,0.6066],需要_grad=True)
B
#张量([0.5248,0.4833],需要_grad=True)
c=a*a+b*b
d=2*a+4*b
[c,d]中t的[torch.autograd.grad(t,输入=[a,b],grad_输出=[torch.Tensor([1,1.])]
#[(张量([1.9133,1.2132]),张量([1.0496,0.9666]),
#(张量([2,2.]),张量([4,4.])]
所以输出只能是标量还是标量列表?我们能不能得到向量对向量的导数(海森矩阵)?是的,这就是我能找到的。即使在典型的神经网络中,在反向传播之前,我们总是对所有小批量样本的损失求和或平均。这是我能找到的唯一一个关于autograd.grad
多变量的例子。但是,我认为第一个输出是通过(dc/da)*grad_outputs[0]+(dd/da)*grad_outputs[1]=[2.4616,2.4776]
计算的。