即使在 loss.backward() 之后 output.grad 也没有

时间:2021-01-03 16:40:38

标签: python machine-learning pytorch

我很困惑...

我的模型输出: tensor([[0.0000,0.1537],...],grad_fn=<ReluBackward0>)

如果我使用 print(output.grad) 它会给我 None 但即使在梯度计算之后 loss.backward() 我得到相同的结果,同样是 None...

即使 with torch.set_grad_enabled(True): 补充,还是一样。

我现在尝试了多个模型变体,始终相同。

我用我的模型取得了很好的结果,似乎没有问题,现在我看到了这一点,我不确定是否可能存在我目前没有认识到的重大缺陷。 但是我的模型正在学习,它有所改进,所以我想它必须这样做?

为什么我得到 None 而不是实际值?

1 个答案:

答案 0 :(得分:3)

您得到 None 是因为梯度仅存储在叶张量的 .grad 属性中。这些是在计算图中没有父项的张量。

您可以使用 is_leaf 检查张量是否为叶子:

>>> x = torch.FloatTensor([1,2,3])
>>> x.requires_grad = True
>>> x.sum().backward() # backward pass

>>> x.is_leaf
True
>>> x.grad
tensor([1., 1., 1.])

您打印的张量显示 grad_fn=<ReluBackward0> 表示它是 ReLU 层的结果,因此不是叶张量。

这是一个非叶张量的例子:

>>> x = torch.FloatTensor([1,2,3])
>>> x.requires_grad=True
>>> z = x.sum()
>>> z.backward()

>>> z.is_leaf
False
>>> z.grad
None

请注意,z 将显示为 tensor(6., grad_fn=<SumBackward0>)


实际访问.grad会给出警告:

<块引用>

UserWarning:正在访问不是叶张量的张量的 .grad 属性。在 autograd.backward() 期间不会填充它的 .grad 属性。如果您确实想要非叶张量的梯度,请在非叶张量上使用 .retain_grad() 。如果您错误地访问了非叶张量,请确保您改为访问叶张量。

如果您想访问非叶张量的梯度,请遵循警告消息:

>>> z.retain_grad()
>>> z = x.sum()
>>> z.retain_grad()
>>> z.backward()

>>> z.is_leaf
False
>>> z.grad
tensor(1.)