Backpropagation
How is the blame for an error shared among thousands of weights?
Lesson complete
If you like:
We know how to fix a weight: subtract its slope. But a network has thousands of weights, in layers, and almost none of them touch the output. How does each one know how much of the error is its fault?
No voice: the lesson advances on its own with subtitles.
The voice for this lesson is being recorded: for now it advances on its own with subtitles.
Review modeComment on this stepI finished the lesson
What you will achieve
- Compute, step by step and with real numbers, the forward pass, the loss, and the blames (gradients) of a small network.
- Explain the chain rule as multiplying the influence of each link, and why one layer’s blame is reused going backward.
- Tell apart what backpropagation computes (the gradient) from what gradient descent does (moves the weights).
Key ideas
- A network’s final error is shared among thousands of weights hidden in layers. Knowing how much blame each one carries is the credit assignment problem.
- The chain rule says that a weight’s total influence on the error is the product of the influence of each link along the path.
- Backpropagation sweeps the network from output to input, computes each neuron’s blame, and reuses it for the previous layer: it gets the whole gradient in a single trip.
- Backpropagation only computes the gradient. The one that corrects the weights is gradient descent: w ← w − η · blame.
- It is cheap (in large networks, on the order of a couple of forward passes), but it needs the values of the forward pass to be stored, and the blame can fade as it crosses many layers.
What many people believe
Common belief Backpropagation is the mechanism by which the network corrects its weights.
What is true In current usage, it only computes how much blame each weight carries (the gradient), with one trip backward. Moving the weights is the job of gradient descent (or another optimizer), which uses those numbers.
Check yourself
Four questions. No grade, no account: they just show whether the idea stuck.
Under the hoodFor those who want the math and the code. You do not need it to follow the course.
The network’s equations
The lesson’s network has inputs , two hidden neurons, one output neuron, a sigmoid activation , and no biases:
With , , and we get and . The starting weights were chosen so that every calculation shown with three decimals can be repeated by hand, using the already-rounded figures, without discrepancies (the lesson’s verify-data.ts script checks it, and compares the gradient with finite differences).
The chain rule, step by step
If depends on , which depends on , which depends on , the derivative of with respect to is the product of the derivatives of each link:
The sigmoid’s derivative is , so it is computed from the activation that was already stored. The first two factors form the neuron’s blame . Going backward, layer by layer:
With the lesson’s numbers: ; ; and . Since , comes out with the opposite sign (). Note that the blames and do not add up to : each weight gets the neuron’s blame multiplied by its own signal, not a share of it.
In layers and in matrix form
With the matrix that takes to , the same ideas are written for any number of layers:
Each is computed once from the next layer: that is what makes the method cheap. With ReLU, is replaced by if and otherwise.
Why it is cheap
For a scalar loss and weights, the reverse mode of automatic differentiation (the techniques for differentiating programs exactly; backpropagation is its special case for networks) delivers all derivatives in a single backward sweep. The forward mode, or probing with finite differences, needs one sweep per weight. The whole gradient costs a small constant times the cost of evaluating the function: Baydin et al. (2018), citing Griewank and Walther (2008), give and typically between 2 and 3, and Griewank (2012) calls it the “cheap gradient principle”.
In a large transformer, Kaplan et al. (2020) count about FLOPs per token going forward, with the parameters excluding embeddings, and note that the backward pass costs approximately twice as much: hence their FLOPs per training token. In exchange, the activations of the forward pass must be stored until they are used: the 1986 paper itself points out that the outputs of the intermediate layers in the forward pass are needed for the backward pass.
A limit: the blame can fade
Since , each layer of sigmoids contributes a factor of at most to the blame: after layers. The weights also multiply at every layer and could compensate, but with moderate weights the product shrinks exponentially. That is why deep networks favor other activations, residual connections, and variants such as the LSTM, topics of lessons 12 and 13.
Where it comes from, carefully
The name and the fame date from 1986, but the idea is older and had several discoverers:
- Linnainmaa. His master’s thesis (University of Helsinki, 1970, in Finnish; results in English in BIT, 1976) studies how the rounding error of an algorithm accumulates and proposes what is now called reverse mode. According to Griewank (2012), he did not present it as a way to get gradients cheaply.
- Werbos. His doctoral thesis in statistics (Harvard, August 1974) develops “ordered derivatives” and “dynamic feedback” for prediction models. He himself says (Werbos, 2006) that he wrote only a few words about neural networks, in chapter 5; Goodfellow et al. (2016) date to 1981 his proposal to apply it to training neural networks.
- Rumelhart, Hinton, and Williams (Nature, 1986). They use the same mathematics as this lesson: error , sigmoid, one forward pass and one backward pass that “propagates derivatives”. They acknowledge that David Parker and Yann LeCun discovered variants independently. In the paper, “back-propagation” names the whole learning procedure (with the update and a variant with an acceleration term, what is now called momentum); today’s distinction, backpropagation for the gradient and another algorithm to learn with it, is the one Goodfellow et al. (2016) explain. The authors close by saying that the procedure, “in its current form, is not a plausible model of learning in brains”.
In code
import math
def sigma(z):
return 1 / (1 + math.exp(-z))
X, T = (1.0, 0.5), 1.0
def forward(w):
a1 = sigma(w[0] * X[0] + w[1] * X[1])
a2 = sigma(w[2] * X[0] + w[3] * X[1])
y = sigma(w[4] * a1 + w[5] * a2)
return a1, a2, y, 0.5 * (y - T) ** 2
def backward(w):
a1, a2, y, loss = forward(w)
d_y = (y - T) * y * (1 - y) # blame of the output neuron
d_1 = d_y * w[4] * a1 * (1 - a1) # blame of hidden 1
d_2 = d_y * w[5] * a2 * (1 - a2) # blame of hidden 2
grad = [d_1 * X[0], d_1 * X[1], d_2 * X[0], d_2 * X[1], d_y * a1, d_y * a2]
return loss, grad
w = [0.6, -0.3, 0.7, 0.5, 0.8, -0.9]
loss, grad = backward(w)
print(round(loss, 3), [round(g, 3) for g in grad])
# 0.146 [-0.026, -0.013, 0.024, 0.012, -0.082, -0.097]
# check: probe each weight (one extra forward pass per weight)
eps = 1e-6
check = []
for k in range(6):
w2 = w.copy()
w2[k] += eps
check.append((forward(w2)[3] - loss) / eps)
print([round(c, 3) for c in check])
# [-0.026, -0.013, 0.024, 0.012, -0.082, -0.097]
# one gradient descent step: gradient descent does this, not backpropagation
eta = 1.0
w = [wk - eta * g for wk, g in zip(w, grad)]
print(round(forward(w)[3], 3))
# 0.129
What comes next
With real data the gradient is computed on a batch of examples rather than on a single one, and optimizers such as momentum or Adam transform that gradient before moving the weights. All of them receive the gradient from backpropagation. That is the topic of lesson 9.
Decision lens
What this idea means if your job is to decide, not to code.
- One training step costs about three forward passes: one forward and one backward that costs twice as much. Ask for the training cost per token, not just the cost of use.
- Training requires storing the intermediate values of the forward pass: GPU memory, not just compute, limits which model fits. Ask how much memory training needs compared with using the model.
- Only what is differentiable can be trained by backpropagation. A hard rule, a database lookup, or a discrete decision in the middle of the system cuts the flow of blame: other methods are needed there.
- Almost nobody codes backpropagation by hand: PyTorch and TensorFlow derive it automatically. The useful questions are which parts are trained and which are frozen, because freezing layers saves compute and gradient memory.
Terms in this lesson
- Gradient The list of the slopes of the error, one for each weight. Seen as an arrow, it points to where the error rises fastest.
- Gradient descent A method that adjusts the weights step by step, always against the slope of the error (the gradient), until it reaches a bottom.
- Derivative The mathematical name for the slope of a curve at a point: how much one quantity changes for each small change in another.
- Learning rate A number (η) that multiplies the slope and sets the size of each step. Too small is slow; too large bounces or diverges.
- Weight (w) In a linear model, the number that multiplies the input: the slope of the line. It tells how much the prediction rises for each unit the input grows.
- Loss function A single number that summarizes how wrong a model is on its data. Training is the search for the parameters that make it as small as possible.
- Forward pass Computing a network’s output: the numbers move on layer by layer, from input to output.
- Hidden layer A layer of neurons between input and output. It creates intermediate signals that the output combines; its values are not observed directly.
- Sigmoid The function σ(z) = 1/(1 + e⁻ᶻ): it turns any number into a value between 0 and 1, and equals 0.5 when z = 0.
- Activation function A function applied to the weighted sum plus the bias to produce the neuron’s output. Examples: the step and the sigmoid.
- Artificial neuron A unit of computation that multiplies each input by a weight, adds the results, adds a bias, and applies an activation function: y = f(w·x + b).
- Layer A group of neurons that receive the same inputs and compute at the same time. A network is a chain of layers: input, one or more hidden ones, and output.
- ReLU Rectified linear unit: an activation function that returns zero if the sum is negative and the sum itself if it is positive, max(0, z). A hinge with a single corner.
- Backpropagation An algorithm that computes the gradient of the loss with respect to every weight of a network in a single backward sweep, applying the chain rule layer by layer. It computes the blames; it does not move the weights (in the 1986 paper, the name covered the whole learning procedure).
- Chain rule If a quantity depends on another through a chain of steps, its total influence is the product of the influence of each step. It is the basis of backpropagation.
- Credit assignment (sharing the blame) The problem of deciding how much each decision, weight, or neuron hidden in the middle of a system contributed to the final outcome (Minsky posed it this way in 1961, for reinforcement learning). In a differentiable network, backpropagation solves it efficiently.
Full transcript
Sources
- Rumelhart, D. E., Hinton, G. E., Williams, R. J. · Nature 323, 533–536 (1986). Learning representations by back-propagating errors
- Griewank, A. (2012). Who invented the reverse mode of differentiation? · Documenta Mathematica, Extra Volume ISMP, 389–400
- Linnainmaa, S. (1976). Taylor expansion of the accumulated rounding error · BIT 16(2), 146–160 (versión en inglés de resultados de su tesis de maestría de 1970, Universidad de Helsinki)
- Werbos, P. J. (1974). Beyond Regression: New Tools for Prediction and Analysis in the Behavioral Sciences (tesis doctoral, Universidad de Harvard; copia escaneada)
- Werbos, P. J. (2006). Backwards differentiation in AD and neural nets: past links and new opportunities · en Automatic Differentiation: Applications, Theory, and Implementations, LNCSE 50, 15–34
- Goodfellow, I., Bengio, Y., Courville, A. (2016). Deep Learning, secciones 6.5 (Back-Propagation and Other Differentiation Algorithms) y 6.6 (Historical Notes)
- Baydin, A. G., Pearlmutter, B. A., Radul, A. A., Siskind, J. M. (2018). Automatic differentiation in machine learning: a survey · JMLR 18(153), 1–43
- Kaplan, J., McCandlish, S., Henighan, T., et al. (2020). Scaling Laws for Neural Language Models (cómputo de entrenamiento ≈ 6N por token; pase hacia atrás ≈ el doble que el de ida)
- Brown, T. B., Mann, B., Ryder, N., et al. (2020). Language Models are Few-Shot Learners (GPT-3: 175 mil millones de parámetros)
- Minsky, M. (1961). Steps toward Artificial Intelligence · Proceedings of the IRE 49(1), 8–30 (§ «The basic credit-assignment problem for complex reinforcement learning systems»)
CommentsThis lesson’s public conversation: questions, facts to check, ideas.
Comments live in GitHub Discussions, in the course’s public repository; writing one requires a GitHub account. They load from giscus.app when you open this section. The course reviewers read them, and if a change is accepted, it is applied in both languages. Open the thread on GitHub