Worked examples — Implementing models from scratch
This page pushes on the machinery from the parent note: the forward pass (), the backward pass (chain rule → gradients), and the update (). Instead of new theory, we drill every case a single dense layer can throw at you: positive and negative activations, dead neurons, zero gradients, a full batch, and the exam-style "predict the shape" twist.
Before the first line, three plain-word reminders so nobody is lost:
One more operation earns its keep on every single forward pass, so we define it now:
Everything below is a single layer computing , sometimes followed by ReLU. We will hand-crank the arithmetic — no PyTorch.
The scenario matrix
Here is every distinct kind of situation this topic can hand you. Each worked example below is tagged with the cell it fills.
| # | Case class | What makes it different | Example |
|---|---|---|---|
| A | Single sample, all positive | baseline forward, no sign trouble | Ex 1 |
| B | Single sample, some negatives | one negative pre-activation feeds ReLU | Ex 2 |
| C | Zero / degenerate input | input is the zero vector | Ex 3 |
| D | Dead neuron (zero gradient) | ReLU gate blocks the gradient | Ex 4 |
| E | Full mini-batch forward | broadcasting bias across columns | Ex 5 |
| F | Backward: weight gradient | , sum over batch | Ex 6 |
| G | Backward: bias gradient | sum across batch dimension | Ex 6 |
| H | One SGD step (real-world word problem) | numbers actually move downhill | Ex 7 |
| I | Limiting value (learning rate too big) | update overshoots, loss rises | Ex 8 |
| J | Exam twist: shape-only reasoning | no numbers, just dimensions | Ex 9 |
| K | All neurons dead | every pre-activation | Ex 10 |
Recall Which cells involve NO calculus at all?
Cases A, B, C, E, J, K ::: they are pure forward-pass or shape bookkeeping — matrix multiply plus a max, or just counting dimensions.
Setup used by all numeric examples
To keep arithmetic checkable by hand we fix a tiny layer: 2 inputs → 2 outputs.
Read row by row: neuron 1 computes , neuron 2 computes . The bias then shifts each: for neuron 1, for neuron 2.
The wiring diagram below makes this concrete: two purple input nodes on the left send weighted wires (orange for neuron 1, teal for neuron 2) into the two output neurons. Notice the dotted grey wire labelled — that is the in the first column of row 2, meaning neuron 2 completely ignores . Trace the orange wires and you can read off neuron 1's formula; trace the teal ones for neuron 2. Keep this picture in mind for every forward pass below.

Case A — single sample, all positive
Case B — single sample, some negatives
Case C — zero / degenerate input
Case D — the dead neuron (zero gradient)
To do backprop we need a loss. Use the simplest: suppose the next layer sent back the gradient of the loss with respect to the activations, ReLU then decides which of these gradients survive. Recall (from the parent, and 6.2.03-Backpropagation-Algorithm): where is if true, if false — the ReLU gate.
? Look at ReLU near zero: to the left the slope is , to the right it is . At the single point the function has a corner, so it has no unique slope — the true mathematical derivative does not exist there. In practice we simply pick one value, and the universal convention (used by every framework) is to send the gate to at , which is why the rule is written with the strict inequality (so falls into the "off" branch). Why choose and not ? Because a neuron sitting exactly at produced output in the forward pass — it contributed nothing — so it is honest to let it also contribute no gradient. The choice is harmless anyway: hitting exactly is a measure-zero fluke, and either choice ( or ) gives a valid subgradient. This is exactly why Ex 2/Ex 4 treat as gate .
Before we compute, one piece of notation we will lean on:
The symbol ==== (say "circle-dot", also called the Hadamard product) means: take two lists of the same shape and multiply them slot by slot, keeping the shape. So . This is not matrix multiplication and not the dot product — nothing sums across slots, each entry stays in its own lane. Picture two identical grids laid on top of each other, multiplying the numbers that overlap.
The figure below shows why a gate of or is exactly the right thing to with the incoming gradient. The orange curve is ReLU itself; the dashed teal curve is its slope — flat at for negative inputs, flat at for positive inputs, with the corner at the origin marked. The two purple markers sit at our example pre-activations (slope , gradient blocked) and (slope , gradient passes). Read the dashed line under each marker to see whether that neuron's gradient survives.

Use the pre-activations from Ex 2: , incoming . Find .
Forecast: one of these two gradient numbers will be killed. Which?
- Build the gate mask: gate ; gate . Mask . Why? ReLU's slope is where its input was negative and where positive — the mask is the derivative (with the corner sent to as discussed).
- Multiply element-wise: . Why and not matrix multiply? Each neuron's gate touches only its own gradient — no mixing across neurons — so it is pointwise, exactly what means.
Verify: neuron 1 output in the forward pass, so nudging its weights can't change — its gradient must be , and it is. . ✓ This is the famous dead-neuron effect.
Case E — a full mini-batch forward
Now feed three samples at once, stacked as columns of :
Compute for the whole batch.
Forecast: you already did the three columns individually — can you assemble them?
- column by column: each column is an independent matrix–vector product. From Ex 1/2/3: columns of are , , . Why columns? A batch matmul is just the same layer applied to each sample — nothing couples the samples.
- Add the bias to every column (broadcasting): is added to all three. Why broadcast? The layer's bias is shared by all samples — the same shift applies everywhere.
Verify: column 1 is = Ex 1's ✓, column 2 is = Ex 2 ✓, column 3 is = Ex 3 ✓. Shape is = (neurons × samples). ✓
Cases F & G — weight and bias gradients over the batch
Suppose the upstream gradient at this layer's pre-activations is The parent gives and .
and the bias sum (cells F & G) Forecast: must come out the same shape as , i.e. . must be .
- Transpose : (samples become rows). Why transpose? We need to line up "for each neuron's error, multiply by the input feature that caused it," and the transpose makes the inner dimensions ( samples) match so they sum away.
- Multiply : the shared collapses, summing each sample's contribution.
- Row 1: columns of : .
- Row 2: : .
- Bias = sum each row of across samples: . Why sum? The bias is reused for all samples, so its total sensitivity is the running total of the per-sample sensitivities. See 3.1.04-Chain-Rule.
Verify: is (matches ) ✓, is (matches ) ✓. Shapes are the acid test that the transposes are correct.
Case H — one real gradient-descent step (word problem)
Story: A single weight predicts room temperature. Current . On this batch the loss gradient is (loss rises when rises). Learning rate . Take one SGD step (see 6.3.04-Optimization-Algorithms).
Forecast: the gradient is positive — will go up or down?
- Apply the rule : . Why subtract? The gradient points in the direction that increases the loss (a positive slope means "loss climbs as climbs"). To decrease the loss we must walk the opposite way — so we subtract the gradient rather than add it. That single minus sign is the whole idea of gradient descent: always step downhill on the loss surface, and downhill is the negative-gradient direction.
- Check the loss actually dropped (local, first-order): the predicted change is . Why this check? The parent's Taylor argument says loss should fall by about — a negative confirms we chose the right direction and a small enough step.
Verify: new (moved down, correct direction) and predicted matches . ✓
Case I — limiting value: learning rate too big
Same subtraction rule as Ex 7 but with a giant , and suppose the true loss is the bowl , so . Start .
Forecast: the minimum is at . Will one big step land near it, or fly past?
- Gradient at : . Why? Slope of the bowl at is steep and positive.
- Step: . Why did we overshoot? We wanted to reach , needed to drop by , but dropped us by — twice too far.
- Loss before vs after: , . Why equal? We landed the exact mirror distance on the other wall of the bowl.
Verify: loss did not decrease (); with this large gradient descent stalls or diverges. Contrast Ex 7 where a small made progress. went , stayed . ✓
For the bowl , a step shrinks the distance to only when ; at you bounce forever; above you spiral outward. This is why picking is half the battle.
Case J — exam twist: reason with shapes only
Statement: A layer maps and processes a batch of samples with the columns-as-samples convention. Give the shapes of , , , , and both gradients and .
Forecast: write the six shapes down before reading — a smart exam trick is that every gradient copies the shape of the thing it differentiates.
- is (out × in) . Why? Each of the output neurons owns a full row of weights, one per input feature.
- is (in × batch) , and is . Why? The shared inner dimension collapses in the matrix product, leaving (neurons × samples).
- is , broadcast across all columns. Why? One bias per output neuron, reused for every sample.
- is — identical to . Why must it match? During the update you compute ; subtraction demands equal shapes.
- is — identical to , ready to hand back to the previous layer.
Verify: each gradient matches the shape of the quantity it differentiates. , , , , , . ✓
Case K — every neuron dead
Same . Input . Compute , , and then the pre-activation gradient if the incoming gradient is .
Forecast: with these inputs, could both neurons go dark at once?
- Row 1: ; add bias . Why watch this one? It lands exactly on the corner — the case we discussed above.
- Row 2: ; add bias . Wait — that is positive. Adjust the input to make the story honest: retry with . Row 1: , (positive). Neither simple input kills both, so choose : Row 1: , ; Row 2: , . Now . Why hunt for it? We deliberately want a case where both pre-activations are to complete the taxonomy.
- ReLU: , . Why? Every pre-activation is negative, so ReLU clamps them all — the layer emits pure zeros.
- Gate the gradient: both mask , so . Why does this matter? Nothing flows backward — this layer learns nothing on this sample, the worst-case degenerate state.
Verify: with , (both ), , and . A completely dead layer: zero output, zero gradient. ✓
Recall checkpoint
Recall Why does the zero input NOT give zero output?
Because the layer is affine, not linear — the bias is added after , so zero input yields . ::: (Ex 3)
Recall In backprop, why is the ReLU gate applied with
rather than matrix multiply? Each neuron's gate affects only its own gradient — there is no mixing across neurons — so it is a pointwise (element-wise) operation. ::: (Ex 4)
Recall What does ReLU's gradient do exactly at z = 0, and why?
The derivative does not truly exist at the corner; by convention we send the gate to 0 (the strict-inequality branch) because a neuron sitting at 0 output contributed nothing forward, so it fairly contributes nothing backward. ::: (Ex 4, Ex 10)
Recall What single check tells you your transposes in
and are right? The gradient must have the same shape as the quantity it differentiates ( like , like ). ::: (Ex 6, Ex 9)
Down = subtract the gradient (Ex 7). Small = keep below the overshoot threshold (Ex 8).
See also 6.4.01-PyTorch-Basics for how these hand-cranked steps become one loss.backward() call, and 6.5.01-Reading-Research-Papers for turning a paper's equations into exactly this kind of worked layer.