One training step
Four phases, one causal story
Keeping the phases separate makes debugging much easier. A wrong prediction, invalid derivative, and unstable optimizer update produce different symptoms and require different fixes.
Forward
Feed the input into the first layer. Every layer computes its weighted pre-activation and nonlinear output. The final activation is the prediction.
z[l] = w[l] * a[l-1] + b[l]
a[l] = activation(z[l])
Loss
Compare prediction with target. This lab uses squared error so the first backward signal is prediction minus target.
L = 0.5 * (prediction - target)^2
dL/dprediction = prediction - target
Backward
Move from output to input. Multiply the upstream gradient by activation slope, then use the result for weight, bias, and previous-activation gradients.
delta[l] = upstream * activation'(z[l])
dL/dw[l] = delta[l] * a[l-1]
Update
Apply the optimizer step only after all gradients are computed. Updating a weight during backward traversal would make later gradients refer to a different network.
w[l] = w[l] - learning_rate * dL/dw[l]
b[l] = b[l] - learning_rate * delta[l]