Pytorch torch.autograd.grad中的grad_输出(无交叉熵)

Pytorch torch.autograd.grad中的grad_输出(无交叉熵),pytorch,autograd,Pytorch,Autograd,我正在尝试获取d(丢失)/d(输入)。我知道我有两个选择 第一种选择: loss.backward() dlossdx = x.grad.data 第二种选择: # criterion = nn.CrossEntropyLoss(reduce=False) # loss = criterion(y_hat, labels) # No need to call backward. dlossdx = torch.autograd.gra

我正在尝试获取
d(丢失)/d(输入)
。我知道我有两个选择

第一种选择:

    loss.backward()
    dlossdx = x.grad.data
第二种选择:

    # criterion = nn.CrossEntropyLoss(reduce=False)
    # loss = criterion(y_hat, labels)     
    # No need to call backward. 
    dlossdx = torch.autograd.grad(outputs = loss,
                                  inputs = x,
                                  grad_outputs = ? )
我的问题是:如果我使用交叉熵损失,我应该在第二个选项中传递什么作为
grad\u输出

我把
d(CE)/d(y_-hat)
放进去了吗?由于pytorch交叉熵包含softmax,这将需要我使用Kronecker delta预先计算softmax导数

或者我应该把
d(CE)/d(CE)
哪个是火炬手


概念上的答案很好。

让我们试着了解这两个选项是如何工作的

我们将使用此设置

import torch 
import torch.nn as nn
import numpy as np 
x = torch.rand((64,10), requires_grad=True)
net = nn.Sequential(nn.Linear(10,10))
labels = torch.tensor(np.random.choice(10, size=64)).long()
criterion = nn.CrossEntropyLoss()
第一选择 请注意,您没有将任何选项传递给gradient,因为损失是一个标量。如果您将损失作为向量计算,则必须传递

第二种选择 这将返回一个元组,您可以使用第一个元素作为x的梯度


请注意,
torch.autograd.grad
如果将多个输出作为元组传递,则返回dout/dx之和。但是由于丢失是标量,所以不必通过<代码> GrordIsOuts< /Cord>。默认情况下,它将被认为是一个。
grad_输出
如果您关心高阶导数产品(例如,Hessian向量产品),则可能非常有用。对于标准渐变,大多数人通常不调用
autograd
方法。
loss = criterion(net(x), labels)
loss.backward(retain_graph=True)
dloss_dx = x.grad
dloss_dx2 = torch.autograd.grad(loss, x)