Deep Learning Slides 📂 Introduction · 10 of 18 32 min read

Backpropagation Solved: 2×2×2 Numerical Example

A complete backpropagation walkthrough on a 2-input, 2-hidden, 2-output network. Every net value, activation, error term, and gradient worked out by hand — the 3-term chain for output weights, the 4-term chain for hidden weights — then confirmed line by line in Python. The classic exam problem, solved.

Backpropagation — Solved Numerical (2×2×2)

Two inputs, two hidden neurons, two outputs — and every single derivative worked out by hand. The classic exam-style problem, solved end to end, then confirmed line by line in Python.
2×2×2 Network Forward & Error 3- & 4-Term Chains Python-Verified

Press Next → or use ← → arrow keys

Section 01

The Network

Two inputs feed two hidden neurons, which feed two outputs. Eight weights in all; sigmoid activation everywhere.

x₁ x₂ H₁ H₂ Y₁ Y₂ InputsHidden · σOutputs · σ w₁…w₄w₅…w₈
🗺️
Eight weights, two error terms

w₁–w₄ connect inputs to the hidden layer; w₅–w₈ connect hidden to outputs. With two outputs, the loss adds up the error from both Y₁ and Y₂.

Section 01

The Givens

x₁ = 0.05,   x₂ = 0.10
T₁ = 0.01,   T₂ = 0.99
σ(z) = 1/(1 + e⁻ᶻ)
η = 0.5
w₁=0.15, w₂=0.20, w₃=0.25, w₄=0.30
w₅=0.40, w₆=0.45
w₇=0.50, w₈=0.55
🧮
Loss = summed squared error

Etotal = ½(T₁ − ŷ₁)² + ½(T₂ − ŷ₂)². Each output contributes its own squared error; backprop will send blame back from both.

Section 02 · Forward

Forward Pass — Hidden Layer

Weighted sum (net), then sigmoid. The net values below already fold in the hidden-layer bias:

1
netH1 = w₁x₁ + w₂x₂ + b₁ = 0.0075 + 0.020 + b₁ = 0.3825
2
outH1 = σ(0.3825) = 0.5944
3
netH2 = w₃x₁ + w₄x₂ + b₂ = 0.0125 + 0.030 + b₂ = 0.3900
4
outH2 = σ(0.3900) = 0.5963
📤
Hidden outputs ready

outH1 = 0.5944 and outH2 = 0.5963 now feed both output neurons.

Section 02 · Forward

Forward Pass — Output Layer

Each output mixes both hidden activations through its own pair of weights, then squashes:

1
netY1 = w₅·outH1 + w₇·outH2 = (0.40)(0.5944) + (0.50)(0.5963) = 0.5359
2
ŷ₁ = σ(0.5359) = 0.7569
3
netY2 = w₆·outH1 + w₈·outH2 = (0.45)(0.5944) + (0.55)(0.5963) = 0.5955
4
ŷ₂ = σ(0.5955) = 0.7685
🎯
Predictions vs targets

We predicted ŷ₁ = 0.7569 (target 0.01 — far too high) and ŷ₂ = 0.7685 (target 0.99 — a bit low). Both need correcting, in opposite directions.

Section 02 · Forward

Total Error

Score each output with ½(T − ŷ)², then add them up:

1
EY1 = ½(0.01 − 0.7569)² = ½(−0.7469)² = 0.2793
2
EY2 = ½(0.99 − 0.7685)² = ½(0.2215)² = 0.0245
3
Etotal = 0.2793 + 0.0245 = 0.3042
0.2793Y₁ error — the big one
0.0245Y₂ error — small
0.3042Total error to minimise
📊
Y₁ dominates the loss

Y₁ is wildly off (0.76 vs 0.01), so it owns most of the error — and will drive the biggest weight changes in the backward pass.

Section 02 · Forward

Forward Pass — On the Network

Every value from the forward pass, in place:

x₁ x₂ H₁ H₂ Y₁ Y₂ x₁=0.05x₂=0.10 0.59440.5963 ŷ₁=0.7569ŷ₂=0.7685 T₁=0.01T₂=0.99
🔍
Read the gap

The distance between each ŷ (green) and its target T (red) is what backprop now works to close, weight by weight.

Section 03 · Backward

Two Chain-Rule Patterns

Every weight's gradient is a product of local derivatives. Output weights need three factors; hidden weights need four.

∂E/∂w = (ŷ − T) × ŷ(1 − ŷ) × outprev
Error signal × sigmoid slope × the activation feeding the weight.
∂E/∂w = δout × wconnect × outH(1−outH) × x
Adds the connecting weight and the hidden neuron's own sigmoid slope.
🔑
∂net/∂w is always the incoming activation

For an output weight it's the hidden activation; for a first-layer weight it's the raw input x. That single fact anchors the last term of every chain.

Section 03 · Backward

Updating w₅ — An Output Weight

w₅ connects H₁ → Y₁. Its gradient is the 3-term chain: error signal × sigmoid slope × incoming activation.

A
Error signal: ∂E/∂ŷ₁ = ŷ₁ − T₁ = 0.7569 − 0.01 = 0.7469
B
Sigmoid slope: ŷ₁(1 − ŷ₁) = 0.7569 × 0.2431 = 0.1840
C
Incoming activation: outH1 = 0.5944
Gradient: ∂E/∂w₅ = 0.7469 × 0.1840 × 0.5944 = 0.0817 → w₅new = 0.40 − 0.5(0.0817) = 0.3592
📉
Positive gradient → weight decreases

ŷ₁ was far too high, so the gradient is positive and w₅ drops from 0.40 to 0.3592 — pulling Y₁'s output down toward its target of 0.01.

Section 03 · Backward

Updating w₁ — A Hidden Weight

w₁ connects x₁ → H₁, buried one layer deeper. Following the error along the Y₁ path gives a 4-term chain:

A
Output error signal: (ŷ₁ − T₁) = 0.7469
B
Sigmoid slope at Y₁: ŷ₁(1 − ŷ₁) = 0.1840
C
Connecting weight: w₅ = 0.40
D
Input to the weight: x₁ = 0.05  →  ∂E/∂w₁ ≈ 0.7469×0.1840×0.40×0.05 = 0.00275 → w₁new ≈ 0.15 − 0.5(0.00275) = 0.1486
A complete solution sums both output paths

H₁ feeds both Y₁ and Y₂, so the full hidden gradient also adds the Y₂ path (through w₆). Here we follow the single Y₁ path the walkthrough demonstrates — the method is identical, just summed over outputs.

Section 04

Every Weight Follows the Pattern

Two solved, six to go — but each is the very same recipe with different indices. Apply, then update all at once with η = 0.5:

WeightTypeChainOld → New
w₅ (H₁→Y₁)Output3-term0.40 → 0.3592
w₆ (H₁→Y₂)Output3-termsame pattern
w₇, w₈Output3-termsame pattern
w₁ (x₁→H₁)Hidden4-term0.15 → 0.1486
w₂, w₃, w₄Hidden4-termsame pattern
⏱️
Compute all gradients from the OLD weights

Never update a weight mid-calculation. Compute every gradient using the original weights, then apply all the updates together — that's one clean training step.

Section 05

Python — Every Number Confirmed

import numpy as np
x1, x2 = 0.05, 0.10; T1, T2 = 0.01, 0.99; lr = 0.5
w5, w6, w7, w8 = 0.40, 0.45, 0.50, 0.55
sig  = lambda z: 1/(1+np.exp(-z))
sigD = lambda z: sig(z)*(1-sig(z))

# forward (net values include the bias)
net_H1, net_H2 = 0.3825, 0.390
out_H1, out_H2 = sig(net_H1), sig(net_H2)     # 0.5944, 0.5963
net_Y1 = w5*out_H1 + w7*out_H2
net_Y2 = w6*out_H1 + w8*out_H2
out_Y1, out_Y2 = sig(net_Y1), sig(net_Y2)     # 0.7569, 0.7685
E_total = 0.5*(T1-out_Y1)**2 + 0.5*(T2-out_Y2)**2  # 0.3042

# backward — w5 (3-term chain)
grad_w5 = (out_Y1 - T1) * sigD(net_Y1) * out_H1   # 0.0817
w5_new  = w5 - lr * grad_w5                        # 0.3592

# backward — w1 (4-term chain, Y1 path)
grad_w1 = (out_Y1 - T1) * sigD(net_Y1) * w5 * x1  # 0.00275
w1_new  = 0.15 - lr * grad_w1                    # 0.1486
Hand-maths and code agree

Etotal = 0.3042, ∂E/∂w₅ = 0.0817 → 0.3592, and the w₁ chain all match the paper solution.

Section 06

7 Golden Rules for Solving on Paper

  Exam-ready backprop recipe
1Forward pass first — compute net and σ(net) for every neuron, left to right.
2Loss before backprop — sum ½(Tᵢ − ŷᵢ)² over all outputs.
3Output weights use 3 terms: (ŷ − T) × ŷ(1 − ŷ) × outprev.
4Hidden weights use 4 terms — add the connecting weight and the hidden sigmoid slope (summed over all outputs the neuron feeds).
5∂net/∂w = the incoming activation — the first layer uses the raw input x.
6Update rule: wnew = wold − η · ∂E/∂w. Positive gradient lowers the weight.
7Update all weights simultaneously at the end, using the old weights for every gradient.
🚀
You can now solve any ANN by hand

Forward, error, 3-term output gradients, 4-term hidden gradients, simultaneous update. Scale the same five moves up and you have every deep network ever trained.