Back to Blog

Backpropagation Step by Step: The Forward and Backward Pass

October 19, 202630–60 min readBy Tom Salembien
BackpropagationChain RuleJacobianGradient DescentDeep LearningInteractive

Before we start

Gradient descent is an optimisation method used to minimise a loss function, and minimising that loss is mainly what training a model means.

Many good sources cover the method itself. Foundations of Learning is the closest neighbour to this article and the source of the chain notation in section 02. Gradient Descent: Downhill to a Minimum takes the linear algebra route, which is the one that matters here. For the method as a tool you call, the scikit-learn guide to SGD is the reference, and Google's Machine Learning Crash Course is a good place to practise it. For the intuition, I strongly recommend the two videos below. They are the clearest visual account there is, and if you do not know 3Blue1Brown yet (shame on you ;)), the rest of the channel is just as good.

Forward pass and backpropagation on a classic example

Take a multilayer perceptron with one hidden layer and two output classes: a linear map gives , a ReLU gives , a second linear map gives the logits (one score per class), a softmax turns them into probabilities , and a compares with the label. Three inputs, four hidden units, two classes, twenty weights, biases aside.

The label is one-hot: 1 for the true class, 0 for the other. To tell cats from dogs, a cat is and a dog .

Training means lowering , the loss, which measures the gap between the probabilities and the label . In its simplest form, gradient descent does it : compute for every weight , .

x1x2x3z1z2z3z4h1h2h3h4u1u2y1y2ℒ

The difficulty is that sits at the beginning of the network and at the far end, with a ReLU, and a softmax in between, so there is no direct expression for to read off.

Backpropagation gets around this with the chain rule: it carries one vector back through the network, the derivative of the loss with respect to whatever the pass has reached. At the hidden layer we write it , which says how fast the loss changes as each coordinate of the hidden representation moves. Once the vector reaches a , the gradient of the loss with respect to its weights needs only two things:

  1. The gradient that arrived at the layer’s output.
  2. The input the layer received on the forward pass.

Writing rather than looks like a shortcut. Append a constant 1 to the representation and the bias becomes , the one multiplying that 1, so nothing that follows changes. Biases do not come up again, and large language models mostly drop them anyway: PaLM uses none and reports steadier training at scale, Llama has none in its linear layers, and Cramming found that removing them makes each step cheaper without slowing the loss. In the numbers here the bias columns are zero and every weight has one decimal place, so every sum has at most four terms and you can check the whole pass on paper.

ReLU set the two negative entries of to zero, and on the way back it zeroes the same two coordinates of the gradient: the weights into and out of those units get no update from this example.

The loss depends on the input through , , and in turn, so its derivative with respect to anything early is a sum over every path by which that quantity reached the end. The vector carried backward, , is that sum. Written as matrix products, each step of it multiplies by the transpose of one Jacobian, the matrix of derivatives of a step’s outputs with respect to its inputs.

A ReLU Jacobian is : each coordinate is scaled on its own, by 1 where the unit was open and 0 where it was closed. A softmax Jacobian is : every coordinate of the outgoing gradient mixes all the incoming ones, so both logits receive a gradient even though only one class is true. Through a deep network these factors multiply, one per layer, and whether their product shrinks or grows decides whether the early layers learn at all: the vanishing and exploding gradient problem, which a following article takes up.

Whatever sits inside the box (the two-layer network just folded, a convolution, an attention head or an entire transformer layer) takes a representation and a set of parameters and returns a representation.

If you would rather watch a network like this train than read about it, A Neural Network Playground puts a network of the same kind in a browser tab, with a live decision boundary and a loss curve that either falls or does not.

Going deeper: the same chain with more layers

Nothing in that walk depended on there being two layers. A deep network is the same chain of functions with more links in it: layer maps one representation to the next, , carrying its own parameters , and the last one feeds the loss:

Training needs for every layer, and the chain rule gets there through the representations in between. Write for the gradient arriving at representation , and for the Jacobian of layer .

On the network of section 01, count each linear map with the activation after it as one layer, the usual way of counting, so that every carries weights and . Any other grouping gives the same gradients, since a product of Jacobians does not depend on where the brackets go.

x1x2x3z1z2z3z4h1h2h3h4u1u2y1y2ℒ

One convention, kept from here on: gradients are column vectors. With it, the backward step is .

The gradient that reaches a layer does two jobs. Through , it carries on to the layer below. Through the derivative of the layer with respect to its own weights , it says how the loss responds when each of those weights moves, which is what training needs to update them:

For a linear map, the second line is of the gradient arriving at the layer with the representation that entered it:

Assembled, those lines are one step of training:

One step of training

forward →
← seed
← backward
update

The learning rate sets how far one step goes.

Most layers are built from Jacobians of three shapes, all three met in section 01: a dense matrix for a linear map, a diagonal one for an elementwise activation , and a dense symmetric one for a softmax:

ReLU is the case . Normalisation and attention are built from these plus one more piece, a product of two values that both depend on the input. Normalisation multiplies the input by the inverse of its own length , which gives ; attention multiplies the queries by the keys, . Every one of them is a case of the generic Jacobian, and all are .

What one backward sweep costs

One backward sweep returns the gradient of every weight. On the network of section 01 its cost can be counted by hand, as the multiplications in its matrix products, since everything else is a handful of comparisons and exponentials:

The multiplications of one step

operationmultiplicationsmemory
forward →
keeps
keeps
keeps
keeps
← backward
reads
reads
reads
reads
reads
skipped, no weights below
nudge each weight and run forward againkeeps nothing
forward20
backward28
nudging400

Laid out along the network, the top row is the forward pass, the middle row passes the gradient down and the bottom row builds the weight gradients, each product with its cost under it:

Write and for the multiplications of the forward pass and of the backward sweep, the totals of the two halves of the table. Forward, each weight is used in exactly one multiplication, so the forward pass costs as many multiplications as there are weights, :

Backward, each linear map does the two jobs of section 02, one product each. The first builds its weight gradient, the outer product of the gradient at its output with its input. That uses every weight once, so over both maps it costs again. The second passes the gradient down through the transpose, so that the map below can build its own weight gradient: gives , the ReLU turns it into , and needs for its gradient. Below there is only the input. Passing down through it would give , the gradient with respect to the data, and no weight needs it, so the sweep stops there. is plus one pass down, through :

The same count holds for any stack of linear maps. A map of shape costs multiplications forward and backward, except the first, which costs backward because it passes nothing down. With the weights of the first map, and nudging each weight in turn for one extra forward pass:

The network of section 01 has 20 weights, and the three totals are 20, 28 and 400. With a billion weights the backward sweep is about multiplications and nudging is , for a finite-difference approximation of the same numbers. The factor 2 is particular to stacked linear maps, but a bound of the same kind holds for any function built from elementary operations: its gradient costs at most a small constant times the function itself, whatever is (Griewank and Walther, chapter 4). It comes from running backward: the loss is one number and the weights are many, so one sweep from the loss reaches all of them, while carrying derivatives forward with the computation takes one sweep per weight again (Baydin et al.).

The price is memory. The backward rows of the table read values the forward pass produced, so those values stay alive until the sweep comes back for them: for the gradient of , for the ReLU mask, for the gradient of and for . Calling their count :

That is 13 numbers against 20 weights. The weights are stored once, but the kept values are stored again for every example of a batch, so with a batch of they cost . That is why the kept values (the “activations” of training-memory accounts), not the weights, usually set the memory bill of training, and why checkpointing, which keeps only some of them and recomputes the rest during the backward sweep, buys memory back with time.

Three exercises

1The same input, the other label

Keep the input of section 01 but label it a dog, . The forward pass never reads the label, so , , and do not change: , and units 1 and 4 are still closed.

  1. Compute , the gradient at the logits.
  2. Carry it back to , through and the ReLU, with:
  3. Write for the gradient of the loss with respect to that section 01 found with the cat label, and for the one the dog label gives. Both are , each with its own , and they differ by a single factor:
    Find without computing either matrix, and say why one number is enough.
Solution, exercise 1
  1. . With the cat label, section 01 had : the model already puts 0.7892 on dog, so with this label it is right, and the gradient is smaller.
  2. gives , and the closed units 1 and 4 delete their coordinates: .
  3. With two classes , so the gradient at the logits, , is:
    Every later step multiplies by something the forward pass fixed, the same under both labels: , the ReLU mask, then . A factor in front of comes out of each of them unchanged, so it is the factor between the two matrices:
    Rows 1 and 4 of both matrices, those of the closed units, are zero.

2The softmax Jacobian

The softmax turns the logits into probabilities:

  1. Show that , where is 1 when and 0 otherwise. In matrix form, .
  2. Show that the entries of sum to zero whatever , so whatever loss follows the softmax.
  3. Add the same number to every logit. Show that does not change, and explain why part 2 already said so: what is the derivative of the loss along that shift?
Solution, exercise 2
  1. Write for the denominator, so that . The numerator depends on alone, while depends on every logit:
    When , both the numerator and depend on , and the quotient rule gives:
    When , only depends on :
    The factor picks the case, so one formula covers both:
    Entry of is and that of is , which gives the matrix form. The network of section 01 has two classes, so and every entry is :
  2. Entry of collects, over every probability , how much moves with :
    Add up all the entries, then swap the two sums so that the inner one runs along row of :
    Every row adds up to zero, because the probabilities sum to one:
    So each term of the outer sum is , and the entries of add up to zero. The argument never used the values of , so it holds for any loss. Written with the vector of ones , the sum is .
  3. Adding to every logit multiplies the numerator and the denominator by :
    So does not change, and neither does the loss. The gradient says the same thing: the rate at which the loss changes as every logit moves together is its component along , which part 2 found to be zero:

3The cost of a real network

A classifier of handwritten digits takes 784 pixels, has two hidden layers of 512 ReLU units and ends on 10 classes, biases aside: . Count as the table of section 03 does: multiplications in the matrix products, and for memory the values the backward sweep reads.

  1. How many weights does it have, and how many multiplications does the backward sweep of one example take?
  2. How many numbers does one example keep for the backward sweep?
  3. From which batch size do the kept values outnumber the weights?
Solution, exercise 3
  1. Write , and for the three maps. A map of shape has weights. Forward, each weight is used in one multiplication, so a layer costs as many multiplications as it has weights. Backward, it costs them twice: once for its weight gradient, once to pass the gradient down through its transpose, so that the layer below can build its own. pays only once: passing down through it would give the gradient with respect to the pixels, and no weight needs it. Along the network, the top row is the forward pass, the middle row passes the gradient down and the bottom row builds the weight gradients, each product with its cost under it:
    Layer by layer, forward:
    and backward, from the top, where the ReLU masks cost nothing:
    Adding up each column:
    layershapeweightsforwardbackward
    total
    The backward column is for the weight gradients plus what passing down costs in and :
    Nudging each weight in turn would cost one forward pass per weight, multiplications.
  2. The backward sweep reads for , each for its ReLU mask, each and for the weight gradient of the layer above it:
  3. A batch of examples keeps numbers, and the weights are stored once:
    From on, one step keeps more values than the network has weights, and a batch of 256 is already past it.

References

The reading list is what this article takes as known: gradient descent itself, and a network to train in a browser. The references are where each claim of the prose and of the proof panels is established, with a note on what each one was cited for.

Further reading

  1. 01
    Foundations of Computer Vision, the learning part

    Book, Torralba, Isola and Freeman, MIT Press

    The chapters this article sits next to: neural networks as function compositions, backpropagation, and the notation for a layer as a map from one representation to the next. It is where the chain notation of section 02 comes from.

  2. 02
    Stochastic Gradient Descent

    Documentation, scikit-learn user guide

    The practitioner view: SGD as a fitting routine you call, with the loss functions, learning-rate schedules and regularisation it exposes. Start here if you want the method as a tool rather than as a theory.

  3. 03
    Lecture 22, Gradient Descent: Downhill to a Minimum

    Lecture, Gilbert Strang, MIT 18.065, MIT OpenCourseWare

    Gradient descent from the linear algebra side, which is the side this article needs: how the geometry of the surface, and therefore the conditioning of a matrix, governs how the iteration behaves.

  4. 04
    Gradient descent, how neural networks learn

    Video, 3Blue1Brown, Neural networks, chapter 2

    The clearest visual account of the method: the cost as a surface over every weight, the gradient as the direction that lowers it fastest, and a network nudging its weights down that slope one step at a time.

  5. 05
    Backpropagation calculus

    Video, 3Blue1Brown, Neural networks, chapter 4

    The chain rule on a network one neuron wide, written out term by term. A wider network writes the same product of local derivatives with Jacobians.

  6. 06
    3Blue1Brown

    Video, Grant Sanderson, YouTube

    Mathematics explained through animation. Its neural networks series holds the two videos at the top of this article, and its linear algebra series takes the same visual route to matrices.

  7. 07
    Linear regression: gradient descent

    Course, Machine Learning Crash Course, Google

    The shortest complete account of the loop this article takes as given: compute the derivative of the loss with respect to each weight, step each weight against it, repeat. Start here if the words "update the weights" are doing too much work.

  8. 08
    TensorFlow Playground

    Interactive, Daniel Smilkov and Shan Carter, Google

    A small network you train in a browser tab: pick a dataset and a set of input features, set the depth, the width, the activation and the learning rate, then watch the weights and the decision boundary move while the loss curves fall.

Papers and books

  1. 01
    Automatic differentiation in machine learning: a survey

    Baydin, Pearlmutter, Radul and Siskind, 2018, Journal of Machine Learning Research 18(153)

    Forward mode and reverse mode side by side, and why a scalar loss with many parameters picks reverse.

  2. 02
    Pattern Recognition and Machine Learning

    Bishop, 2006, Springer

    Section 4.3.4 for the softmax derivative and section 5.3 for the backward recursion in the same notation.

  3. 03
    PaLM: Scaling Language Modeling with Pathways

    Chowdhery, Narang, Devlin and others, 2022, Journal of Machine Learning Research, arXiv:2204.02311

    Section 2, "No Biases": none in the dense layers or the layer norms, a choice the authors report made training of large models more stable.

  4. 04
    Cramming: Training a Language Model on a Single GPU in One Day

    Geiping and Goldstein, 2023, ICML 2023, arXiv:2212.14034

    Section 4.2: dropping the attention and feed-forward biases makes each gradient step cheaper without slowing how fast the model improves.

  5. 05
    Deep Learning

    Goodfellow, Bengio and Courville, 2016, MIT Press

    Section 6.5 for backpropagation as a computational graph, and chapter 8 for what optimisation does with the result.

  6. 06
    Evaluating Derivatives: Principles and Techniques of Algorithmic Differentiation

    Griewank and Walther, 2008, SIAM, second edition

    Chapter 4 (memory issues and complexity bounds) for the bound that a gradient costs a small constant times the function, whatever the number of inputs.

  7. 07
    Adam: A Method for Stochastic Optimization

    Kingma and Ba, 2015, ICLR 2015, arXiv:1412.6980

    Section 2 is the per-parameter step size itself: the two moment estimates, the bias correction, and the division that makes the update scale-free.

  8. 08
    Decoupled Weight Decay Regularization

    Loshchilov and Hutter, 2019, ICLR 2019, arXiv:1711.05101

    Why weight decay inside the gradient is not weight decay once Adam has rescaled it, and the one-line fix that became AdamW.

  9. 09
    Learning representations by back-propagating errors

    Rumelhart, Hinton and Williams, 1986, Nature 323, 533 to 536

    The backward recursion in its original form: an error signal at a layer, computed from the one after it.

  10. 10
    Attention is all you need

    Vaswani, Shazeer, Parmar, Uszkoreit, Jones, Gomez, Kaiser and Polosukhin, 2017, Neural Information Processing Systems

    Section 3.2.1 for the scaled dot product, including the division by the root of the head dimension and the reason given for it.

Get in touch

We hope you enjoyed this article. If you have questions, found a bug, or just want to chat about AI and engineering, we'd love to hear from you.

Future articles?

We're planning more deep dives into:

  • Graph Neural Networks
  • Transformer Architecture
  • System Design for ML

Get them in your inbox

Send feedback

Share this article