Only leaves get .grad — by default
Autograd makes a strong distinction between two kinds of tensors:
- Leaf tensors — created by you (or by
nn.Parameter). They are inputs to the graph, not outputs of any op. Their.gradis the gradient of the loss with respect to them. - Intermediate tensors — outputs of operations. PyTorch's default behavior is to NOT store gradients on them, because storing intermediates everywhere would balloon memory.
If you're debugging and want to see the gradient on an intermediate (the output of layer 3, say), you have two options:
x.retain_grad()— call this on the intermediate before backward, and PyTorch will store its gradient too.x.register_hook(callback)— register a function that gets called with the gradient as it flows through. Doesn't store anything; lets you log or modify.
In a normal training loop you don't touch either. They're both for the moment when you go "huh, why is this layer not learning" and you reach for diagnostics.