pytorch 中张量的 Autograd.grad()

Posted

技术标签:

【中文标题】pytorch 中张量的 Autograd.grad()【英文标题】:Autograd.grad() for Tensor in pytorch 【发布时间】:2019-07-12 05:49:48 【问题描述】:

我想计算网络中两个张量之间的梯度。输入 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?

【问题讨论】:

Pytorch. Can autograd be used when the final tensor has more than a single value in it?的可能重复 【参考方案1】:

让我们从简单的工作示例开始,该示例具有普通的损失函数和常规的后向。我们将构建一个简短的计算图并对其进行一些梯度计算。

代码:

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 can be implicitly created only for scalar outputs”。如您所见,前面示例中的损失是一个标量。 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))

【讨论】:

不错的答案,但grad_outputs 的一般含义是什么?在某些情况下我们需要使用 grad_outputs=torch.ones_like(outputs) 以外的东西吗?如果解决方案始终相同,为什么grad 不简单地假设grad_outputs=torch.ones_like(outputs) 而不是抛出错误?

以上是关于pytorch 中张量的 Autograd.grad()的主要内容,如果未能解决你的问题,请参考以下文章

pytorch torch类

在 PyTorch 中,是啥让张量具有非连续内存?

在pytorch中连接两个不同形状的火炬张量

PyTorch从入门到精通100讲-PyTorch张量从概念到应用

Pytorch基础-张量基本操作

pytorch 中张量的 Autograd.grad()