我想计算一个网中两个张量之间的梯度。输入X张量(批量大小x m)通过一组卷积层发送,这些卷积层返回并输出Y张量(批量大小x n)。
我正在创造一个新的损失,我想知道Y w.r.t的梯度。X. tensorflow中的内容如下所示:
tf.gradients(ys=Y, xs=X)
不幸的是,我一直在用torch.autograd.grad()做测试,但我不知道该怎么做。我得到类似这样的错误:“RunTimeerror: grad can be implicitly created only for scalar outputs”。
如果我想知道Y w.r.t.的梯度,torch.autograd.grad()中的输入应该是什么?X?
发布于 2019-02-19 08:46:53
让我们从简单的工作示例开始,使用简单的损失函数和正则向后。我们将构建简短的计算图,并在其上进行一些梯度计算。
代码:
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可以隐式创建仅用于标量输出“。正如您所注意到的,前面示例中的loss是一个标量。默认情况下,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))即可。
https://stackoverflow.com/questions/54754153
复制相似问题