Consider a layer that has an input i, and output o and some weights w. And suppose you have a loss function L.
If you want to minimize your loss by gradient descent, you want to obtain dL/dw and then update w as w = w - lr * dL/dw.
This dL/dw is computed during the backward pass and is stored in the Variable's .grad field.
That means that [x.grad.data for x in network.parameters()] will give you the list of all the dL/dw associated to each w in your network. If you want to do gradient descent by hand you can do:
for w in network.parameters():
    w.data -= lr * w.grad.data

Which is more or less what is done by sgd here 65.
If you use a hook, you will get dL/di and dL/do. These are just intermediary computations. They are used to compute the dL/dw during the backward pass using the chain rule as we write for our layer: dL/dw = dL/do * do/dw where dL/do is given by the chain rule applied to the next layer, and do/dw is written by hand for each layer.
The gradients passed to these hook does not correspond to any weight that you are trying to learn.
Does that make it clearer?
You can also take a look at the examples 118 to see how the optimiser should used in practice.