【问题标题】:Calculating gradient from network output in PyTorch gives error从 PyTorch 中的网络输出计算梯度会出错
【发布时间】:2021-04-01 05:04:30
【问题描述】:

我正在尝试使用我的网络输出手动计算梯度,然后我将在损失函数中使用它。我设法获得了一个在 keras 中工作的示例,但将其转换为 PyTorch 被证明更加困难

我有一个这样的模型:

class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.fc1 = nn.Linear(1, 50)  
        self.fc2 = nn.Linear(50, 10)
        self.fc3 = nn.Linear(10, 1)

    def forward(self, x):
        x = F.sigmoid(self.fc1(x))
        x = F.sigmoid(self.fc2(x))
        x = self.fc3(x)
        return x

还有一些数据:

x = torch.unsqueeze(torch.linspace(-1, 1, 101), dim=1)
x = Variable(x)

然后我可以尝试找到类似的渐变:

output = net(x)
grad = torch.autograd.grad(outputs=output, inputs=x, retain_graph=True)[0]

我希望能够找到每个点的梯度,然后执行以下操作:

err_sqr = (grad - x)**2
loss = torch.mean(err_sqr)**2

但是,目前如果我尝试这样做,我会收到错误:

grad can be implicitly created only for scalar outputs

我已经尝试改变我的网络输出的形状来解决这个问题,但是如果我把它改变得太多,它就会说它不是图表的一部分。我可以通过允许来摆脱这个错误,但它说我的渐变是None。我已经设法让它在 keras 中工作,所以我相信它在这里也是可能的,我只需要帮助!

我的问题是:

  • 有没有办法“修复”我必须允许我计算梯度的内容

【问题讨论】:

    标签: python pytorch loss-function


    【解决方案1】:

    PyTorch 期望 grad 调用中的上游梯度。对于通常的(标量)损失函数,上游梯度被隐式假设为1

    您可以通过传递ones 作为上游梯度来做类似的事情:

    grad = torch.autograd.grad(outputs=output, inputs=x, grad_outputs=torch.ones_like(output), retain_graph=True)[0]
    

    【讨论】:

    • 谢谢,在我的数据 x 中设置 requires_grad=True 后,这解决了我的问题。它现在不会抛出错误,但也不会收敛到正确的结果。损失函数中的 autograd 函数会干扰我的优化器吗?如果这是一个问题,有没有办法阻止两人说话?
    • @Andrew 我不确定你想要做什么——让net(x) 的渐变与x 本身相同?为什么这有意义?无论如何,这似乎是另一个问题的主题。
    • 您可以将其用作求解方程的方法。是的,我再问一个问题,再次感谢您的帮助!
    猜你喜欢
    • 2019-01-10
    • 2021-07-07
    • 2020-01-24
    • 2019-09-24
    • 1970-01-01
    • 2017-08-14
    • 2020-04-03
    • 2018-10-14
    • 2020-05-12
    相关资源
    最近更新 更多