EVERYTHING AIAI engineering, made visual
0/13 complete
LESSON 04 · DEEP LEARNING × AI · BUILD

Squash it, or
let it through.

Every layer ends with one fixed curve and no weights of its own. The curve’s shape decides what the layer can express; its slope decides whether learning survives the trip backward. This is how depth became trainable — and why some units go dark forever.

45 MIN · 8 CHAPTERSPREREQ · PHASE 3 · LESSON 03
FIG. 04 / THE FIXED CURVES AND THEIR SLOPES
sigmoid tanh relu gelu
LESSON 04TYPE · BUILD~45 MINPREREQ · PHASE 3 · LESSONS 01–03ORIGINAL LESSON ↗
01 / NO GATE, NO DEPTH

Stack linear layers and you get one linear layer.

y = W₂(W₁x + b₁) + b₂ collapses to (W₂W₁)x + (W₂b₁ + b₂) — one matrix, one bias. A hundred linear layers have exactly the expressive power of one. The fixed nonlinear curve between layers is what makes depth mean something.

depth without nonlinearity is a lie
02 / FOUR SHAPES, FOUR CONTRACTS

Bounded, centered, clipped, or smooth.

Sigmoid maps to (0, 1) with derivative peaking at 0.25. Tanh maps to (−1, 1) with derivative peaking at 1. ReLU clips negatives and passes positives, derivative exactly 0 or 1. GELU is smooth, dips to ≈ −0.17, and never reads exactly zero. The shape decides forward expressiveness; the derivative decides backward learning.

max f′ — sigmoid 0.25 · tanh 1 · ReLU 0/1 · GELU ≈ 1.1
03 / THE EXIT GATE MATCHES THE ANSWER

Sigmoid for two classes, softmax for many, nothing for numbers.

Output layers report an answer, so the gate must match its shape: one probability (sigmoid), a distribution summing to 1 (softmax), or the unbounded real line (no gate). And the gate's derivative decides failure modes — sigmoid's 0.25 vanishes with depth, ReLU's hard zero kills units, softmax never belongs in a hidden layer.

report probabilities · learn from slopes
MENTAL MODEL IN ONE SENTENCE

An activation is a fixed door between learned rooms: it has no weights of its own, but its shape decides what can pass forward and its slope decides how much learning signal can come back — and the whole modern toolkit of activations is a negotiation between those two jobs.

By the end you will be able to compute every gate’s value and derivative by hand; prove that a stack of linear layers collapses to one matrix; explain saturation, vanishing gradients and dead ReLUs with numbers; implement stable softmax and say why it lives only at the output; and choose a defensible default for any layer in a network — then justify it with a measurement, not a preference.

WHY NONLINEARITY IS NECESSARY

Stack all you like.
It is still one line.

A linear layer is a matrix multiply plus a shift. Compose two of them and you get one matrix multiply plus one shift. Without a nonlinear gate in between, depth has no representational power to add — it just changes the numbers in the one matrix you already had.

Here is the entire argument in three lines. A layer computes h = W₁x + b₁. A second layer computes y = W₂h + b₂. Substitute the first into the second:

y = W₂(W₁x + b₁) + b₂ = (W₂W₁)x + (W₂b₁ + b₂) = Ax + c

That is one linear layer wearing two layers’ clothing. The same substitution works for five layers, fifty, a hundred — the product of all the matrices is still a matrix, so every deep linear stack is exactly one affine map. The parameters were never what gave depth its power; the missing ingredient is a nonlinearity between the layers.

Insert a gate g after the first layer and the algebra breaks: W₂·g(W₁x + b₁) + b₂ cannot be rewritten as a single matrix, because g bends the space before the second matrix touches it. Each gate adds bends; stacked gates compose those bends into ever-richer piecewise shapes. That is why a network with ReLUs can draw an XOR boundary or wrap itself around a spiral, and a network of pure matrix multiplies cannot — no matter how deep you make it.

Worked check: two layers collapse into one, with numbers

Take W₁ = [[1, 2], [0, 1]], b₁ = [0.5, −0.5], W₂ = [[2, 0], [1, 3]], b₂ = [1, 1], and feed the input x = (1, 1).

layer by layer h = W₁x + b₁ = [1·1 + 2·1 + 0.5, 0·1 + 1·1 − 0.5] = [3.5, 0.5] y = W₂h + b₂ = [2·3.5 + 0 + 1, 3.5 + 3·0.5 + 1] = [8, 6] collapsed into one layer A = W₂W₁ = [[2·1 + 0·0, 2·2 + 0·1], [1·1 + 3·0, 1·2 + 3·1]] = [[2, 4], [1, 5]] c = W₂b₁ + b₂ = [1 − 0 + 1, 0.5 − 1.5 + 1] = [2, 0] y = Ax + c = [2·1 + 4·1 + 2, 1·1 + 5·1 + 0] = [8, 6] ✓ same output, one matrix, half the parameters doing anything

The collapse lab below runs the same test on a random stack: drag the depth from 2 to 8 and the readout’s difference stays at zero because the layer-by-layer result and A·x + c are the same arithmetic rearranged. Now add a ReLU after every layer and the green curve bends — those bends are the capacity.

Depth without gates is one line

Grey is the whole stack with no activation — mathematically identical to a single layer y = A·x + c. Green is the same weights with a ReLU after every layer. Raise the depth and watch the bends multiply; the straight line can never follow.

depth 5 · seed 24 w = [1.400, 1.329, 0.998, 0.600, 1.089] b = [0.300, -0.569, -0.235, -0.270, -0.249] collapsed single layer A = Πw = 1.212772 c = w·c + b, layer by layer = -0.807672 numeric check at x = 0.80 layer-by-layer stack 0.162545058 A·x + c 0.162545058 difference 5.6e-17 same stack with ReLU output at x 0.162545 bends in view 5 at x = -0.21, 0.09, 0.22, 0.46, 0.67

The check never fails: a product of matrices is a matrix, so the difference is exactly zero in real arithmetic. Depth buys representational power only when a nonlinear gate sits between the layers.

Quick check

A colleague reports that their 40-layer network with no activations still trains fine. They conclude depth helps. What actually happened?

THE ORIGINAL THREE

Squash it, center it,
or just let it through.

Every neural network block is h = g(Wx + b), where g is one fixed scalar function applied to every number. Three gates from three eras — and the derivative below each one is what backpropagation actually multiplies.

The gate has no weights of its own — it is a fixed shape, applied elementwise after the layer’s weighted sum z = Wx + b. The network learns where to feed each gate; the shape itself is chosen by you. That shape matters twice: forward, it decides what kinds of functions the layer can represent; backward, its derivative decides how much learning signal survives the trip through it.

Sigmoid squashes any real number into (0, 1), which is why it looks like a probability. Its derivative is beautifully simple, and fatally capped:

sigmoid(x) = 1 / (1 + e^(−x)) range (0, 1) sigmoid′(x) = sigmoid(x) · (1 − sigmoid(x)) sigmoid(0) = 0.5000 sigmoid′(0) = 0.2500 ← the ceiling sigmoid(2) = 0.8808 sigmoid′(2) = 0.1050 sigmoid(−2) = 0.1192 sigmoid′(−2) = 0.1050

No sigmoid output is ever negative, which sounds harmless and is not: when every input to a weight is positive, every weight in that layer receives an update of the same sign, so the parameter vector moves diagonally and corrections zig-zag instead of going straight. Zero-centering fixes that — which is exactly what tanh is for.

Tanh is sigmoid re-centered at the origin: same S-shape, outputs in (−1, 1), inputs of both signs possible. Its derivative is also simple and reaches a full 1.0 at x = 0.

tanh(x) = (eˣ − e⁻ˣ) / (eˣ + e⁻ˣ) range (−1, 1) tanh′(x) = 1 − tanh(x)² tanh(0) = 0.0000 tanh′(0) = 1.0000 ← the peak tanh(2) = 0.9640 tanh′(2) = 0.0707 ← already saturating tanh(−2) = −0.9640 tanh′(−2) = 0.0707

ReLU — the rectified linear unit — does nothing at all for positive inputs and nothing but zero for negative ones. That triviality is the breakthrough: on the positive side the derivative is exactly 1, so the gradient passes through a layer untouched.

relu(x) = max(0, x) range [0, ∞) relu′(x) = 1 if x > 0, 0 if x ≤ 0 relu(−2) = 0.0000 relu′(−2) = 0.0000 relu(0) = 0.0000 relu′(0) = 0.0000 (defined as 0 here) relu(2) = 2.0000 relu′(2) = 1.0000 ← full passthrough

ReLU’s hard zero is both its superpower and its flaw: gradient 1.0 on the positive side is why deep networks became trainable after 2010, and gradient exactly 0 on the negative side is why a unit can die permanently — the subject of chapter 5.

The original three, side by side. “Saturates” marks the regions where the derivative collapses toward zero.
GateForwardRangeDerivativeZero-centeredSaturates
Sigmoid1 / (1 + e⁻ˣ)(0, 1)σ·(1 − σ) — max 0.25 at 0noboth tails
Tanh(eˣ − e⁻ˣ) / (eˣ + e⁻ˣ)(−1, 1)1 − t² — max 1.0 at 0yesboth tails
ReLUmax(0, x)[0, ∞)1 if x > 0 else 0nothe whole negative half

Plot the gate and its slope

Pick an activation, then drag x. The solid line is the function; the orange dashed line is its derivative — the factor backpropagation multiplies through. The red strip below marks the flat tails where that factor collapses toward zero.

Sigmoid f(x) = 1 / (1 + e^(−x)) range (0, 1) f′(x) = s·(1 − s), max 0.25 at x = 0 at x = 0.80 (slider) f(x) = 0.689974 f′(x) = 0.213910 flat tails below |f′| = 0.05 negative side: |x| > 2.89 positive side: |x| > 2.89 reference points x = −2 f = 0.1192 f′ = 0.1050 x = 0 f = 0.5000 f′ = 0.2500 x = 2 f = 0.8808 f′ = 0.1050

The historical squasher. All-positive outputs and a derivative capped at 0.25 make deep stacks untrainable.

Worked check: the three gates at z = −2, 0, 2

Take one neuron whose pre-activation z — the weighted sum before the gate — is −2, then 0, then 2. Here is the full forward number and the backward factor each gate contributes:

z = −2 f(z) f′(z) sigmoid 0.1192 0.1050 small output, small gradient tanh −0.9640 0.0707 saturated; nearly no gradient relu 0.0000 0.0000 off; gradient exactly zero z = 0 f(z) f′(z) sigmoid 0.5000 0.2500 the derivative's maximum tanh 0.0000 1.0000 the derivative's maximum relu 0.0000 0.0000 still off (ReLU passes nothing at 0) z = 2 f(z) f′(z) sigmoid 0.8808 0.1050 saturated output, weak gradient tanh 0.9640 0.0707 saturated output, weaker gradient relu 2.0000 1.0000 identity; gradient untouched

Read the middle column of each block as “what the next layer sees” and the right column as “what backprop gets to multiply.” Sigmoid never exceeds 0.25; tanh can reach 1.0 but pays for it with fast saturation on both sides; ReLU is a perfect 1.0 punctured by a perfect 0.0.

THE MODERN GATES: LEAKY, GELU, SWISH

The smooth gates
that trained the transformers.

ReLU’s two flaws are its hard zero and its hard corner. Leaky ReLU files the corner, GELU smooths it away, and Swish was found by a search algorithm rather than a human — all three keep a gradient alive where ReLU turns everything off.

Leaky ReLU is the smallest possible repair to the dead-neuron problem: instead of clamping the negative side to zero, give it a whisper of a slope. With α = 0.01, a negative input is scaled to one percent of itself instead of being erased.

leaky(x) = x if x > 0 else 0.01 · x leaky′(x) = 1 if x > 0 else 0.01 leaky(−2) = −0.0200 leaky′(−2) = 0.0100 ← nonzero, so learning continues leaky(2) = 2.0000 leaky′(2) = 1.0000

A whisper is enough for a neuron to keep moving and eventually climb out, but it is still not centered, still not smooth, and it adds a hyperparameter. Modern practice mostly skips it: GELU solves the same problem with a better gradient and no new knob.

GELU — the Gaussian Error Linear Unit — weights each input by how likely it is to be positive under a standard normal distribution. Φ(x) is that probability (the normal CDF), and the gate is a simple product:

gelu(x) = x · Φ(x) Φ = P(Gaussian ≤ x), range ≈ (−0.17, ∞) gelu′(x) = Φ(x) + x · φ(x) φ = the normal density in practice everyone uses the tanh approximation: gelu(x) ≈ 0.5 · x · (1 + tanh(√(2/π) · (x + 0.044715 · x³))) gelu(−2) = −0.0454 gelu′(−2) = −0.0852 gelu(2) = 1.9546 gelu′(2) = 1.0852 minimum ≈ −0.17 at x ≈ −0.75 · derivative dip ≈ −0.128 at x = −√2

Two numbers carry the whole idea. GELU(−2) is negative — small, −0.045 — so a unit can sit below zero and still matter, unlike ReLU’s hard clip. And GELU′(−2) is −0.085: a small but real gradient pointing back, where ReLU would pass exactly zero. The gate is smooth everywhere, so a stuck unit always has a slope to follow home. That is why BERT, GPT and most transformers use GELU in their feed-forward blocks.

Swish (also called SiLU) is GELU’s near-twin, discovered in 2017 by a search algorithm combing through activation space — a network designing part of a network. It gates x with the sigmoid instead of the Gaussian CDF:

swish(x) = x · sigmoid(x) swish′(x) = sigmoid(x) + x · sigmoid(x) · (1 − sigmoid(x)) swish(−2) = −0.2384 swish′(−2) = −0.0908 swish(2) = 1.7616 swish′(2) = 1.0908

In practice Swish and GELU perform almost identically; Swish shows up in EfficientNet-style vision models, GELU dominates in language models. The lesson is not which one wins — it is that both share the property that matters: smooth, slightly negative, never exactly zero.

Where gradients die: a dead-zone scan

Sweep the input range and count how often each derivative drops below the threshold. The curves at the top show why the bars below differ: ReLU zeroes an entire half-line, while GELU and Swish keep a small but nonzero slope almost everywhere.

range ±5 · 241 points · near-zero = |f′(x)| < 0.010 dead-zone fraction Sigmoid 8.3% (20/241) Tanh 40.7% (98/241) ReLU 50.2% (121/241) Leaky ReLU 0.0% (0/241) GELU 19.9% (48/241) Swish / SiLU 0.8% (2/241) why the numbers differ ReLU: 0 gradient on the whole negative half tanh: saturates faster than sigmoid despite a bigger peak slope sigmoid: derivative capped at 0.25, flat only in the far tails leaky: its 0.01 slope sits right on a 0.01 threshold — drop the threshold below 0.01 and the negative side clears gelu: a shallow negative dip (min −0.128) stays above 0.05 swish: nearly no dead zone inside ±6

ReLU’s 50% is the entire negative half of this artificial symmetric range — not a claim that half of your neurons are dead. On real data pre-activations lean positive, which is exactly why the scan is a teaching picture, not a diagnosis.

Worked check: the dead-zone scan across all six gates

Scan 241 evenly spaced inputs from −5 to 5 and count how often|f′| drops below 0.01 — the source’s exact experiment, made interactive above:

dead-zone fraction over [−5, 5], threshold |f′| < 0.01 sigmoid 8.3% flat only in the far tails (|x| > 4.6) tanh 40.7% saturates sooner (|x| > 3.0) relu 50.2% the entire negative half leaky 0.0% negative slope 0.01 — exactly on the threshold gelu 19.9% smooth decay on the negative side swish 0.8% nearly nothing dead inside ±5 same scan at threshold 0.05 sigmoid 42.3% · tanh 56.4% · relu 50.2% leaky 50.2% · gelu 29.0% · swish 14.5%

Two surprises worth keeping. First, tanh has a larger flat zone than sigmoid even though its peak derivative is four times bigger: it races to ±1 in each direction and then sits there. Second, Leaky ReLU’s 0.01 slope lands exactly on the boundary — with a 0.01 threshold it counts as alive, but raise the bar and its whole negative half turns red. A small slope is a rescue rope, not a guarantee.

SATURATION & VANISHING

The flat tails
steal the learning.

An activation’s forward shape decides what a layer can express; its derivative decides whether the layer learns at all. Wherever the curve flattens, the local derivative approaches zero — and backprop multiplies by that number at every layer.

Look back at the curves in chapter 02 and read the slopes instead of the outputs. Sigmoid and tanh are flat at both ends: push the input to −8 and the output barely moves, so the derivative is a few ten-thousandths. That region is called saturation, and a unit sitting there is not broken — it still computes a clean forward value. It simply has no slope to learn with. ReLU has the opposite shape: perfect slope 1 on the entire positive side, and a hard zero on the entire negative side. Neither failure is visible in the forward pass; both are written in the derivative.

Depth turns a small per-layer factor into an exponential one. Ten sigmoid layers multiply the backward signal by at most 0.25¹⁰ ≈ 9.5 × 10⁻⁷; the first layer receives roughly a millionth of the output’s gradient while the last layers train normally. The network does not error — it quietly becomes a shallow network with a large attached constant.

Ten layers of multiplication

One number moves forward through seeded layers, then the gradient walks back multiplying by f′(z) at every stop. Pick a gate and watch what ten — or thirty — multiplications do. Bold is the selected activation; the faint lines are the rest of the family under the same weights.

Sigmoid · 10 layers · seed 7 final gradient at the input side: 8.072e-8 typical per-layer factor: 0.1953 exactly-dead layers: 0 every gate at this seed and depth Sigmoid final 8.07e-8 · typical factor 0.195 Tanh final 0.0019 · typical factor 0.535 ReLU final 1.0000 · typical factor 1.000 Leaky ReLU final 1.0000 · typical factor 1.000 GELU final 0.0576 · typical factor 0.752 Swish / SiLU final 0.0120 · typical factor 0.643 the arithmetic sigmoid caps every factor at 0.25: 0.25¹⁰ = 9.54e-7 0.25³⁰ = 8.67e-19 — thirty layers of sigmoid your gate's typical factor 0.195 over 10 layers ≈ 8.07e-8 ReLU factors are 1 while the unit is active — nothing is multiplied away

This is a one-number teaching model, not a full network: it shows the mechanism, not a training run. Re-roll the weights a few times — ReLU’s gradient is either exactly 1 or exactly 0 depending on whether each unit stayed active, and one dead layer zeroes everything behind it.

Worked example — thirty layers, four gates, one seed

The lab’s one-number teaching model sends a signal forward through 30 seeded layers and walks the gradient back, multiplying by the local derivative at every stop. Same random weights for every gate; only the activation changes.

30 layers, seed 7, unit-scale weights gate typical |f′| gradient at layer 1 dead layers sigmoid 0.208 3.59 × 10⁻²¹ 0 tanh 0.611 3.77 × 10⁻⁷ 0 GELU 0.483 3.25 × 10⁻¹⁰ 0 ReLU 0.063 0 3 ← hard zeros worst-case per-layer factors (all units at max derivative) sigmoid 0.25¹⁰ = 9.54 × 10⁻⁷ tanh 1.0¹⁰ = 1 GELU ~0.8¹⁰ = 1.07 × 10⁻¹ ReLU 1 or 0, never in between

Two lessons hide in the table. First, the ordering — sigmoid worst, then GELU, then tanh — follows the typical derivative each gate actually spends time at, not its advertised maximum. Second, ReLU is not sigmoid’s opposite: no exponential shrink, but three dead layers each multiply everything behind them by exactly 0. A decay can be countered by depth, initialization or normalization; a zero cannot. That cliff is the next chapter.

Quick check

A 30-layer tanh network trains, but the first five layers' weights barely change. The per-layer factors sampled from the data average 0.61. What is the gradient reaching layer 1, roughly?

DEAD NEURONS

Zero gradient
is forever.

A unit whose pre-activation is negative on every sample gets output 0, derivative 0, and therefore an update of exactly 0 — on every example, at every step. It is not slow and it is not small. It is switched off, and gradient descent cannot switch it back on.

ReLU’s negative half has derivative exactly 0, not merely small. That makes the failure categorical. A sigmoid unit in its tail still receives a trickle of gradient — 10⁻⁴, 10⁻⁶ — and over enough steps the trickle can move it. A dead ReLU receives zero, and zero times any learning rate is still zero. The update rule runs, the parameter does not move, and the unit stays dead for every remaining epoch.

How does a unit get there? Its weighted sum must be negative on every training sample. That happens when a large negative bias lands on the wrong side of the data — a big learning-rate step, an initialization that starts the unit deep in the negative region, or simply bad luck with a sparse feature. Once there, the unit’s job is taken over by its neighbours, which makes recovery even less likely: nothing in the loss ever asks the dead unit to return.

The dead neuron ward: same weights, three gates

Twenty neurons read 5 Gaussian inputs, 1000 samples each. Push the biases negative — what a bad initialization step or a too-large learning rate does to some units — and count how many stop learning. The weights never change; only the gate does.

n01healthy
11% active · 0.112 mean |f′|
n02weak
1% active · 0.010 mean |f′|
n03weak
2% active · 0.022 mean |f′|
n04dead
0% active · 0.000 mean |f′|
n05healthy
16% active · 0.155 mean |f′|
n06dead
0% active · 0.000 mean |f′|
n07weak
0% active · 0.004 mean |f′|
n08healthy
8% active · 0.080 mean |f′|
n09dead
0% active · 0.000 mean |f′|
n10weak
5% active · 0.049 mean |f′|
n11dead
0% active · 0.000 mean |f′|
n12weak
4% active · 0.036 mean |f′|
n13weak
5% active · 0.048 mean |f′|
n14dead
0% active · 0.000 mean |f′|
n15healthy
13% active · 0.129 mean |f′|
n16healthy
13% active · 0.129 mean |f′|
n17weak
5% active · 0.049 mean |f′|
n18weak
0% active · 0.001 mean |f′|
n19weak
5% active · 0.045 mean |f′|
n20weak
2% active · 0.019 mean |f′|

“Active” means the sample gave this neuron a gradient of at least 0.05. A bar at 0% with status DEAD is a unit that will never move again under this gate.

ReLU · 20 neurons · 5 inputs · 1000 samples bias shift -4.5 dead (no gradient ever) 5 / 20 weak (barely any) 10 / 20 healthy 5 / 20 smallest |f′| seen on any sample: 0.000000 ReLU: every negative sample has f′ = 0 exactly the same 20 neurons under the other gates ReLU dead 5 · weak 10 · healthy 5 Leaky ReLU dead 0 · weak 15 · healthy 5 GELU dead 0 · weak 7 · healthy 13

A dead ReLU neuron is not slow or small — it is stuck: output zero, gradient zero, so every update is zero times the learning rate. Leaky ReLU keeps a 0.01 slope on the negative side and GELU keeps a real slope everywhere, so the same unlucky units stay trainable.

Worked example — same unit, three gates, one nudge

One hidden unit sits at z = −2 with upstream gradient ∂L/∂h = 0.05 and learning rate 0.1. Compare the weight update each gate permits at that point.

gate f′(−2) update = lr × ∂L/∂h × f′(−2) × x ReLU 0 0 ← exactly nothing Leaky ReLU 0.01 0.1 × 0.05 × 0.01 = 5.0 × 10⁻⁵ × x GELU −0.085 0.1 × 0.05 × 0.085 = 4.3 × 10⁻⁴ × x the ward: 20 neurons, 5 Gaussian inputs, 1000 samples, seed 0 bias shift −4.5 ReLU Leaky ReLU GELU dead 5 0 0 weak 10 0 0 healthy 5 20 20

The Leaky ReLU update looks negligible — 5 × 10⁻⁵ times the input — and for one step it is. But it is nonzero, so z drifts, the unit’s outputs stop being flat zero, its derivative grows, and the next update is larger. The road back is exponential, and it starts with the one thing ReLU cannot give: a gradient that is not exactly zero. GELU gets there faster still, because at z = −2 its slope is already eight times steeper than Leaky ReLU’s.

Quick check

During training you notice 30% of a ReLU layer's units output 0 for every input in the batch. Which statement is correct?

SOFTMAX

Scores in,
shares out.

A classifier’s last layer does not owe you a probability — it owes you a distribution over mutually exclusive classes. Softmax manufactures one: exponentiate every score, then divide by the total. The exponent makes big scores disproportionately big; the division makes the shares sum to 1.

Softmax takes a vector of raw scores — logits, the unbounded outputs of the last linear layer — and turns it into a probability distribution over the classes:

softmax(zᵢ) = exp(zᵢ) / Σ exp(zⱼ) properties: every output ∈ (0, 1) all outputs sum to 1 order is preserved — the largest logit keeps the largest share adding a constant to every logit changes nothing (the constant cancels)

Two design choices carry the meaning. Exponentiation is monotone, so the ranking of the scores survives — the argmax of the probabilities is the argmax of the logits. And because the shares are computed from ratios, only differences between logits matter: shifting every score by +10 produces the same distribution. That last property is not a curiosity; it is the trick that makes softmax numerically stable, and the difference between a working classifier and a row of NaNs.

Softmax: one total, split many ways

Four class scores (logits) go in; four probabilities that sum to 1 come out. Temperature divides the logits before exponentiating: low temperature sharpens toward the argmax, high temperature flattens toward uniform.

0%25%50%75%100%63.8%catlogit 2.023.5%doglogit 1.09.5%foxlogit 0.13.2%birdlogit -1.0softmax output · probability per classstable: x − max, then exp

All four bars share one total. The largest logit does not own the largest bar — it owns the largest share, and the shares always sum to 1.0000.

temperature T = 1.00 stable probabilities (sum = 1.0000) cat 63.81% dog 23.47% fox 9.54% bird 3.18% prediction: cat (63.8%) gap to runner-up 0.4033 temperature sweep for these logits T=0.25 [0.982, 0.018, 0.000, 0.000] T=1.00 [0.638, 0.235, 0.095, 0.032] T=4.00 [0.348, 0.271, 0.216, 0.164]

Softmax is an output gate, not a hidden one: it collapses the vector’s magnitude into a fixed total, which is exactly what a classifier needs to report and exactly what an intermediate representation must not do.

Worked example — four classes and a temperature dial

The lab’s default logits are z = [2, 1, 0.1, −1]. Exponentiate, total, divide:

exp(2) = 7.389056 exp(1) = 2.718282 exp(0.1) = 1.105171 exp(−1) = 0.367879 total = 11.580388 softmax = [0.638066, 0.234731, 0.095435, 0.031767] sum = 1.000000 temperature T divides the logits before exp: T = 0.5 → z/T = [4, 2, 0.2, −2] → [0.861932, 0.116650, 0.019282, 0.002137] T = 0.25 → z/T = [8, 4, 0.4, −4] → [0.981525, 0.017977, 0.000491, 0.000006] T → 0 sharpens toward the argmax; T → ∞ flattens toward uniform

The class with logit 2 was never five times better than the class with logit 0.1 — the logits are not measurements, just scores — and softmax does not pretend otherwise. What it does is commit: at T = 1 the model reports 64% confidence for the winner; turn the dial to T = 0.25 and the same scores become 98% confidence. Temperature trades decisiveness for caution without touching the model’s parameters, which is exactly why language models expose it as a sampling knob.

Quick check

A model outputs logits [0.1, 0.2] for two mutually exclusive classes. What does softmax report, and what would a sigmoid report for the first class?

WHICH GATE, WHEN

Defaults first.
Measure before you change.

Activation choice is a small decision that beginners treat as a large one. The field converged on a short list of defaults for the obvious combinations — start there, and only deviate when a learning curve gives you a reason.

The table below is the whole decision, and none of it is arbitrary. Hidden layers want a gate whose derivative stays usable across the operating range — GELU in transformers, ReLU-family in vision and tabular models, tanh where the state is multiplied repeatedly. Output layers want the gate that matches the shape of the answer: a probability for two classes (sigmoid), a distribution over many (softmax), or no gate at all when the answer is a real number.

The defaults table from the source lesson — the starting point, not a law. Every row has a reason, and the reasons are the derivations in this lesson.
where the gate sitsdefaultwhy
Hidden · transformer / NLPGELUSmooth, never exactly zero; the default in BERT, GPT and friends.
Hidden · CNN / visionReLU (Swish with headroom)Sparse and fast; decades of tuning from AlexNet onward.
Hidden · RNN / LSTMtanhBounds the repeatedly-multiplied hidden state; never explodes.
Hidden · simple MLP / tabularReLUThe cheapest strong default; escalate only if curves stall.
Output · binary classificationSigmoidOne score → one probability; pair with binary cross-entropy.
Output · multi-class classificationSoftmaxA distribution over mutually exclusive classes; sums to 1.
Output · regressionNone (linear)Predictions must span the reals; any squash would cap them.

Pick the right gate for the job

The source lesson’s decision flow, made clickable. Two questions — where the gate sits and what you are building — collapse to a default you can defend. Start with the default; change it only when a measurement asks you to.

QUESTION 1 / WHERE DOES THE GATE SIT?

Hidden layers need a nonlinear gate between every affine map. Output layers need the gate that matches the loss — or none at all.

choose a path the defaults table hidden · transformer GELU hidden · CNN ReLU (Swish) hidden · RNN / LSTM tanh hidden · simple MLP ReLU output · binary sigmoid output · multi-class softmax output · regression none (linear) the lesson's rule: start with these, change only with evidence.

Activation choice is a default-setting decision, not a research project. The measurement that justifies changing it is a learning curve — loss going flat while units sit dark, or gradients shrinking by orders of magnitude.

Quick check

You are predicting tomorrow's temperature (a real number, roughly −30 °C to +45 °C). What does the output layer look like, and why?

CHECK YOURSELF

Six questions.
Then the terms worth keeping.

Answer before you look. The collapse question and the softmax question are the two that separate a memorised activation list from an understanding of what each gate does to a signal — forward and backward.

0 / 6 answered · 0 correct

01You stack five linear layers with no activation functions. What do you actually have?

02What is the output range of the ReLU activation function?

03What is the “dead neuron” problem in a ReLU network?

04Which activation function is the hidden-layer default in modern transformers like BERT and GPT?

05Why does softmax belong in the output layer only, never in a hidden layer?

06Sigmoid's derivative peaks at 0.25. What does a 10-layer sigmoid stack pass back from the output to the input?

Key terms, demystified

Click a card to swap the lazy description for what it actually means.

Exercises from the lesson

Four problems with exact numbers — learn PReLU’s slope, walk the vanishing experiment to 50 layers, rescue an all-negative unit with ELU, and compute what a sigmoid output layer is actually doing wrong. Try first; a worked answer is one click away.

  1. Implement PReLU — Leaky ReLU where the negative slope α is learned — and train it on the source's circle dataset beside a fixed Leaky ReLU. Write down the gradient that updates α, and explain why α can move a unit that ReLU would have let die.
    Show one worked answer

    Forward: pReLU(z) = z if z > 0 else αᵢ·z, one α per unit. Backward adds one line per unit: ∂L/∂αᵢ = Σ_samples (∂L/∂hᵢ) · zᵢ · 1[zᵢ < 0] — the negative pre-activation, weighted by the upstream gradient. Numeric check: a unit that is dead under ReLU has z = −2 on some sample and upstream gradient ∂L/∂h = 0.1. With learning rate 0.1 the PReLU update is Δα = −lr · (0.1 × (−2)) = +0.02; three such steps lift α from 0.25 to 0.31, the negative-side slope grows, the unit's output stops being flat zero, and it starts contributing to the loss. The ReLU unit at the same z cannot make that move: its own derivative is 0, so every update is 0. Practical cautions: constrain α ≥ 0 (libraries store log α or clamp), and use a separate learning rate if α moves too fast. On the circle dataset the accuracy difference versus fixed Leaky ReLU is small — the point of the exercise is the gradient path and the recovery, not the score.

  2. Run the vanishing experiment with 50 layers instead of 10. Using worst-case per-layer factors (sigmoid 0.25, tanh 0.5, ReLU 1.0, GELU 0.8), find the layer where each signal effectively reaches zero (below 10⁻⁶), then say what the real, data-dependent plot looks like.
    Show one worked answer

    With a constant factor f per layer the gradient is fᴸ. Sigmoid: 0.25¹⁰ = 9.54 × 10⁻⁷ crosses the bar at layer 10; by layer 30 it is 8.67 × 10⁻¹⁹. Tanh: 0.5¹⁰ = 9.77 × 10⁻⁴, 0.5²⁰ = 9.54 × 10⁻⁷ — crossed near layer 20. ReLU: 1ᴸ = 1 wherever units stay active; the first inactive layer multiplies everything behind it by exactly 0, so the curve is a cliff, not a decay. GELU: 0.8ᴸ falls below 10⁻⁶ only past layer 60 (0.8⁵⁰ = 1.43 × 10⁻⁵). The lesson's sampled chain (seed 7, 30 layers) lands close to that ordering: sigmoid 3.59 × 10⁻²¹, tanh 3.77 × 10⁻⁷, GELU 3.25 × 10⁻¹⁰. Honesty note: real factors are data-dependent and vary layer to layer, so read the plot as an order-of-magnitude story, not a prediction — and remember ReLU's failure is a hard zero, which no amount of depth can soften.

  3. Implement ELU: elu(x) = x if x > 0, α(eˣ − 1) if x ≤ 0. Compare its dead-neuron rate to ReLU on the same weights, and show with numbers that an all-negative ELU unit can still move.
    Show one worked answer

    ELU's derivative is 1 for positive inputs and α·eˣ for negative ones — never exactly zero, approaching zero only as x → −∞. Numeric check: a unit stuck at z = −3 has ReLU output 0 and gradient 0; with α = 1 the ELU unit outputs e⁻³ − 1 = −0.9502 and its gradient is e⁻³ = 0.0498. With upstream gradient δ = 0.05 and learning rate 0.1, the ReLU weight update is 0.1 × 0.05 × 0 = 0, while the ELU update is 0.1 × 0.05 × 0.0498 = 2.5 × 10⁻⁴ times the input — small, but nonzero, so z drifts, eᶻ grows, and the unit can climb out of the negative region. On the lesson's 20-neuron ward at bias shift −4.5, ReLU buries 5 units while ELU shares Leaky ReLU's property that the permanently-dead count is 0. The price is an exp() per unit and a derivative that is not monotone, which can make the mean activation harder to interpret.

Terms this lesson borrows from later lessons (or outside)

You do not need to master these here. Each one gets a proper treatment in its own lesson; the one-line meaning is enough to keep reading. Orange dotted underlines in the prose point back to this list.

  • derivativeHow much a function's output moves when its input nudges, and in which direction. Every gate here is judged by its derivative because that is the number backprop multiplies. (Phase 1, Lesson 04)
  • chain ruleDifferentiate nested functions by multiplying local slopes: (f∘g)′ = f′(g)·g′. Ten layers mean ten multiplications — which is how a 0.25 factor per layer becomes 10⁻⁶. (Phase 1, Lesson 05)
  • matrix compositionMultiplying matrices means applying transformations one after another, and the product is again a single matrix. That closure is exactly why a stack of linear layers collapses. (Phase 1, Lesson 03)
  • probability distributionA list of nonnegative numbers that sum to 1 — each entry is a share of belief. Softmax manufactures one from raw scores. (Phase 1, Lesson 06)
  • logistic regressionA linear score pushed through the sigmoid to produce a probability. The activation predates neural networks by decades: this lesson is a logistic regression stacked up and un-squashed. (Phase 2, Lesson 03)
  • backpropagationThe algorithm that walks backward through the network multiplying local derivatives layer by layer. This lesson is about the number it multiplies — and what happens when that number is 0.25, 1, or 0. (Phase 3, Lesson 03)
KEEP GOING

A picture is a start.
Practice is the rest.

This lesson is a port of an open course. Everything here traces back to it — and the next step is running the code yourself.

Lesson text adapted from AI Engineering from Scratch (Phase 03, Lesson 04) and the Math Foundations Notebook reference build. The seven labs (activation plotter, linear-collapse proof, gradient dead-zone scan, 30-layer vanishing chain, dead-neuron ward, softmax with temperature and stability toggle, activation picker), the per-gate value/derivative table at x = −2/0/2, the seeded 30-layer gradient products, the ELU/PReLU recovery arithmetic, the softmax overflow demonstration and the defaults table are original to this page. Every number shown is computed live by the labs or verified by hand in the prose.