You are getting None
because the gradient is only stored on the .grad
property for leaf tensors. Those are tensors that don't have parents in the computational graph.
You can check whether a tensor is a leaf or not with 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.])
The tensor you printed shows grad_fn=<ReluBackward0>
indicating it's the result of a ReLU layer, and therefore not a leaf tensor.
Here is an example of a non-leaf tensor:
>>> x = torch.FloatTensor([1,2,3])
>>> x.requires_grad=True
>>> z = x.sum()
>>> z.backward()
>>> z.is_leaf
False
>>> z.grad
None
Notice that z
will show as tensor(6., grad_fn=<SumBackward0>)
.
Actually accessing .grad
will give a warning:
UserWarning: The .grad attribute of a Tensor that is not a leaf Tensor is being accessed. Its .grad attribute won't be populated during autograd.backward(). If you indeed want the gradient for a non-leaf Tensor, use .retain_grad() on the non-leaf Tensor. If you access the non-leaf Tensor by mistake, make sure you access the leaf Tensor instead.
And if you want to access the gradient on non-leaf tensors, following the warning message:
>>> z.retain_grad()
>>> z = x.sum()
>>> z.retain_grad()
>>> z.backward()
>>> z.is_leaf
False
>>> z.grad
tensor(1.)
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…