Exercises — Implementing models from scratch
Before we start, let me pin down every symbol so nothing appears unearned.
Level 1 — Recognition
Exercise 1.1 — Name the shapes
A dense layer maps a vector of features to outputs. State the shapes of , , and (for a batch of examples) the input and output .
Recall Solution
A row of is one linear function turning inputs into output number. We have outputs, so rows, each of length : One bias per output neuron: . Batch convention (features down the rows, examples across the columns): . Then : multiplying by gives , so The bias is broadcast — copied across all columns.
Exercise 1.2 — Recall the three roles
Match each object to its job: (a) , (b) , (c) . Jobs: rotate/scale the input space · shift the output · inject non-linearity.
Recall Solution
- ::: rotates and scales the input space (a linear map).
- ::: shifts the output (moves the decision boundary without changing its tilt).
- ::: injects non-linearity so stacked layers do not collapse into one big linear layer.
Level 2 — Application
Exercise 2.1 — Compute a forward pass by hand
Let Compute , then where .
Recall Solution
Row by row — each row of dotted with : So . Both are positive, so ReLU passes them through unchanged:
Exercise 2.2 — Gradient of weights
Continuing 2.1, suppose the gradient arriving at the pre-activation is (single example, batch size ). Using , compute and .
Recall Solution
Why ? From we get . Chain rule: — the outer product of (column) with (row): Shape check: , same as ✓. For bias, , so (with batch you would sum across the batch).
Exercise 2.3 — One SGD step
Using from 2.2 and learning rate , apply .
Recall Solution
We subtract the gradient because the gradient points uphill (toward larger loss); the minus turns us downhill.
Level 3 — Analysis
Exercise 3.1 — Why does the linear model collapse?
Show that two stacked linear layers (no activation) are equivalent to a single linear layer. Give the effective weight and bias.
Recall Solution
Expand using distributivity of matrix multiplication: Define and . Then — a single affine layer. Figure below: two straight-line maps compose into one straight-line map; no bend appears anywhere.

This is exactly why exists: only a bend (non-linearity) between the layers stops this collapse and lets the network draw curved boundaries.
Exercise 3.2 — Dead ReLU
A neuron has pre-activations across three examples. The incoming gradient is . Compute the gradient flowing back through ReLU, . Which examples pass gradient?
Recall Solution
ReLU's derivative is a gate: where , else . Only the third example () passes gradient. The first two are in ReLU's flat region — no gradient, so the weights feeding them learn nothing from these examples. See the gate picture:

Edge case : by the parent's convention (the rule uses , strict). At exactly the true slope is undefined (a corner), and libraries just pick or by convention.
Level 4 — Synthesis
Exercise 4.1 — One full training step end-to-end
Single example. Layer 1: , , then ReLU. Layer 2: , . Input , target , loss . Learning rate . Do forward → backward → update .
Recall Solution
Forward.
Backward. Loss derivative: . Gradient for (using with ):
Update. Sanity: the prediction was too low ( vs target ), so we push toward larger output — both entries moved up. ✓
Exercise 4.2 — Momentum accumulation
Momentum: , update . Wait — the parent's snippet omits the scaling; use the classic form . With , , and three identical gradients , compute .
Recall Solution
Notice the velocity grows past the raw gradient of : momentum accelerates when successive gradients agree in direction. Its steady-state limit is times the constant gradient — momentum can move up to faster than plain SGD on a consistent slope.
Level 5 — Mastery
Exercise 5.1 — Batch bias gradient, all-signs case
A layer with output neurons sees a batch of examples. The incoming pre-activation gradient is Compute (sum across columns, keep shape ).
Recall Solution
Bias is shared across every example, so its total gradient is the sum of each example's contribution — sum each row:
Note we sum (not average) here; whether you divide by batch size is a convention baked into your loss — be consistent (the parent's code divides by batch_size, giving instead).
Exercise 5.2 — Learning-rate stability limit
For a 1-D quadratic loss with , the gradient is . Gradient descent gives . Find the exact range of for which , and the value of giving the fastest convergence.
Recall Solution
Each step multiplies by the factor . The sequence shrinks to iff :
- gives : converges in one step (fastest).
- : is negative, so oscillates in sign while shrinking.
- : , bounces forever, never settling.
- : , diverges — this is why too-large learning rates blow up.

Exercise 5.3 — Gradient of a whole mini-batch matmul
Prove the batched weight gradient automatically sums over the batch, where ( = batch size) and .
Recall Solution
Write the matrix product entry-wise. The entry of is: Read this: for weight , we take example 's incoming gradient times that example's input feature , and sum over all examples. The single matrix multiply is the batch sum — no explicit loop needed. That is the whole reason vectorised backprop is fast. (Dividing this by turns the sum into the mean gradient, matching the parent's code.)
Recall Self-test roundup
Fastest 1-D learning rate for ? ::: (converges in one step). Backward derivative of ReLU at ? ::: (dead: input was in the flat region). Why subtract the gradient in the update? ::: the gradient points uphill; subtracting moves us downhill toward lower loss. Effective weight of two stacked linear layers ? ::: (they collapse into one).
Related: 6.3.04-Optimization-Algorithms · 6.4.01-PyTorch-Basics · 6.5.01-Reading-Research-Papers