Put the features in a design matrix of shape and fold the bias in by adding a column of ones, so a single weight vector of length does everything. Then all predictions are and the loss is a squared vector length:
The gradient in matrix form
Applying the chain rule to every residual at once gives a compact gradient. Check the shapes: is and the residual vector is , so the result is , one number per weight.
Read it as: each weight's gradient is the correlation between its feature column and the residuals. If a feature is high exactly where the model under-predicts, its weight should go up.
Route 1: solve it exactly
The loss is a bowl (convex), so its minimum is where the gradient is zero. Setting and solving gives the normal equation:
- It is exact and needs no learning rate.
- Solving a system costs about , fine for hundreds or a few thousand features, painful for millions.
- It needs to be invertible. If two features are perfectly correlated (say, height in cm and height in inches) it isn't, and even nearly-correlated features make the solution numerically unstable. Regularisation (module 3) fixes this.
- In code, never form the inverse explicitly: use
np.linalg.solve(X.T @ X, X.T @ y)or, better,np.linalg.lstsq(X, y), which is more stable.
Route 2: gradient descent, in batches
Gradient descent scales to any size and is the only option for models with no closed-form solution, which is nearly all of them. Computing the gradient over all examples every step (batch gradient descent) is wasteful when is in the millions: the average over a random sample of 32 to 1,024 examples points in nearly the same direction at a tiny fraction of the cost.
| variant | examples per step | character |
|---|---|---|
| batch GD | all | smooth, exact gradient, slow per step |
| stochastic GD | 1 | very noisy, cheap, rarely used alone |
| mini-batch SGD | 32 to 1,024 | the standard: cheap, parallel on GPUs, mildly noisy |
One pass through the whole training set is called an epoch. The noise of mini-batches isn't only a cost: it helps neural networks escape saddle points and is thought to bias them toward solutions that generalise better.
The gradient of the squared error is . Set it to zero for the exact answer when features are few; follow it in mini-batches when data or models are big.