Pytorch:从矩阵元素的总和反向传播到叶变量

Pytorch: backpropagating from sum of matrix elements to leaf variable

我试图更好地理解 pytorch 中的反向传播。我有一个代码片段成功地从输出 d 反向传播到叶变量 a,但是如果我添加重塑步骤,反向传播不再为输入提供梯度。

我知道 reshape 不合时宜,但我仍然不确定如何将其置于上下文中。

有什么想法吗?

谢谢。

#Works
a = torch.tensor([1.])
a.requires_grad = True
b = torch.tensor([1.])
c = torch.cat([a,b])
d = torch.sum(c)
d.backward()

print('a gradient is')
print(a.grad) #=> Tensor([1.])

#Doesn't work
a = torch.tensor([1.])
a.requires_grad = True
a = a.reshape(a.shape)
b = torch.tensor([1.])
c = torch.cat([a,b])
d = torch.sum(c)
d.backward()

print('a gradient is')
print(a.grad) #=> None

编辑:

这里有详细的解释("this isn't a bug per se, but it is definitely a source of confusion"):https://github.com/pytorch/pytorch/issues/19778

所以一个解决方案是特别要求保留 grad for now non-leaf a:

a = torch.tensor([1.])
a.requires_grad = True
a = a.reshape(a.shape)
a.retain_grad()
b = torch.tensor([1.])
c = torch.cat([a,b])
d = torch.sum(c)
d.backward()

旧答案:

如果在重塑后移动 a.requires_grad = True,它会起作用:

a = torch.tensor([1.])
a = a.reshape(a.shape)
a.requires_grad = True
b = torch.tensor([1.])
c = torch.cat([a,b])
d = torch.sum(c)
d.backward()

似乎是 PyTorch 中的一个错误,因为在此之后 a.requires_grad 仍然成立。

a = torch.tensor([1.])
a.requires_grad = True
a = a.reshape(a.shape)

这似乎与以下事实有关 a 在您的 "Doesn't work" 示例中不再是叶子,但在其他情况下仍然是叶子(打印 a.is_leaf 进行检查) .