x = jnp.arange(-8.0, 8.0, 0.1)
y = jax.nn.relu(x)
d2l.plot(x, y, 'x', 'relu(x)', figsize=(5, 2.5))Dive into Deep Learning · §4.1
Multilayer Perceptrons
one kink between affine layers · XOR untangled · any function, hinge by hinge · why depth beats width.
Motivation
Softmax regression is a single affine map: monotonic, line-shaped decisions.
The fix: learn the features, keep the linear predictor on top. A two-unit net computes XOR exactly, and depth multiplies what width merely adds.
01
From Linear to Nonlinear
hidden layers, and why they need a kink
Architecture
Stack fully-connected layers. The middle ones are hidden: neither input nor output. Every unit sees every unit below it.
We read the first layers as a learned representation and the last as a linear predictor on top of it.
Architecture
For a minibatch \mathbf{X} \in \mathbb{R}^{n \times d}, hidden width h, and q outputs:
\mathbf{H} = \mathbf{X} \mathbf{W}^{(1)} + \mathbf{b}^{(1)}, \qquad \mathbf{O} = \mathbf{H} \mathbf{W}^{(2)} + \mathbf{b}^{(2)}.
Two weight matrices, two biases. It looks like we have bought ourselves a more powerful model.
The catch
Substitute \mathbf{H} into the output layer:
\mathbf{O} = (\mathbf{X} \mathbf{W}^{(1)} + \mathbf{b}^{(1)})\,\mathbf{W}^{(2)} + \mathbf{b}^{(2)} = \mathbf{X}\,\underbrace{\mathbf{W}^{(1)}\mathbf{W}^{(2)}}_{=\,\mathbf{W}} + \underbrace{\mathbf{b}^{(1)}\mathbf{W}^{(2)} + \mathbf{b}^{(2)}}_{=\,\mathbf{b}}.
An affine function of an affine function is still affine. The hidden layer added zero expressive power.
Stacking linear layers is wasted effort: we are back to plain softmax regression.
The fix
Apply an elementwise nonlinearity \sigma after every hidden affine map:
\mathbf{H} = \sigma\!\left(\mathbf{X} \mathbf{W}^{(1)} + \mathbf{b}^{(1)}\right),\qquad \mathbf{O} = \mathbf{H} \mathbf{W}^{(2)} + \mathbf{b}^{(2)}.
Now the layers can no longer be merged: the network bends, folds, and curves its decision surface. Two ingredients (affine + nonlinear), and every architecture in this book follows.
02
A Concrete Win: XOR
one ReLU layer untangles the impossible case
Why nonlinearity matters
Label each corner of the unit square by whether its coordinates differ. The two classes sit on opposite diagonals (left), so no straight line works.
One hidden layer \mathbf{h} = \operatorname{ReLU}(\mathbf{x}\mathbf{W}^{(1)} + \mathbf{b}^{(1)}) then folds the two label-1 corners onto the same point (right), and now a single line separates them.
XOR · verified
With \mathbf{W}^{(1)} = \left(\begin{smallmatrix}1 & 1\\ 1 & 1\end{smallmatrix}\right), \mathbf{b}^{(1)} = (0,\,{-1}), \mathbf{w}^{(2)} = (1,\,{-2})^\top and a ReLU, pushing all four corners through by hand gives
| x_1 | x_2 | \mathbf{h} = \operatorname{ReLU}(\mathbf{x}\mathbf{W}^{(1)} + \mathbf{b}^{(1)}) | o = h_1 - 2h_2 | XOR |
|---|---|---|---|---|
| 0 | 0 | (0,\ 0) | 0 | 0 ✓ |
| 0 | 1 | (1,\ 0) | 1 | 1 ✓ |
| 1 | 0 | (1,\ 0) | 1 | 1 ✓ |
| 1 | 1 | (2,\ 1) | 0 | 0 ✓ |
We constructed these weights; the rest of the book is about having optimization discover such representations. Watch that happen live on the XOR and spiral datasets at the TensorFlow Playground (playground.tensorflow.org).
Expressive power
Universal approximation theorem. A single hidden layer with enough units can approximate any continuous function on a bounded domain, to arbitrary accuracy, for any non-polynomial \sigma, ReLU included (Cybenko 1989; Leshno et al. 1993).
“Enough units” can be exponentially many; the theorem says a fit exists, not that SGD finds it, nor that it generalizes.
This is why we reach for depth: a deep net often represents the same function far more compactly than a shallow one would, trading width for layers.
Expressive power
Each ReLU unit contributes a hinge a_k\operatorname{ReLU}(x - t_k): with D units the output is piecewise linear with at most D+1 pieces. Approximating a curve is then just fitting a polyline: more joints, less error.
Three hinges (left) sum to a 4-piece polyline that tracks the smooth target (right); the shaded band is the error.
Expressive power · verified
Evaluate randomly initialized ReLU MLPs on a dense 1-D grid, detect where the slope jumps, and count the linear pieces (mean over 20 draws):
| width D | 2 | 4 | 8 | 16 |
|---|---|---|---|---|
| bound D+1 | 3 | 5 | 9 | 17 |
| depth 1 | 2.6 | 4.3 | 7.5 | 14.4 |
| depth 2 | 3.5 | 7.0 | 13.9 | 27.4 |
| depth 3 | 3.6 | 8.1 | 22.1 | 40.1 |
One layer of width D: at most D+1 pieces, as promised. Each extra layer folds the graph, roughly multiplying the count, the multiplicative-vs-additive gap that makes depth pay.
03
Activation Functions
ReLU, sigmoid, tanh, and when to use each
Activations
\operatorname{ReLU}(x) = \max(0, x).
Keep the positive part, zero the rest. Why it won:
Activations
The derivative is a step: 0 on the left, 1 on the right:
\operatorname{ReLU}'(x) = \mathbb{1}[x > 0].
Dead ReLU: a unit pushed negative for every example gets zero gradient forever. LeakyReLU / PReLU, \max(0,x)+\alpha\min(0,x), leak a little signal to keep it alive.
Activations
\operatorname{sigmoid}(x) = \frac{1}{1 + e^{-x}}.
A smooth, differentiable threshold, and the original neuron activation. Today it lives mostly at the edges of a net:
Activations · the catch
\operatorname{sigmoid}'(x) = \operatorname{sigmoid}(x)\,(1 - \operatorname{sigmoid}(x)).
The gradient peaks at just 0.25 and vanishes past |x|\gtrsim 5. Even at its best, ten stacked layers attenuate the backward signal by 0.25^{10} \approx 10^{-6}: the vanishing-gradient problem ReLU fixed (the full story in the numerical-stability section).
Activations
\tanh(x) = \frac{1 - e^{-2x}}{1 + e^{-2x}} = 2\,\operatorname{sigmoid}(2x) - 1.
Same S-shape, but range (-1,1) and zero-centered, which mildly eases optimization. The default inside RNN cells, where bounded activations help.
Still saturates at both tails, so its gradient vanishes just like sigmoid’s.
04
Wrap-up
choosing an activation, plus what comes next
Reference
| Range | Saturates? | Typical use | |
|---|---|---|---|
| ReLU | [0, \infty) | left only (can die) | default hidden layer |
| LeakyReLU / PReLU | \mathbb{R} | no | when ReLU dies |
| GELU \,x\Phi(x) | \approx\mathbb{R} | barely | BERT, GPT-2-style Transformers |
| SiLU / SwiGLU | \mathbb{R} | barely | many recent language models |
| Sigmoid | (0, 1) | both ends | gates, binary output |
| Tanh | (-1, 1) | both ends | RNN cells |
| Softmax | simplex | one end | multiclass output |
Use ReLU as a simple hidden-layer baseline. Transformer families differ: some use GELU, while many recent language models use gated SiLU/SwiGLU blocks. Use sigmoid / softmax at outputs when the model calls for probabilities.
Wrap-up
Next (the MLP-implementation section): build one and train it on Fashion-MNIST, from scratch, then in a few high-level API lines.