Backpropagation computes the gradient of the loss with respect to every parameter in the network by applying the Chain Rule (Multivariable) on the computation graph.
Forward pass: compute output layer by layer, storing all intermediates.
Backward pass: propagate gradients from loss backward:

Each node receives an upstream gradient and passes down a downstream gradient = upstream × local gradient, where the local gradient is the gradient of the node's output w.r.t. its input. Backprop visits nodes in reverse topological order, seeding the output gradient with .
Gate intuitions:
- distributes the upstream gradient unchanged to each summand
- routes the upstream gradient to whichever input was largest
- swaps the forward inputs as coefficients on the downstream gradient
- gradients sum at outward branches: if feeds both and , then

For a 2-layer MLP with , , :
Vanishing gradients: if consistently (sigmoid), gradients shrink exponentially with depth. Solutions:
- ReLU — gradient is 1 for positive inputs
- Residual Connections — gradient highway that bypasses layers
- Weight Initialization — controls initial gradient magnitudes
- Batch Normalization — stabilizes intermediate distributions
Gradient checking: verify a hand-derived gradient against a numerical estimate using the symmetric difference .
Activation / gradient checkpointing trades compute for memory: store only a subset of activations (the "checkpoints") and recompute the rest on the fly during the backward pass. For layers split into segments, memory drops from to ; the optimum gives memory at the cost of one extra forward pass ( backward compute).
In PyTorch: loss.backward() traverses the computation graph and populates .grad for every parameter. optimizer.step() then applies SGD/Adam. Backprop must start from a scalar loss, since is one number per parameter; with mean reduction, by linearity the batch gradient is exactly the mean of per-example gradients.
See also: The Artificial Neuron, Computation Graphs