我很困惑...
我的模型输出:
tensor([[0.0000,0.1537],...],grad_fn=<ReluBackward0>)
如果我使用 print(output.grad)
它会给我 None
但即使在梯度计算之后
loss.backward()
我得到相同的结果,同样是 None
...
即使
with torch.set_grad_enabled(True):
补充,还是一样。
我现在尝试了多个模型变体,始终相同。
我用我的模型取得了很好的结果,似乎没有问题,现在我看到了这一点,我不确定是否可能存在我目前没有认识到的重大缺陷。 但是我的模型正在学习,它有所改进,所以我想它必须这样做?
为什么我得到 None 而不是实际值?
答案 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.)