A gradient tells you how a loss changes when a model’s parameters change. For a model with a weight and a bias, it is a vector containing two derivatives: one for the weight and one for the bias. Those values guide parameter updates toward lower loss. section 5.4.2 section 5.2
For a linear model and mean squared error, the chain rule combines how the loss changes with each prediction and how each prediction changes with a parameter. Summing across predictions gives the derivative for that parameter. Unlike checking the loss at nearby parameter values, this calculates the gradient at the current values. section 5.4.2
# In[14]:
def grad_fn(t_u, t_c, t_p, w, b):
dloss_dtp = dloss_fn(t_p, t_c)
dloss_dw = dloss_dtp * dmodel_dw(t_u, w, b)
dloss_db = dloss_dtp * dmodel_db(t_u, w, b)
return torch.stack([dloss_dw.sum(), dloss_db.sum()])
The gradient function combines the loss and model derivatives, sums their contributions, and stacks the weight and bias results into one tensor. section 5.4.2
Let PyTorch compute it
With a model and loss function defined, start with `params = torch.tensor([1.0, 0.0], requires_grad=True)`. Compute `loss = loss_fn(model(t_u, *params), t_c)`, then call `loss.backward()`. The two derivatives are now in `params.grad`. Before the next backward call, clear that gradient; when updating parameters yourself, make the update inside `torch.no_grad()`. section 5.5.1
The same pattern extends to neural networks: `loss.backward()` fills the gradients of trainable weights and biases, and an optimizer updates them with `optimizer.step()`. An activation such as `nn.Tanh()` transforms values but has no parameter to update. section 6.3.2



















