AI ENGINEER02-02 · Backpropagation from scratch
20/90
Sign in

Layer 02 · Deep Learning · Ch 02

Backpropagation from scratch

Trace an error backwards through a tiny neural calculation, compute a gradient, and make one honest learning update.

60 min readdifficulty beginnerdepth build

A model predicts that a support ticket is safe to wait. The target says it was urgent. Knowing the prediction was wrong is not enough: the system needs to know which of thousands or billions of adjustable numbers should change, and in which direction.

BackpropagationBackpropagationAn efficient method for calculating how a model’s loss changes with respect to each parameter. It works backwards through a computation graph, combining local derivatives with the chain rule. Backpropagation calculates gradients; an optimiser uses them to update parameters. is the accounting method that assigns that local credit. It is the bridge between a forward-pass calculator and a model that can learn.

Lesson details

Module
Deep learning
Lesson
2 · Backpropagation from scratch
Difficulty
Beginner
Learning time
60 minutes

Before you start

  • Perceptrons, activations, hidden layers, and a forward pass
  • Derivatives, gradients, and the chain rule from Maths I

Skills you will gain

  • Draw a computation graph for a small prediction and loss
  • Use the chain rule to calculate one parameter gradient
  • Explain the distinct jobs of a forward pass, backpropagation, and an optimiser
  • Make and verify one gradient-descent update in Python
  • Use a finite-difference check as a small gradient debugging tool

Why this matters

Every trainable neural network needs a way to improve its parameters from examples. Backpropagation makes this practical: it calculates a gradient for each parameter without separately redoing the whole calculation for every parameter. Frameworks automate the arithmetic, but debugging a training run requires knowing what they are doing.

Plain-English mental model

Step 1 — Turn an error into a number the model can reduce

A model needs a numeric target for improvement. A loss functionLoss functionA numerical score describing how costly a model's prediction is relative to the training target. Fitting adjusts parameters to reduce an aggregate training loss, but lower training loss does not guarantee better real-world behaviour. measures how costly a prediction is compared with the training target. For one numeric prediction, a simple choice is squared error:

loss = (prediction − target)²

Let input x = 2, target t = 1, and one parameter w = 0. Our tiny model predicts:

y = w × x = 0 × 2 = 0
error = y − t = 0 − 1 = −1
loss = error² = (−1)² = 1

The loss is not a moral judgement and it is not the same as user harm. It is the training signal we chose. In a real system, choosing the wrong target or loss can optimise the wrong behaviour very efficiently.

Step 2 — Put the forward pass on a computation graph

FIG 02-02.1 · ONE ERROR, TRACED BOTH WAYSforward: calculate a lossweightw = 0x = 2multiplyy = w × x = 0subtract targete = y − t = −1t = 1square errorL = e² = 1backward: assign credit with local slopesdL/de = 2e = −2de/dy = 1dy/dw = x = 2gradient for this parameter: dL/dw = (−2) × 1 × 2 = −4update: w ← w − 0.1 × (−4) = 0.4
FIG 02-02.1— the top path calculates a prediction and squared loss. The bottom path applies local derivatives backwards. Their product is the gradient for w, which an optimiser uses for one small update.

A computation graphComputation graphA diagram or data structure that represents a calculation as connected operations and values. It makes clear what was calculated in the forward pass and provides the paths used to apply the chain rule backwards. makes the calculation explicit as connected values and operations. Our graph has three operations: multiply, subtract, and square.

The forward pass goes left to right. Backpropagation goes right to left. It does not reverse the model’s answer. It calculates how a small change in an earlier value would change the final loss.

Step 3 — Use the chain rule, one local slope at a time

A derivativeDerivativeA number describing how a small change in one value changes another value nearby. In model training, a derivative of loss with respect to a parameter tells whether increasing that parameter would locally increase or decrease loss, and by how much. is a local rate of change. For squared error, the derivative of error² with respect to error is 2 × error. At error = −1, that is −2.

We need the derivative of loss L with respect to weight w. The chain rule says multiply the local effects along the path:

dL/dw = dL/derror × derror/dy × dy/dw

For our example:

dL/derror = 2 × error = −2
derror/dy = 1
dy/dw = x = 2

dL/dw = −2 × 1 × 2 = −4

dL/dw = −4 means a small increase in w would locally decrease loss. The sign matters. A gradient is not “the amount to subtract”; it points uphill. To reduce loss, gradient descent goes in the opposite direction.

Worked example — make one update and check it

Gradient descentGradient descentAn optimisation procedure that repeatedly changes parameters in the direction opposite the loss gradient. The gradient supplies a local direction; practical training also needs a learning rate, batches, stability checks, and validation evidence. updates a parameter using a learning rateLearning rateA positive setting that controls the size of an optimiser’s parameter update. Too large can overshoot or diverge; too small can make training impractically slow. It must be evaluated with the full training and validation process., a positive step-size setting:

new_weight = old_weight − learning_rate × gradient

With learning rate 0.1 and gradient −4:

new_weight = 0 − 0.1 × (−4)
new_weight = 0.4

Now run a new forward pass, using w = 0.4:

new prediction = 0.4 × 2 = 0.8
new error = 0.8 − 1 = −0.2
new loss = (−0.2)² = 0.04

Loss fell from 1 to 0.04 on this example. That is a useful sanity check, not a generalisation result. A real training step averages or sums loss over a batch, repeats across training data, and still needs validation data to reveal whether the improvement survives unseen examples.

FIG 02-02.2 · MOVE DOWNHILL, BUT NOT BLINDLYparameter w →lossminimumtangent = local slopestartupdate rulew = w − learning_rate × gradientopposite the uphill direction
FIG 02-02.2— a gradient is a local uphill direction. Gradient descent moves the opposite way using a learning rate. Steps that are too large can overshoot; steps that are too small can make learning painfully slow.

Try it — manual forward, backward, and update in Python

PythonOne parameter learns from one example
x = 2.0
target = 1.0
weight = 0.0
learning_rate = 0.1

# Forward pass
prediction = weight * x
error = prediction - target
loss_before = error ** 2

# Backward pass: local derivatives multiplied by the chain rule
d_loss_d_error = 2 * error
d_error_d_prediction = 1.0
d_prediction_d_weight = x
gradient = d_loss_d_error * d_error_d_prediction * d_prediction_d_weight

# Optimiser step
new_weight = weight - learning_rate * gradient
new_loss = (new_weight * x - target) ** 2

print('loss before:', loss_before)
print('dL/dw:', gradient)
print('new weight:', new_weight)
print('loss after:', new_loss)

Important lines

error = prediction - target
The signed error says which side of the target the prediction lies on.
d_loss_d_error = 2 * error
This is the local slope of squared error at the current error.
d_prediction_d_weight = x
For y=w×x, increasing w by a tiny amount changes y in proportion to x.
weight - learning_rate * gradient
The gradient points uphill, so subtracting it takes a controlled downhill step.

Step 4 — Check a gradient before trusting it

A small automatic differentiationAutomatic differentiationA technique used by machine-learning frameworks to calculate exact derivatives of a program’s composed operations, up to floating-point precision. It is not numerical approximation by tiny input changes and it is not symbolic algebra; frameworks commonly implement reverse-mode automatic differentiation for neural-network training. system calculates chain-rule gradients for framework operations. It is exact for those operations up to normal floating-point effects. It cannot detect a wrong target, incorrect data, an unsuitable loss, a missing mask, or a model that is unsafe to deploy.

For a small debugging check, estimate a slope with two nearby forward passes. This finite difference is slower and approximate, so it is for checking—not for training a large network.

PythonCompare manual and numerical gradients
def loss_for(weight: float) -> float:
    prediction = weight * 2.0
    return (prediction - 1.0) ** 2


weight = 0.0
epsilon = 0.0001

numerical = (loss_for(weight + epsilon) - loss_for(weight - epsilon)) / (2 * epsilon)
manual = 2 * (weight * 2.0 - 1.0) * 2.0

print('numerical:', round(numerical, 4))
print('manual:', round(manual, 4))

If these disagree for a small test, stop and inspect the calculation before launching a long training run. In larger systems, test a few parameters and keep tolerances realistic because floating-point arithmetic and very small epsilon values can introduce numerical noise.

Real-world AI engineering example — a training run that starts to fail

Common mistakes

Saying backpropagation “updates the weights”.

Fix — Separate the jobs: backpropagation calculates gradients; an optimiser applies an update using those gradients and settings such as learning rate.

Dropping the sign of a gradient.

Fix — Write the update rule explicitly: parameter minus learning rate times gradient. Check whether a tiny step lowers loss on a toy example.

Treating lower loss on one batch as success.

Fix — Use it only as a local sanity check. Measure held-out performance, error slices, calibration, latency, and user impact separately.

Changing learning rate, model shape, data, and loss at the same time after NaNs appear.

Fix — Return to a known-good run, log finite values and magnitudes, then change one controlled factor at a time.

Assuming automatic differentiation makes any model correct.

Fix — Autodiff differentiates implemented operations. It cannot validate the target, data pipeline, masking, metric, or decision policy.

Using finite differences as the main training method.

Fix — Use backpropagation/autodiff for efficient training. Use finite differences only on tiny cases to catch implementation mistakes.

Knowledge check

Knowledge check

1What is the main output of backpropagation?
2For L=(y-t)², what is dL/dy?
3If dL/dw is -4 and learning rate is 0.1, what update does gradient descent make from w=0?
4What is a finite-difference gradient useful for?

Practice activity

Practice · 10–20 minutes

Follow one error backwards

Goal: Calculate a loss gradient by hand, make one update, and verify that the local loss falls.

  1. Use x=3, target=1, and weight=0 with y=w×x and squared error.
  2. Write y, error, and loss for the forward pass.
  3. Calculate dL/de, de/dy, dy/dw, and dL/dw.
  4. Apply learning rate 0.1 and calculate the new loss.
  5. Run the starter code and compare it with your working.
  6. State one reason this single-example result is not sufficient for deployment.

Expected result: Your gradient is -6, the updated weight is 0.6, and loss decreases from 1 to 0.64. You should identify validation on relevant unseen cases as a missing step.

Optional challenge: Add a bias parameter, derive its gradient, and confirm a numerical gradient check for both w and b.

Reveal solution
x = 3.0
target = 1.0
weight = 0.0
learning_rate = 0.1

prediction = weight * x
error = prediction - target
loss = error ** 2

gradient = 2 * error * x
new_weight = weight - learning_rate * gradient
new_loss = (new_weight * x - target) ** 2

print('loss:', loss)
print('gradient:', gradient)
print('new weight:', new_weight)
print('new loss:', new_loss)

Solution: the forward pass gives prediction=0, error=-1, and loss=1. The local derivatives are dL/de=-2, de/dy=1, and dy/dw=3, so the gradient is -6. The update is 0 - 0.1×(-6) = 0.6. The new prediction is 1.8, with error 0.8 and loss 0.64. The loss fell, but this is only one training example. A deployable model still needs representative data, protected validation and test evidence, an error policy, and monitoring.

Key takeaways

  • A loss converts one prediction error into a numeric training signal, not a complete measure of product success.
  • A computation graph records the forward operations that backpropagation differentiates in reverse.
  • The chain rule multiplies local derivatives to assign a gradient to an earlier parameter.
  • Gradient descent subtracts learning rate times gradient; the sign tells the update direction.
  • Autodiff makes gradients practical, while data, loss design, validation, and monitoring remain engineering responsibilities.

Flashcards

Flashcards

1 of 6

Revision and interview questions

  1. Draw a computation graph for y=w×x, e=y−t, L=e². Label the forward values and local derivatives.
  2. Derive dL/dw for squared error and explain every factor in the chain-rule product.
  3. Explain why backpropagation and gradient descent are different operations.
  4. Design a small gradient-debugging plan for a model whose loss becomes NaN after a configuration change.

One-page sketchnote summary

Print me · one-page revision sheet

Backpropagation from scratch

Main idea

Backpropagation breaks one final error into local responsibilities for each parameter. The chain rule moves backward through the forward calculation; an optimiser then makes a measured move downhill.

Core terms

  • Loss — numeric training signal
  • Computation graph — connected operations
  • Derivative — local rate of change
  • Chain rule — multiply local effects
  • Gradient — loss change per parameter
  • Learning rate — update step size

One picture

forward: calculate a lossweightw = 0x = 2multiplyy = w × x = 0subtract targete = y − t = −1t = 1square errorL = e² = 1backward: assign credit with local slopesdL/de = 2e = −2de/dy = 1dy/dw = x = 2gradient for this parameter: dL/dw = (−2) × 1 × 2 = −4update: w ← w − 0.1 × (−4) = 0.4

Code pattern

forward → loss
backward → gradient
parameter ← parameter − rate × gradient

Watch out

  • Do not confuse gradients with updates
  • Do not lose the gradient sign
  • Do not trust one-batch loss alone
  • Do not treat autodiff as data validation

Remember

  • Forward computes loss
  • Backward assigns gradients
  • Optimiser changes parameters
  • Tiny checks catch big training bugs
  • Validation judges useful learning

Three quick questions

  1. What is dL/dw?
  2. Which direction lowers loss?
  3. What does autodiff not know?

Lesson checklist

0 of 7 complete

Resources

Next up
PyTorch
You can now explain the arithmetic that a training framework automates. Next, use tensors, autograd, modules, data loaders, and training loops to apply the same ideas to real models.