Visual walkthrough — Feed-forward network sublayers
We assume you know only one thing: multiplying two numbers, and adding. Everything else — what a "weight", a "matrix", a "ReLU", a "hidden layer" mean — is built below, in pictures.
Step 1 — One input, one weight: what "" is even doing
WHAT. Start with the smallest possible piece. We have one number coming in — call it (the "input"). We have one dial we can turn — call it (a "weight"). The machine's whole job at this stage is to compute : stretch or shrink the input.
WHY. Before any transformer, before any matrix, we must understand what a single weight means. A weight is a volume knob. Turn it up () and the input's effect triples. Turn it to zero and the input is ignored. Make it negative and the input flips sign. Every giant matrix later is just a grid of these knobs.
PICTURE. Look at the figure: the horizontal axis is the input , the vertical axis is the output . The line's steepness is . Three lines are drawn — a gentle one (), a steep one (), and a downhill one ().
Notice the flaw already: every line goes through the origin, and every line is straight. No matter what knob we turn, always gives , and the relationship is always a straight line. That straightness is the enemy we fight in Step 4.
Step 2 — Adding a bias: sliding the line off the origin
WHAT. We add one more number, (the "bias"), after the multiply: the machine now computes .
WHY. In Step 1 every line was chained to the origin. But real features don't switch on at exactly zero. Maybe "this pattern is present" should trigger when , not . The bias is a shift — it slides the whole line up or down so the machine can choose where the interesting threshold sits. The symbol appears added, on its own, because it must act regardless of the input's size.
PICTURE. Same axes. One line is (through origin, dashed). The solid amber line is — identical steepness, but lifted up by exactly . The vertical amber bracket marks the lift.
Reveal check:
What does the weight control, and what does the bias control?
Step 3 — Many inputs → the matrix row is a dot product
WHAT. A token isn't one number; it is a list of numbers, (its "embedding"). To make one output number we give each input its own weight and add them all up:
WHY. One knob can only react to one number. But a useful feature — say "positive sentiment AND past tense" — depends on several input dimensions at once. So we need one knob per input dimension. This weighted sum is called a dot product. We use a dot product specifically because it answers the question "how much does this input pattern match my stored pattern of weights?" — big when the input lines up with the weights, small or negative when it doesn't. No other single operation both mixes all inputs and stays linear.
PICTURE. The figure shows the input as a vertical stack of bars (heights ) and the weights as a second stack. Each pair is multiplied (amber links), the products flow into a summing node, and the bias drops in at the end to give one output number .
Now stack many such neurons. If we want output numbers, we need rows of weights. Bundling all rows into one grid gives the matrix , and all the biases into the vector . That single line is nothing more than "run Step 3's dot product times in parallel." The matrix is not new magic — it is a rack of Step-1 knobs.
Step 4 — Why it collapses without a bend: the non-linearity
WHAT. We apply to every neuron's output: keep it if positive, clamp it to zero if negative.
WHY. This is the heart of the whole page. Suppose we did NOT bend — we just did matrix, then matrix: . Multiplying two matrices gives another matrix . So two straight layers = one straight layer. Stacking 24 of them = still one straight line's worth of power! The parent note's warning — "stacking would collapse into a single linear transformation" — is exactly this. We need a kink, an operation that is not a straight line, sitting between the two matrices. ReLU is the simplest kink: flat for negatives, sloped for positives.
PICTURE (left). The ReLU graph: a flat floor at zero for , then a ramp for . The corner at the origin is the "bend" — mark it in amber.
PICTURE (right). The proof of collapse: two straight lines composed give one straight line (still straight); but a straight line through a ReLU gives a genuine elbow — a shape no single matrix could make.
Step 5 — Expand then contract: the funnel
WHAT. The first matrix grows the vector from up to ; ReLU bends it; the second matrix shrinks it back to .
WHY. Why go up first? Each hidden neuron is one detector (Step 3). With only neurons you get detectors — a bottleneck. Widening to gives four times as many detectors, so the layer can look for many more distinct patterns at once. Then why come back down? Because the output must be added to the residual stream, which lives in dimensions. The second matrix is forced to summarise the raw detections into useful numbers — a compression that keeps only what matters.
PICTURE. A funnel drawn as three vertical columns of nodes: a narrow input column (), a wide hidden column () with amber ReLU'd nodes, and a narrow output column back to . Arrows fan out (expansion ) then fan in (contraction ).
Step 6 — Position-wise: the same funnel, stamped on every token
WHAT. Given a whole sentence , the FFN applies the identical funnel to each token separately:
WHY. By this point the attention sublayer has already mixed information between tokens, so each already "knows" about its neighbours. The funnel's job is pure per-token feature extraction; it does not need to peek sideways. Same weights everywhere means one funnel is reused times — this is why it parallelises perfectly and why it is literally a convolution.
PICTURE. Six token slots ("The cat sat on the mat") each feeding an identical grey funnel; a single shared weight-box connects to all of them with dotted lines to stress "same weights, different inputs." No horizontal arrows between funnels — that absence is the point.
Step 7 — Degenerate cases: check the machine never breaks
WHAT. Push weird inputs through and confirm each stays sane.
WHY. A trustworthy derivation must survive its own edge cases. Four to check:
- All-negative pre-activation. If every entry is negative, ReLU zeroes the entire hidden vector: . Then . The layer outputs just its bias — a constant. Not broken, just uninformative; the residual connection still carries forward, so no signal is lost.
- Zero input, . Then ; the output depends only on the biases. The line-through-origin problem of Step 1 is exactly why had to exist.
- Huge positive input. ReLU is unbounded, so scales linearly — but the next LayerNorm rescales it, so no explosion reaches the next block.
- Modern smooth activations. Swap ReLU for GELU or SiLU: the hard corner becomes a soft curve, so tiny negatives leak a small gradient instead of dying. Everything above still holds; only the shape of the bend changes.
PICTURE. Four mini-panels, one per case: the all-negative flatline to ; the landing on ; the unbounded ramp tamed by a LayerNorm bracket; and ReLU's sharp corner overlaid with GELU's smooth curve.
Recall Edge cases in one breath
When ::: does the FFN output a constant? ::: When every hidden pre-activation is negative, so ReLU zeroes and only survives. Why ::: must exist even when ? ::: Because then, so without the layer could never fire on a zero input (Step 1's origin trap). What ::: stops a huge positive input from exploding the next block? ::: The following LayerNorm rescales the residual sum.
The one-picture summary
Everything collapses into a single diagram: one token vector enters (Step 1–3 build each connection), fans it out (Step 5), ReLU bends it (Step 4), fans it back in, the bias shifts it (Step 2), and the whole stamp is reused per position (Step 6) with edge behaviour noted (Step 7).
Recall Feynman retelling — say it to a 12-year-old
Imagine each word in a sentence has already gossiped with the other words (that was attention), so it now holds a little bundle of clues. The feed-forward network is a thinking booth that every word steps into, one at a time, using the exact same set of rules.
Inside the booth: first we ask a big pile of yes/no questions about the bundle of clues — "is it positive?", "is it a past-tense verb?", "is it a name?" — and we ask four times as many questions as there were clues, because we want to notice lots of patterns. Each question is just: multiply every clue by a personal importance number, add them up, add a nudge, and if the total is below zero, say "nope, zero" (that's the ReLU bend — and it's the only reason stacking booths isn't a waste, because two plain multiply-steps would secretly fuse into one). Then we shrink all those answers back down to the original size, keeping only the useful summary, so the word can carry it forward.
That's the whole machine: stretch out, bend, squeeze back — the same booth stamped on every word.
Related reading: Universal Approximation Theorem (why two layers can learn anything), Batch Normalization vs Layer Normalization, Positional Encoding, and the full Transformer Encoder Block.