从 PyTorch 中的网络输出计算梯度给出错误
Calculating gradient from network output in PyTorch gives error
我正在尝试使用我的网络输出手动计算梯度,然后我将在损失函数中使用它。我设法获得了一个在 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 中工作,所以我相信它在这里也有可能,我只需要一只手!
我的问题是:
- 有没有办法“修复”我必须允许我计算梯度的东西
PyTorch 期望在 grad
调用中有一个上游梯度。对于通常的(标量)损失函数,上游梯度被隐式假设为 1
.
你可以通过传递 ones
作为上游梯度来做类似的事情:
grad = torch.autograd.grad(outputs=output, inputs=x, grad_outputs=torch.ones_like(output), retain_graph=True)[0]
我正在尝试使用我的网络输出手动计算梯度,然后我将在损失函数中使用它。我设法获得了一个在 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 中工作,所以我相信它在这里也有可能,我只需要一只手!
我的问题是:
- 有没有办法“修复”我必须允许我计算梯度的东西
PyTorch 期望在 grad
调用中有一个上游梯度。对于通常的(标量)损失函数,上游梯度被隐式假设为 1
.
你可以通过传递 ones
作为上游梯度来做类似的事情:
grad = torch.autograd.grad(outputs=output, inputs=x, grad_outputs=torch.ones_like(output), retain_graph=True)[0]