pytorch中用于Tensor的Autograd.grad()

时间:2019-02-18 19:32:27

标签: pytorch autograd

我想计算网络中两个张量之间的梯度。输入X张量(批大小x m)通过一组卷积层发送,这些卷积层使我返回并输出Y张量(批大小x n)。

我正在产生新的损失,我想知道Y w.r.t.的梯度。 X.张量流中的内容将是:

tf.gradients(ys = Y,xs = X)

不幸的是,我一直在使用torch.autograd.grad()进行测试,但我不知道该怎么做。我收到如下错误:“ RunTimeerror:只能为标量输出隐式创建grad。”

如果我想知道Y w.r.t.的梯度,torch.autograd.grad()中的输入应该是什么。 X?

1 个答案:

答案 0 :(得分:2)

让我们从简单的工作示例开始,该示例具有简单的损失函数并定期向后移动。我们将构建简短的计算图并对其进行一些grad计算。

代码:

import torch
from torch.autograd import grad
import torch.nn as nn


# Create some dummy data.
x = torch.ones(2, 2, requires_grad=True)
gt = torch.ones_like(x) * 16 - 0.5  # "ground-truths" 

# We will use MSELoss as an example.
loss_fn = nn.MSELoss()

# Do some computations.
v = x + 2
y = v ** 2

# Compute loss.
loss = loss_fn(y, gt)

print(f'Loss: {loss}')

# Now compute gradients:
d_loss_dx = grad(outputs=loss, inputs=x)
print(f'dloss/dx:\n {d_loss_dx}')

输出:

Loss: 42.25
dloss/dx:
(tensor([[-19.5000, -19.5000], [-19.5000, -19.5000]]),)

好的,这行得通!现在,让我们尝试重现错误“只能为标量输出隐式创建grad”。如您所见,上一个示例中的损失是一个标量。默认情况下,backward()grad()处理单个标量值:loss.backward(torch.tensor(1.))。如果尝试通过张量传递更多的值,则会出现错误。

代码:

v = x + 2
y = v ** 2

try:
    dy_hat_dx = grad(outputs=y, inputs=x)
except RuntimeError as err:
    print(err)

输出:

grad can be implicitly created only for scalar outputs

因此,在使用grad()时,您需要指定grad_outputs参数,如下所示:

代码:

v = x + 2
y = v ** 2

dy_dx = grad(outputs=y, inputs=x, grad_outputs=torch.ones_like(y))
print(f'dy/dx:\n {dy_dx}')

dv_dx = grad(outputs=v, inputs=x, grad_outputs=torch.ones_like(v))
print(f'dv/dx:\n {dv_dx}')

输出:

dy/dx:
(tensor([[6., 6.],[6., 6.]]),)

dv/dx:
(tensor([[1., 1.], [1., 1.]]),)

注意::如果您使用的是backward(),只需执行y.backward(torch.ones_like(y))