Multilayer Perceptrons and Backpropagation › Example

Michael BrenndoerferOctober 29, 20265 min read
Machine Learning from ScratchAll chapters
Part 7 of 15Supervised Learning Beyond Linear Models
Chapter 57Multilayer Perceptrons and Backpropagation › Example
Reading section 5 of 10 · Example · 5 minSection 5 of 10 · 5 min

Section 5 of 10 · 5 min read

Multilayer Perceptrons and Backpropagation › ExampleSection view · Sections in this chapter5 / 10 ↓
Reading tools Definitions, links & notes

Choose your expertise level to adjust how many terms are explained. Beginners see more tooltips, experts see fewer to maintain reading flow. Hover over underlined terms for instant definitions.

Article links

Make inline references clickable

Notes & comments

To make the formula concrete, we compute it by hand. The following example is deliberately tiny: two input features, two hidden units, and one binary output. Its purpose is not to be realistic but to expose every number that the code will later compute. We will carry the forward pass, the backward pass, and one gradient step by hand, so that each matrix in the implementation has a concrete scalar counterpart. Calculations retain full precision; displayed results are rounded to four decimal places.

Suppose we have two input features, two hidden units, and one binary output. Let the input be

x=[1.0−1.0],y=1.x = \begin{bmatrix}1.0\\-1.0\end{bmatrix}, \qquad y=1.

Let the hidden weights and biases be

W=[0.5−0.51.00.5],b=[0.1−0.2],\mathbf{W} = \begin{bmatrix} 0.5 & -0.5\\ 1.0 & 0.5 \end{bmatrix}, \qquad \mathbf{b}= \begin{bmatrix} 0.1\\-0.2 \end{bmatrix},

and let the output weights and bias be

v=[1.2−0.8],c=0.05.\mathbf{v}= \begin{bmatrix} 1.2\\-0.8 \end{bmatrix}, \qquad c=0.05.

We use tanh⁡\tanh in the hidden layer and sigmoid at the output.

Forward pass

We compute the hidden preactivations one unit at a time. For the first hidden unit,

z1=0.5(1.0)+(−0.5)(−1.0)+0.1=0.5+0.5+0.1=1.1.z_1 = 0.5(1.0)+(-0.5)(-1.0)+0.1 = 0.5+0.5+0.1=1.1.

Then

a1=tanh⁡(1.1)≈0.8005.a_1=\tanh(1.1)\approx 0.8005.

For the second hidden unit,

z2=1.0(1.0)+0.5(−1.0)−0.2=1.0−0.5−0.2=0.3,z_2 = 1.0(1.0)+0.5(-1.0)-0.2 = 1.0-0.5-0.2=0.3,

so

a2=tanh⁡(0.3)≈0.2913.a_2=\tanh(0.3)\approx 0.2913.

The output logit is

s=1.2a1−0.8a2+0.05≈0.7775.s = 1.2a_1-0.8a_2+0.05\approx 0.7775.

The predicted probability is

p=σ(s)=11+e−s≈0.6852.p=\sigma(s)=\frac{1}{1+e^{-s}}\approx 0.6852.

where:

  • σ\sigma: the sigmoid function mapping the logit to a probability
  • pp: the predicted probability that the example belongs to class 11

The loss is

ℓ=−log⁡(p)≈0.3781.\ell = -\log(p)\approx 0.3781.

where:

  • ℓ\ell: the binary cross-entropy loss for this single example
  • log⁡\log: the natural logarithm

Equivalently, using the stable logit form,

ℓ=logaddexp⁡(0,s)−s≈0.3781.\ell=\operatorname{logaddexp}(0,s)-s\approx 0.3781.

We can read this forward pass as a pipeline: the input is projected into two hidden numbers, each hidden number is squashed by tanh, and the two squashed numbers are combined into a logit. The predicted probability is above 0.50.5, so the network already leans toward class 11, and the observed label is 11. Since the assigned probability p≈0.6852p\approx0.6852 is below 11, its binary cross-entropy −log⁡p≈0.3781-\log p\approx0.3781 is positive.

Backward pass

We now reverse the forward pass. The output gradient is

δ=p−y≈−0.3148,\delta = p-y \approx -0.3148,

The output weight gradients are

∂ℓ∂v1=δa1≈−0.2520,\frac{\partial \ell}{\partial v_1}=\delta a_1\approx -0.2520, ∂ℓ∂v2=δa2≈−0.0917,\frac{\partial \ell}{\partial v_2}=\delta a_2\approx -0.0917,

where:

  • δ=p−y\delta = p - y: the output delta for this single example, without the 1/B1/B scaling used for a batch mean
  • a1,a2a_1, a_2: the hidden activations computed in the forward pass
  • v1,v2v_1, v_2: the output weights

and the output bias gradient is

∂ℓ∂c=δ≈−0.3148.\frac{\partial \ell}{\partial c}=\delta\approx -0.3148.

For the hidden units, we first compute

∂ℓ∂a1=δv1≈−0.3778,\frac{\partial \ell}{\partial a_1}=\delta v_1\approx -0.3778, ∂ℓ∂a2=δv2≈0.2519.\frac{\partial \ell}{\partial a_2}=\delta v_2\approx 0.2519.

The tanh derivatives are

1−a12≈0.3592,1−a22≈0.9151,1-a_1^2\approx 0.3592, \qquad 1-a_2^2\approx 0.9151,

Therefore the hidden preactivation gradients are

Δ1=δv1(1−a12)≈−0.1357,\Delta_1=\delta v_1(1-a_1^2)\approx -0.1357, Δ2=δv2(1−a22)≈0.2305.\Delta_2=\delta v_2(1-a_2^2)\approx 0.2305.

Now we can compute the weight gradients. Since z1=W11x1+W12x2+b1z_1=W_{11}x_1+W_{12}x_2+b_1,

∂ℓ∂W11=Δ1x1≈−0.1357,\frac{\partial \ell}{\partial W_{11}}=\Delta_1 x_1\approx -0.1357, ∂ℓ∂W12=Δ1x2≈0.1357.\frac{\partial \ell}{\partial W_{12}}=\Delta_1 x_2\approx 0.1357.

Similarly,

∂ℓ∂W21=Δ2x1≈0.2305,\frac{\partial \ell}{\partial W_{21}}=\Delta_2 x_1\approx 0.2305, ∂ℓ∂W22=Δ2x2≈−0.2305.\frac{\partial \ell}{\partial W_{22}}=\Delta_2 x_2\approx -0.2305.

The hidden bias gradients are simply Δ1\Delta_1 and Δ2\Delta_2:

∂ℓ∂b1≈−0.1357,∂ℓ∂b2≈0.2305.\frac{\partial \ell}{\partial b_1}\approx -0.1357, \qquad \frac{\partial \ell}{\partial b_2}\approx 0.2305.

At this point every gradient has been computed by following the chain rule one link at a time. The output delta is the derivative of the loss with respect to the logit; its sign tells us which local change in the logit would reduce the loss. Multiplying by the hidden activations tells us how to change the output weights. Multiplying the output delta by the output weights and tanh derivative gives the loss gradient with respect to each hidden preactivation. Finally, multiplying by the input tells us how to change the hidden weights.

One gradient step

Gradient descent subtracts a multiple of the gradient. With learning rate η=0.5\eta=0.5, the new first hidden weight is

W11new=W11−η∂ℓ∂W11≈0.5679.W_{11}^{\text{new}}=W_{11}-\eta\frac{\partial\ell}{\partial W_{11}}\approx 0.5679.

where:

  • W11newW_{11}^{\text{new}}: the updated hidden weight after the gradient step
  • 0.50.5: the initial value of W11W_{11}
  • 0.50.5: the learning rate η\eta
  • −0.1357-0.1357: the gradient ∂ℓ/∂W11\partial \ell/\partial W_{11}

The new first output weight is

v1new=v1−η∂ℓ∂v1≈1.3260.v_1^{\text{new}}=v_1-\eta\frac{\partial\ell}{\partial v_1}\approx 1.3260.

where:

  • v1newv_1^{\text{new}}: the updated first output weight after the gradient step
  • 1.21.2: the initial value of v1v_1
  • 0.50.5: the learning rate η\eta
  • −0.2520-0.2520: the rounded gradient ∂ℓ/∂v1\partial \ell/\partial v_1

Applying the same rule at full precision and rounding the displayed values gives

W11≈0.5679,W12≈−0.5679,W21≈0.8847,W22≈0.6153,b1≈0.1679,b2≈−0.3153,v1≈1.3260,v2≈−0.7541,c≈0.2074.\begin{aligned} W_{11}&\approx0.5679, & W_{12}&\approx-0.5679,\\ W_{21}&\approx0.8847, & W_{22}&\approx0.6153,\\ b_1&\approx0.1679, & b_2&\approx-0.3153,\\ v_1&\approx1.3260, & v_2&\approx-0.7541,\\ c&\approx0.2074. \end{aligned}

A new forward pass with these updated parameters gives z1≈1.3036z_1\approx 1.3036, a1≈0.8626a_1\approx 0.8626, z2≈−0.0458z_2\approx -0.0458, a2≈−0.0457a_2\approx -0.0457, s≈1.3858s\approx 1.3858, p≈0.7999p\approx 0.7999, and loss ≈0.2232\approx 0.2232. The loss decreased from about 0.3780.378 to about 0.2230.223, which is the expected effect of a step in the negative gradient direction. It is a small confirmation that the signs and scales in the backward pass are consistent with the goal of reducing the loss.

Comments

Add to the conversation

A question, a correction, or an example from your own work.

No comments yet. Be the first to share your thoughts!

Newsletter

Stay up to date

Get new articles, book updates, and notes on AI and technology.

Unsubscribe at any time. Privacy policy