Hi,

grad_in[2] is the gradients for the bias as you saw.
The conv takes 3 inputs: (input, weights, bias). Since for the first layer, you don’t need gradients for the input, None is returned. For the second layer, gradients for the input are needed to compute the gradients of the first layer and so are computed.
Not sure what you mean here? what do you want to save exactly? If you want the gradients for weights or bias, you can recover them after the backward pass with the .grad attribute on them· If you want to gradient for the input, you can inp.register_hook(your_saving_function) that will be called with the gradient for that tensor when it’s computed.
If this is your goal, I would do that as a postprocessing step after the backward:

# Whenever you want to reset the history
for p in model.parameters():
  p.history = []

# Inside your training loop
loss.backward() # compute the .grad for all weights
with torch.no_grad(): # deactivate the autograd as you don't want to differentiate through these ops
  for p in model.parameters(): # You can do some filtering here (only conv weights) if you want here
    p.history.append(p.grad)
    new_grad = your_fn(p.history) # p.history[-1] is the last gradient
    p.grad.copy_(new_grad) # Use copy to make sure that .grad is still the same Tensor