Simplified teaching network, fixed by hand so every number is checkable: W1 = [[0.5, −0.25], [0.25, 0.5]], b1 = [0.1, −0.1], W2 = [0.6, −0.4], b2 = 0.2, input x = [1.0, 0.5], target y = 1.0.
FORWARD
z1 = [0.5×1.0 − 0.25×0.5 + 0.1, 0.25×1.0 + 0.5×0.5 − 0.1]
= [0.475, 0.400]
a1 = σ([0.475, 0.400]) = [0.616567, 0.598688]
z2 = 0.6×0.616567 − 0.4×0.598688 + 0.2 = 0.330465
a2 = σ(0.330465) = 0.581872
L = (0.581872 − 1)² = 0.174831
BACKWARD
dL/da2 = 2 × (−0.418128) = −0.836255
a2(1 − a2) = 0.243297
dL/dz2 = −0.836255 × 0.243297 = −0.203458
dL/dW2 = −0.203458 × [0.616567, 0.598688]
= [−0.125446, −0.121808] dL/db2 = −0.203458
dL/da1 = −0.203458 × [0.6, −0.4] = [−0.122075, +0.081383]
a1(1 − a1) = [0.236412, 0.240261]
dL/dz1 = [−0.122075 × 0.236412, 0.081383 × 0.240261]
= [−0.028860, +0.019553]
dL/dW1 = dL/dz1 × xᵀ = [[−0.028860, −0.014430],
[+0.019553, +0.009777]]
dL/db1 = dL/dz1 = [−0.028860, +0.019553]
NUMERIC SPOT CHECK (centered difference, h = 10⁻⁵)
W2[0]: backprop −0.125446 numeric −0.125446 diff 1.1×10⁻¹²
b2: backprop −0.203458 numeric −0.203458 diff 5.0×10⁻¹⁴
Follow one number end to end: the output unit’s error rate −0.203458 becomes each output weight’s gradient by multiplying by the hidden activation that fed it — a bigger activation fed more of the error, so it earns a bigger gradient. Then the same error rate rides back through the output weights to reach the hidden units, gets multiplied by each hidden sigmoid’s local derivative, and finally becomes each input weight’s gradient by multiplying by the input value. Nothing new was invented; the chain just got longer.