Coding Hubs School of AI – Best AI & Full Stack Courses in Delhi NCR | 100% Placement
Limited Offer: Get 50% OFF on AI & Full Stack Courses
📞 Call Now: +91 8448811540
Back to Deep Learning Notes
Topic #305

Backpropagation Worked Example

This note ties every piece of this category together into one complete, fully numerical example: a small but genuine multi-layer network, one full forward pass, one full backward pass computing every gradient by hand, and a weight update — verified against PyTorch's autograd at the end.

The Network

A 2-input, 2-hidden-neuron, 1-output network, sigmoid activations throughout, trained with squared error loss:

\[ \mathbf{x} = [0.5, 0.8], \quad y_{\text{true}} = 1 \] \[ \mathbf{W}^{(1)} = \begin{bmatrix}0.1 & 0.3\\0.2 & 0.4\end{bmatrix}, \quad \mathbf{b}^{(1)}=[0,0], \qquad \mathbf{W}^{(2)}=[0.5, 0.6], \quad b^{(2)}=0 \]

Step 1 — Forward Pass

\[ \mathbf{z}^{(1)} = \mathbf{W}^{(1)}\mathbf{x}+\mathbf{b}^{(1)} = \begin{bmatrix}0.1(0.5)+0.3(0.8)\\0.2(0.5)+0.4(0.8)\end{bmatrix} = \begin{bmatrix}0.29\\0.42\end{bmatrix} \] \[ \mathbf{a}^{(1)} = \sigma(\mathbf{z}^{(1)}) = [\sigma(0.29), \sigma(0.42)] \approx [0.5720, 0.6034] \] \[ z^{(2)} = \mathbf{W}^{(2)}\cdot\mathbf{a}^{(1)}+b^{(2)} = 0.5(0.5720)+0.6(0.6034) \approx 0.6480 \] \[ \hat y = \sigma(z^{(2)}) \approx \sigma(0.6480) \approx 0.6566 \]

Step 2 — Loss

\[ L = (y_{\text{true}} - \hat y)^2 = (1-0.6566)^2 \approx 0.1179 \]

Step 3 — Backward Pass: Output Layer's Error Signal

\[ \frac{\partial L}{\partial \hat y} = -2(y_{\text{true}}-\hat y) = -2(0.3434) \approx -0.6868 \] \[ \delta^{(2)} = \frac{\partial L}{\partial \hat y}\cdot\sigma'(z^{(2)}) = -0.6868 \times \hat y(1-\hat y) = -0.6868 \times 0.6566(0.3434) \approx -0.1548 \]

Step 4 — Backward Pass: Hidden Layer's Error Signal

\[ \boldsymbol\delta^{(1)} = \big(\mathbf{W}^{(2)}\big)^\top\delta^{(2)} \odot \sigma'(\mathbf{z}^{(1)}) \] \[ \big(\mathbf{W}^{(2)}\big)^\top\delta^{(2)} = [0.5, 0.6]\times(-0.1548) = [-0.0774, -0.0929] \] \[ \sigma'(\mathbf{z}^{(1)}) = [0.5720(0.4280), 0.6034(0.3966)] \approx [0.2448, 0.2393] \] \[ \boldsymbol\delta^{(1)} \approx [-0.0774(0.2448),\ -0.0929(0.2393)] \approx [-0.0189, -0.0222] \]

Step 5 — Gradient Calculation

\[ \frac{\partial L}{\partial \mathbf{W}^{(2)}} = \delta^{(2)}\cdot(\mathbf{a}^{(1)})^\top \approx -0.1548\times[0.5720, 0.6034] \approx [-0.0886, -0.0934] \] \[ \frac{\partial L}{\partial \mathbf{W}^{(1)}} = \boldsymbol\delta^{(1)}\mathbf{x}^\top \approx \begin{bmatrix}-0.0189\\-0.0222\end{bmatrix}[0.5,\ 0.8] \approx \begin{bmatrix}-0.0095 & -0.0151\\-0.0111 & -0.0178\end{bmatrix} \]

Step 6 — Weight Update (\(\eta=0.5\), for a visible change)

\[ \mathbf{W}^{(2)}_{\text{new}} \approx [0.5, 0.6] - 0.5[-0.0886,-0.0934] \approx [0.5443, 0.6467] \]

The output layer's weights both increased slightly — correct, since the network under-predicted (\(\hat y=0.657 < y_{\text{true}}=1\)) and increasing these weights pushes \(\hat y\) higher.

Verifying Every Number with PyTorch Autograd

import torch

x = torch.tensor([0.5, 0.8])
y_true = torch.tensor(1.0)
W1 = torch.tensor([[0.1, 0.3], [0.2, 0.4]], requires_grad=True)
b1 = torch.tensor([0.0, 0.0], requires_grad=True)
W2 = torch.tensor([0.5, 0.6], requires_grad=True)
b2 = torch.tensor(0.0, requires_grad=True)

z1 = W1 @ x + b1
a1 = torch.sigmoid(z1)
z2 = W2 @ a1 + b2
y_pred = torch.sigmoid(z2)
loss = (y_true - y_pred) ** 2

loss.backward()
print("y_pred:", y_pred.item())        # matches 0.6566 above
print("loss:", loss.item())              # matches 0.1179 above
print("dL/dW2:", W2.grad)                 # matches [-0.0886, -0.0934] above
print("dL/dW1:", W1.grad)                 # matches the W1 gradient matrix above

Common Mistakes

  • Losing track of which cached forward-pass values (\(\mathbf{a}^{(1)}\), \(\mathbf{z}^{(1)}\), \(\mathbf{z}^{(2)}\)) feed into which backward-pass formula — working through a full example like this one, step by step, is the most reliable way to build the habit of tracking them correctly.
  • Forgetting the sigmoid derivative's convenient form, \(\sigma'(z)=\sigma(z)(1-\sigma(z))\), and instead re-deriving it from scratch each time — reusing the cached activation value directly is both simpler and exactly what an efficient implementation does.

Interview Relevance

Q: "Walk through backpropagation for a small 2-layer network with real numbers." This exact worked example is the kind of answer that demonstrates genuine understanding rather than memorized formulas — being able to compute a forward pass, derive both layers' error signals via the chain rule, compute the resulting weight gradients via the outer product formula, and apply an update, all with concrete numbers, is a strong signal of true comprehension.

Practice Question

Using the same network and the newly computed gradient for \(\mathbf{W}^{(1)}\), compute the updated \(\mathbf{W}^{(1)}\) with \(\eta=0.5\).

Related DL Notes

Want to go beyond the notes?

Join Coding Hubs School of AI's Deep Learning course — live mentorship, real projects, and 100% placement support.

Enroll Now — Free Demo Available
💬 Talk to Advisor
1
WhatsApp

Latest from Our Blog

Insights on AI, Data Science, Full Stack & Career

View All Articles →