代码之家  ›  专栏  ›  技术社区  ›  aerin

Grad_输出为torch.automated.grad(交叉熵损失)

  •  1
  • aerin  · 技术社区  · 7 年前

    我在努力 d(loss)/d(input) . 我知道我有两个选择。

    第一选择:

        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_outputs 在第二个选项中?

    我把 d(CE)/d(y_hat) ?由于pytorch交叉熵包含softmax,这需要我使用kronecker delta预先计算softmax导数。

    还是我把 d(CE)/d(CE) 火炬是什么样的?

    概念上的答案是好的。

    1 回复  |  直到 7 年前
        1
  •  1
  •   aerin    7 年前

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

    我们将使用这个设置

    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()
    

    第一选择

    loss = criterion(net(x), labels)
    loss.backward(retain_graph=True)
    dloss_dx = x.grad
    

    请注意,没有将任何选项传递给渐变,因为损失是一个标量。如果将损失计算为向量,则必须传递

    第二选择

    dloss_dx2 = torch.autograd.grad(loss, x)
    

    这将返回一个元组,您可以使用第一个元素作为x的渐变。

    注意 torch.autograd.grad 如果将多个输出作为元组传递,则返回dout/dx的和。但是由于损失是标量的,所以不需要通过 grad_outputs 默认情况下,它会认为它是一个。

    推荐文章