Type at least 2 letters. Enter opens the first result, Esc closes.

    Deep Learning · Lesson 1 · Networks and how they learn

    MLPs and universal approximation

    Beginner 65 min 3 interactive figures 4 videos Colab notebook

    Before this lesson: matrices as maps (linear algebra, lesson 01) and rank (linear algebra, lesson 02); logistic and softmax regression (ml-fundamentals track); functions, sets and the notation f:Rn→Rmf: \mathbb{R}^n \to \mathbb{R}^m (foundations track). This is the first lesson of the track. Time: about 65 minutes, plus the notebook.


    Why this matters #

    Every architecture in this track is built from multilayer perceptrons (MLPs). The feed-forward block of a transformer is a two-layer MLP and holds about 2/3 of the weights of a standard block. Physics-informed neural networks (PINNs) and neural fields are MLPs that take coordinates as input, and the branch and trunk networks of DeepONet are usually MLPs. When someone asks "why can a network fit this?", the usual answer is the universal approximation theorem. You should know exactly how weak this answer is: it promises existence, nothing more. Depth separation is the first precise reason to prefer deep networks over wide ones.

    1. Predict first #

    2. The picture #

    One unit is a hinge #

    The rectified linear unit is relu⁡(u)=max⁡(0,u)\operatorname{relu}(u) = \max(0, u). One unit with one input xx computes relu⁡(wx+b)\operatorname{relu}(wx + b). The inside, wx+bwx + b, is zero at x=−b/wx = -b/w. On one side of this point the unit outputs 0; on the other side it outputs the straight line wx+bwx + b. We call this graph a hinge and the point −b/w-b/w its joint.

    Example: relu⁡(2x−1)\operatorname{relu}(2x - 1) has its joint at x=1/2x = 1/2. For x<1/2x < 1/2 it is 0; for x>1/2x > 1/2 it is 2x−12x - 1, a line with slope 2. If w<0w < 0, the sides swap: relu⁡(−2x+4)\operatorname{relu}(-2x + 4) is 00 for x>2x > 2 and −2x+4-2x + 4 for x<2x < 2.

    A hidden layer adds hinges #

    A network with one hidden layer of HH units and one output computes

    N(x)=c0+∑i=1Hcirelu⁡(wix+bi).N(x) = c_0 + \sum_{i=1}^{H} c_i \operatorname{relu}(w_i x + b_i).

    Each term is a hinge scaled by its output weight cic_i. A sum of hinges is continuous and piecewise linear. Each unit adds at most one joint, so NN has at most HH joints and at most H+1H + 1 linear pieces. Between two joints nothing bends, so NN is a straight line there.

    How to "connect the dots". Take four points: (0,0)(0, 0), (1,2)(1, 2), (2,1)(2, 1), (3,1)(3, 1). The straight lines between them have slopes s1=2s_1 = 2, s2=−1s_2 = -1, s3=0s_3 = 0. Build NN from left to right:

    1. Start at x=0x = 0 with a unit relu⁡(x−0)\operatorname{relu}(x - 0) and output weight c0=2c_0 = 2. Now the slope is 22, which is right on [0,1][0, 1].
    2. At x=1x = 1 the slope must change from 22 to −1-1. Add relu⁡(x−1)\operatorname{relu}(x - 1) with output weight c1=−1−2=−3c_1 = -1 - 2 = -3.
    3. At x=2x = 2 the slope must change from −1-1 to 00. Add relu⁡(x−2)\operatorname{relu}(x - 2) with output weight c2=0−(−1)=1c_2 = 0 - (-1) = 1.

    So N(x)=2relu⁡(x)−3relu⁡(x−1)+relu⁡(x−2)N(x) = 2\operatorname{relu}(x) - 3\operatorname{relu}(x - 1) + \operatorname{relu}(x - 2). Check: N(1)=2N(1) = 2, N(2)=4−3=1N(2) = 4 - 3 = 1, N(3)=6−6+1=1N(3) = 6 - 6 + 1 = 1. Each output weight is a change of slope. That is the whole idea of the construction in section 3. More points give more units and a closer fit to a smooth curve.

    Interactive figure: loading…

    Fit x2x^2 with ReLU units. The aqua curve is the target ff; the blue curve is the network NN; the thin blue lines are its single units ckrelu⁡(x−xk)c_k\operatorname{relu}(x - x_k); the violet knots set the weights; the magenta bar is the largest error. Predict first: if you double the number of units KK, by what factor does the largest error fall? Then move the slider from 2 to 4 to 8. Try sin⁡πx\sin \pi x, and the step, which is not continuous: its error never falls below 1/21/2. Outside [0,2][0, 2] the network is a straight line.

    Depth folds, width only adds #

    A second hidden layer applies hinges to the output of the first layer, not to xx. Suppose the first layer outputs a function that goes up and then down on [0,1][0, 1]. It folds the interval: two different inputs give the same value. Every hinge in the next layer then acts on both halves at the same time. So the pieces multiply from layer to layer, while inside one layer they only add.

    The cleanest example is the tent map t(x)=2relu⁡(x)−4relu⁡(x−12)t(x) = 2\operatorname{relu}(x) - 4\operatorname{relu}(x - \tfrac12). On [0,12][0, \tfrac12] it is 2x2x (up from 0 to 1); on [12,1][\tfrac12, 1] it is 2x−4x+2=2−2x2x - 4x + 2 = 2 - 2x (down from 1 to 0). It uses 2 units. Apply it twice: t(t(x))t(t(x)) goes up and down twice, so it has 4 pieces. Each new layer of 2 units doubles the number of pieces.

    Interactive figure: loading…

    Pieces multiply with depth. Move the slider kk. Top left: the deep network t(k)t^{(k)} (blue) with kk hidden layers of 2 units has 2k2^k pieces. Top right: a network with one hidden layer and the same 2k2k units (grey) can have at most 2k+12k + 1 pieces; here it passes through 2k+12k + 1 points of the aqua target t(k)t^{(k)}. It is exact for k≤2k \le 2 and then fails (largest error in magenta). Bottom: pieces against units on a log scale; the yellow line is the current 2k2k.

    Without an activation nothing folds #

    If we remove the activation, every layer is an affine map x↦xW+bx \mapsto xW + b, and an affine map of an affine map is affine. Straight lines stay straight, parallel lines stay parallel, and the midpoint of a segment goes to the midpoint of its image. No number of layers changes this.

    Interactive figure: loading…

    Three layers, with and without ReLU. A grid of inputs in [−1.5,1.5]2[-1.5, 1.5]^2 goes through three layers 2→2→2→22 \to 2 \to 2 \to 2. With "none", the image after every layer is a grid of parallelograms, and the readout shows the single affine map that does the same job. Switch to ReLU and look at layer 1 first: the parts of the plane where a unit is negative are flattened onto an axis. The yellow segment pp–qq (drag its ends in the input view) stays straight only without ReLU; the midpoint test measures the gap between the image of the midpoint and the midpoint of the images.

    Quick check

    A one-hidden-layer ReLU network R→R\mathbb{R} \to \mathbb{R} has 3 hidden units with joints at x=−1x = -1, 00 and 22, and all output weights are nonzero. How many linear pieces does NN have on R\mathbb{R}?

    Quick check

    Where is the joint of relu⁡(−2x+4)\operatorname{relu}(-2x + 4), and on which side is it zero?

    3. Definitions and main results #

    The multilayer perceptron #

    We use the row-vector convention of PyTorch. A mini-batch of BB inputs is a matrix X∈RB×n0X \in \mathbb{R}^{B \times n_0}, one example per row. For l=1,…,Ll = 1, \dots, L:

    A0=X,Zl=Al−1Wl+1bl,Al=σ(Zl)  (l<L),A_0 = X, \qquad Z_l = A_{l-1} W_l + \mathbf{1} b_l, \qquad A_l = \sigma(Z_l) \ \ (l < L),

    with weights Wl∈Rnl−1×nlW_l \in \mathbb{R}^{n_{l-1} \times n_l}, biases bl∈R1×nlb_l \in \mathbb{R}^{1 \times n_l}, the column of ones 1∈RB\mathbf{1} \in \mathbb{R}^{B} (it adds blb_l to every row), and an activation σ\sigma applied entry by entry. The last layer has no activation: ZLZ_L is the output (the logits for classification, followed by a softmax in the loss; lesson 02).

    • LL is the depth: the number of affine layers. (Do not mix it with the loss L\mathcal{L}.)
    • nln_l is the width of layer ll. Layers 1,…,L−11, \dots, L - 1 are the hidden layers.
    • ZlZ_l is the pre-activation and AlA_l the activation of layer ll. Shapes: Zl,Al∈RB×nlZ_l, A_l \in \mathbb{R}^{B \times n_l}.

    Parameter count. Layer ll has nl−1nln_{l-1} n_l weights and nln_l biases, so

    P=∑l=1L(nl−1+1) nl.P = \sum_{l=1}^{L} (n_{l-1} + 1)\, n_l .

    Example: 2→3→12 \to 3 \to 1 has (2+1)⋅3+(3+1)⋅1=9+4=13(2 + 1) \cdot 3 + (3 + 1) \cdot 1 = 9 + 4 = 13 parameters.

    Example: the transformer feed-forward block. With model width DD and hidden width 4D4D, the block is D→4D→DD \to 4D \to D. Its parameter count is (D+1)⋅4D+(4D+1)⋅D=8D2+5D(D + 1) \cdot 4D + (4D + 1) \cdot D = 8D^2 + 5D. The attention projections WQ,WK,WV,WOW_Q, W_K, W_V, W_O have 4D2+4D4D^2 + 4D, and two LayerNorms have 4D4D. So the feed-forward part is about 8D2/12D2=2/38D^2 / 12D^2 = 2/3 of a block (lesson 11). For D=1024D = 1024 it has 8,393,7288{,}393{,}728 parameters.

    Quick check

    How many parameters (weights and biases) does an MLP 784→256→10784 \to 256 \to 10 have?

    Collapse without nonlinearity #

    Proposition. If σ\sigma is the identity, the network is one affine map x↦xW+bx \mapsto xW + b with W=W1W2⋯WLW = W_1 W_2 \cdots W_L, and rank⁡(W)≤min⁡lnl\operatorname{rank}(W) \le \min_l n_l.

    Proof.

    1. Two layers: (xW1+b1)W2+b2=x(W1W2)+(b1W2+b2)(xW_1 + b_1)W_2 + b_2 = x(W_1W_2) + (b_1W_2 + b_2). This is affine, with weight W1W2W_1W_2 and bias b1W2+b2b_1W_2 + b_2.
    2. Induction on LL: if the first L−1L - 1 layers are one affine map, adding layer LL is step 1 again.
    3. Rank: rank⁡(AB)≤min⁡(rank⁡A,rank⁡B)\operatorname{rank}(AB) \le \min(\operatorname{rank} A, \operatorname{rank} B) (linear algebra, lesson 01), and rank⁡(Wl)≤min⁡(nl−1,nl)\operatorname{rank}(W_l) \le \min(n_{l-1}, n_l). So the product has rank at most the smallest width. ■\blacksquare

    So a deep linear classifier is just softmax regression, possibly with a rank bottleneck. (Its training problem is still non-convex in (W1,…,WL)(W_1, \dots, W_L), which is why deep linear networks are a useful model for studying optimization.)

    The universal approximation theorem #

    A set K⊂RdK \subset \mathbb{R}^d is compact if it is closed and bounded, for example a cube [0,1]d[0, 1]^d. The sup norm of an error is its largest absolute value over KK: sup⁡x∈K∣f(x)−g(x)∣\sup_{x \in K} |f(x) - g(x)|. A small sup norm means the approximation is good everywhere on KK, not only on average.

    Theorem (universal approximation; Leshno, Lin, Pinkus and Schocken, 1993). Let σ:R→R\sigma: \mathbb{R} \to \mathbb{R} be continuous and not a polynomial. For every compact set K⊂RdK \subset \mathbb{R}^d, every continuous f:K→Rf: K \to \mathbb{R} and every ε>0\varepsilon > 0 there are HH and ai,bi∈Ra_i, b_i \in \mathbb{R}, wi∈Rdw_i \in \mathbb{R}^d with

    sup⁡x∈K∣f(x)−∑i=1Hai σ(wi⊤x+bi)∣<ε.\sup_{x \in K} \Big| f(x) - \sum_{i=1}^{H} a_i\, \sigma(w_i^\top x + b_i) \Big| < \varepsilon .

    In words: one hidden layer is enough to approximate any continuous function on a compact set, to any accuracy, if the activation is not a polynomial. ReLU, tanh, the logistic sigmoid and GELU all qualify. Cybenko (1989) proved the first version for sigmoid-like σ\sigma, and Hornik (1991) for continuous, bounded, non-constant σ\sigma.

    Why polynomials fail. If σ\sigma is a polynomial of degree kk, then each σ(wi⊤x+bi)\sigma(w_i^\top x + b_i) is a polynomial in xx of degree at most kk, and so is every sum of them, for any HH. These polynomials form a finite-dimensional subspace of the continuous functions. A finite-dimensional subspace is closed, so it cannot come arbitrarily close to functions outside it, such as x1k+1x_1^{k+1} on a cube.

    Quick check

    Why is σ(u)=u2\sigma(u) = u^2 not a universal activation, even with very many hidden units?

    The 1-D ReLU case by construction #

    For ReLU in one dimension we can prove the theorem with our own hands. The idea is the "connect the dots" construction of section 2.

    Theorem (exact interpolation). Take knots x0<x1<⋯<xKx_0 < x_1 < \dots < x_K with values y0,…,yKy_0, \dots, y_K, and let gg be the piecewise-linear interpolant (straight lines between the points). Let sk=(yk−yk−1)/(xk−xk−1)s_k = (y_k - y_{k-1})/(x_k - x_{k-1}) be the slope on [xk−1,xk][x_{k-1}, x_k], for k=1,…,Kk = 1, \dots, K. Then

    N(x)=y0+s1relu⁡(x−x0)+∑k=1K−1(sk+1−sk)relu⁡(x−xk)N(x) = y_0 + s_1 \operatorname{relu}(x - x_0) + \sum_{k=1}^{K-1} (s_{k+1} - s_k) \operatorname{relu}(x - x_k)

    equals gg on [x0,xK][x_0, x_K]. It is a one-hidden-layer network with KK units: input weights 1, biases −x0,…,−xK−1-x_0, \dots, -x_{K-1}, output weights s1s_1 and sk+1−sks_{k+1} - s_k, and output bias y0y_0.

    Proof.

    1. NN is continuous and piecewise linear, with joints only at x0,…,xK−1x_0, \dots, x_{K-1}.
    2. At x=x0x = x_0 every ReLU is zero, so N(x0)=y0=g(x0)N(x_0) = y_0 = g(x_0).
    3. Take xx in an interval (xj,xj+1)(x_j, x_{j+1}). The units with joints x0,…,xjx_0, \dots, x_j are active (each has slope 1), and the others are zero. So the slope of NN there is s1+(s2−s1)+⋯+(sj+1−sj)=sj+1s_1 + (s_2 - s_1) + \dots + (s_{j+1} - s_j) = s_{j+1}. The sum telescopes: every middle term cancels.
    4. NN and gg start at the same value and have the same slope on every interval, so they are equal on [x0,xK][x_0, x_K]. ■\blacksquare

    Theorem (approximation of any continuous ff on [a,b][a, b]). For every continuous ff and every ε>0\varepsilon > 0 there is a one-hidden-layer ReLU network gg with sup⁡[a,b]∣f−g∣<ε\sup_{[a, b]} |f - g| < \varepsilon.

    Proof.

    1. A continuous function on a closed, bounded interval is uniformly continuous: there is δ>0\delta > 0 such that ∣x−x′∣<δ|x - x'| < \delta implies ∣f(x)−f(x′)∣<ε|f(x) - f(x')| < \varepsilon.
    2. Choose knots a=x0<⋯<xK=ba = x_0 < \dots < x_K = b with spacing less than δ\delta. Set yk=f(xk)y_k = f(x_k) and let gg be the interpolant. By the previous theorem, gg is a ReLU network.
    3. For x∈[xk,xk+1]x \in [x_k, x_{k+1}], g(x)=λf(xk)+(1−λ)f(xk+1)g(x) = \lambda f(x_k) + (1 - \lambda) f(x_{k+1}) for some λ∈[0,1]\lambda \in [0, 1]. Then ∣f(x)−g(x)∣≤λ∣f(x)−f(xk)∣+(1−λ)∣f(x)−f(xk+1)∣<ε|f(x) - g(x)| \le \lambda |f(x) - f(x_k)| + (1 - \lambda)|f(x) - f(x_{k+1})| < \varepsilon, because xx is within δ\delta of both knots. ■\blacksquare

    Rate. For a twice-differentiable ff and knot spacing hh, the interpolation error is at most h2max⁡∣f′′∣/8h^2 \max|f''| / 8. Halve hh (twice the units) and the error falls by a factor 4. In dd dimensions, a grid of spacing hh has about h−dh^{-d} cells, so a grid-based construction needs a number of units that grows exponentially with dd: the curse of dimensionality.

    What the theorem does not give #

    • Width. HH can be huge, exponential in dd in the worst case.
    • Learnability. The weights exist; nothing says gradient descent finds them. For example, networks trained by gradient descent fit low frequencies first (spectral bias, Rahaman et al. 2019), so fine details can take very long to learn.
    • Generalization. The theorem approximates a known ff. It says nothing about learning ff from finite, noisy samples (lesson 17).
    • Outside KK. No control at all. Far from its joints, a ReLU network is affine.
    Barron's theorem: a rate without the explicit dd

    Barron (1993) gives a rate that does not show dd in the exponent. Let f^\hat f be the Fourier transform of ff and Cf=∫∥ω∥ ∣f^(ω)∣ dωC_f = \int \|\omega\|\, |\hat f(\omega)|\, d\omega (finite for "smooth enough" functions). Then for every probability measure μ\mu on the ball of radius rr there is a one-hidden-layer sigmoidal network fHf_H with HH units and

    ∫(f(x)−fH(x))2 μ(dx)≤(2rCf)2H.\int (f(x) - f_H(x))^2 \, \mu(dx) \le \frac{(2 r C_f)^2}{H}.

    The mean squared error falls like 1/H1/H in any dimension. The catch: CfC_f itself can grow quickly with dd for many functions, so the curse of dimensionality moves into the constant.

    Depth separation #

    Shallow, 1-D. HH ReLU units in one hidden layer give at most H+1H + 1 pieces (section 2).

    Theorem (pieces of a deep ReLU network, 1-D input). A network R→R\mathbb{R} \to \mathbb{R} with KK hidden layers of width DD has at most (D+1)K(D + 1)^K linear pieces.

    Proof.

    1. After the first hidden layer, every unit output is piecewise linear in xx, with at most D+1D + 1 pieces in total (all joints together).
    2. Suppose that after layer ll all unit outputs are linear on each of pp pieces. A unit of layer l+1l + 1 computes relu⁡\operatorname{relu} of an affine combination of these outputs. On each piece, the combination is a linear function of xx, so the ReLU adds at most one joint inside that piece.
    3. The DD units of layer l+1l + 1 add at most DD joints inside each piece, which splits it into at most D+1D + 1 pieces. So after layer l+1l + 1 there are at most p(D+1)p(D + 1) pieces.
    4. Start with p=1p = 1 (no layer yet) and repeat KK times: at most (D+1)K(D + 1)^K. The output layer is affine and adds no joint. ■\blacksquare

    The tent map reaches exponential growth. tt maps [0,1][0, 1] onto [0,1][0, 1] twice (once going up, once going down). So every composition doubles the pieces: the kk-fold composition t(k)t^{(k)} is a sawtooth with 2k2^k pieces. Its values are 0,1,0,1,…0, 1, 0, 1, \dots at x=j/2kx = j/2^k. It uses kk hidden layers of 2 units (2k2k units). A network with one hidden layer needs 2k−12^k - 1 joints, so at least 2k−12^k - 1 units, to represent it.

    Telgarsky's theorem and a caveat

    Telgarsky (2016) turns the sawtooth into an approximation result. For every kk there are functions computed by networks with Θ(k3)\Theta(k^3) layers and Θ(1)\Theta(1) units per layer that networks with O(k)O(k) layers cannot approximate (in the L1L^1 sense, up to a fixed constant error) unless they have Ω(2k)\Omega(2^k) units. The proof counts oscillations: a shallow network cannot cross a level often enough.

    A caveat (Prince, Understanding Deep Learning, §4.5): the regions of a deep network are strongly dependent on each other, because later layers reuse the same folds. More regions help only if the target has matching structure, such as composition, repetition or symmetry. "More regions" is not the same as "more useful capacity".

    Answers to section 1. (1) Only affine maps x↦xW+bx \mapsto xW + b, with rank⁡(W)\operatorname{rank}(W) at most the smallest width. The ten layers add nothing that one layer cannot do. (2) Network B. The tent-map construction gives 210=10242^{10} = 1024 pieces with 20 units, while A has at most 1000+1=10011000 + 1 = 1001 pieces.

    Quick check

    What does the universal approximation theorem guarantee for a continuous ff on [0,1]d[0, 1]^d?

    4. Worked example #

    Approximate f(x)=x2f(x) = x^2 on [0,2][0, 2] with a ReLU network.

    Knots 0,1,20, 1, 2 (spacing h=1h = 1). The values are y=(0,1,4)y = (0, 1, 4). The slopes are s1=(1−0)/1=1s_1 = (1 - 0)/1 = 1 and s2=(4−1)/1=3s_2 = (4 - 1)/1 = 3. The output weights are c0=s1=1c_0 = s_1 = 1 and c1=s2−s1=2c_1 = s_2 - s_1 = 2, so

    N(x)=0+1⋅relu⁡(x)+2relu⁡(x−1).N(x) = 0 + 1 \cdot \operatorname{relu}(x) + 2 \operatorname{relu}(x - 1).

    This is a network with two hidden units: input weights (1,1)(1, 1), biases (0,−1)(0, -1), output weights (1,2)(1, 2), output bias 0.

    • Values. N(0)=0N(0) = 0. N(1)=1+2⋅0=1N(1) = 1 + 2 \cdot 0 = 1. N(2)=2+2⋅1=4N(2) = 2 + 2 \cdot 1 = 4. ✓
    • Slopes. On (0,1)(0, 1) only relu⁡(x)\operatorname{relu}(x) is active: slope 1. On (1,2)(1, 2) both are active: slope 1+2=31 + 2 = 3. ✓
    • Error. At x=0.5x = 0.5: N=0.5N = 0.5, f=0.25f = 0.25, error 0.250.25. The bound is h2max⁡∣f′′∣/8=1⋅2/8=0.25h^2 \max|f''|/8 = 1 \cdot 2/8 = 0.25. It is reached at the midpoints 0.50.5 and 1.51.5.

    Knots 0,0.5,1,1.5,20, 0.5, 1, 1.5, 2 (spacing h=0.5h = 0.5). The values are 0,0.25,1,2.25,40, 0.25, 1, 2.25, 4. The slopes are 0.5,1.5,2.5,3.50.5, 1.5, 2.5, 3.5. The output weights are c0=0.5c_0 = 0.5 and the slope changes 1.5−0.5=11.5 - 0.5 = 1, 2.5−1.5=12.5 - 1.5 = 1, 3.5−2.5=13.5 - 2.5 = 1:

    N(x)=0.5relu⁡(x)+relu⁡(x−0.5)+relu⁡(x−1)+relu⁡(x−1.5).N(x) = 0.5\operatorname{relu}(x) + \operatorname{relu}(x - 0.5) + \operatorname{relu}(x - 1) + \operatorname{relu}(x - 1.5).

    The largest error is 0.0625=0.25/40.0625 = 0.25/4: twice the units give a quarter of the error (the h2h^2 rate). This network has H=4H = 4 units and 3H+1=133H + 1 = 13 parameters (an input weight, a bias and an output weight per unit, plus the output bias).

    5. In code #

    PyTorch and NumPy check the counts, the collapse, the worked example and the tent map.

    import numpy as np
    import torch
    from torch import nn
    
    torch.manual_seed(0)
    
    # 1. Parameter count of a transformer-style FFN, D = 1024, hidden width 4D.
    ffn = nn.Sequential(nn.Linear(1024, 4096), nn.GELU(), nn.Linear(4096, 1024))
    print(sum(p.numel() for p in ffn.parameters()))        # 8393728 = 8 D^2 + 5 D
    
    # 2. Without the nonlinearity, two layers are one affine map.
    f1, f2 = nn.Linear(5, 7), nn.Linear(7, 3)
    x = torch.randn(4, 5)
    W = f2.weight @ f1.weight                  # PyTorch layout: (out, in)
    b = f2.weight @ f1.bias + f2.bias
    print(torch.allclose(f2(f1(x)), x @ W.T + b, atol=1e-6))   # True
    
    # 3. The worked example: N(x) = relu(x) + 2 relu(x - 1) against x^2 on [0, 2].
    xs = np.linspace(0, 2, 2001)
    N = np.maximum(xs, 0) + 2 * np.maximum(xs - 1, 0)
    print(np.abs(N - xs**2).max())             # 0.25 (at x = 0.5 and x = 1.5)
    
    # 4. Depth: k compositions of the tent map t(x) = 2 relu(x) - 4 relu(x - 1/2).
    t = lambda u: 2 * np.maximum(u, 0) - 4 * np.maximum(u - 0.5, 0)
    grid = np.linspace(0, 1, 2**12 + 1)        # dyadic grid: contains every joint
    for k in (1, 3, 10):
        y = grid.copy()
        for _ in range(k):
            y = t(y)
        slopes = np.diff(y) / np.diff(grid)
        pieces = 1 + np.count_nonzero(np.abs(np.diff(slopes)) > 1e-9)
        print(k, 2 * k, pieces)                # 1 2 2 / 3 6 8 / 10 20 1024
    

    The FFN count is 1024⋅4096+4096+4096⋅1024+1024=8,393,7281024 \cdot 4096 + 4096 + 4096 \cdot 1024 + 1024 = 8{,}393{,}728. The last loop prints 2, 8 and 1024 pieces for 2, 6 and 20 units.

    6. Where it shows up #

    • Transformers. Each block has the feed-forward MLP D→4D→DD \to 4D \to D with 8D28D^2 weights, against 4D24D^2 for the attention projections (lesson 11). Mixture-of-experts layers replace this one MLP by many (lesson 15).
    • Classifiers and regressors. An MLP on top of features is the standard "head" of a vision or language model; a linear probe is the special case with no hidden layer (lesson 14).
    • ML for science. PINNs and neural fields are coordinate MLPs. The theorem says a solution can be represented; it does not say it can be learned. Spectral bias is why Fourier features (Tancik et al. 2020) or sine activations (SIREN, Sitzmann et al. 2020) are used for fields with fine scales.
    • Operator learning. Chen and Chen (1995) proved a universal approximation theorem for nonlinear operators. It is the theory behind DeepONet (Lu et al. 2021).
    • Architecture design. Depth against width is a design choice with a theory behind it: for a fixed parameter budget, deeper ReLU networks can produce far more linear regions (Prince, Fig. 4.7).

    7. Common mistakes #

    • Forgetting the biases in the parameter count. Each layer has (nl−1+1)nl(n_{l-1} + 1) n_l parameters, not nl−1nln_{l-1} n_l.
    • Putting an activation on the output layer. The last layer outputs logits or real values; a ReLU there would make negative outputs impossible.
    • "Universal approximation means a network can learn anything." It is an existence result: no width bound, no training guarantee, no statement about data.
    • Dropping the conditions. A ReLU network cannot approximate x2x^2 or sin⁡x\sin x uniformly on all of R\mathbb{R}: it is affine outside a bounded interval. The domain must be compact, and the target continuous.
    • Stacking linear layers "for capacity". Without σ\sigma they collapse to one affine map, with rank at most the narrowest width.
    • Counting regions as capacity. The many regions of a deep network depend strongly on each other.

    8. Check yourself #

    1. How many parameters does an MLP 3→4→4→23 \to 4 \to 4 \to 2 with biases have?
      Answer(3+1)⋅4+(4+1)⋅4+(4+1)⋅2=16+20+10=46(3+1)\cdot 4 + (4+1)\cdot 4 + (4+1)\cdot 2 = 16 + 20 + 10 = 46.
    2. Why does a polynomial activation fail the theorem?
      AnswerWith σ\sigma of degree kk, every one-hidden-layer network is a polynomial of degree at most kk, for any width. These polynomials form a finite-dimensional, closed subspace of the continuous functions on KK, which is not dense: it misses, for example, xk+1x^{k+1} on an interval.
    3. In the worked example, how many hidden units does the uniform grid need for a largest error of at most 10−410^{-4} on [0,2][0, 2]?
      Answerh2⋅2/8≤10−4h^2 \cdot 2/8 \le 10^{-4} gives h2≤4⋅10−4h^2 \le 4 \cdot 10^{-4}, so h≤0.02h \le 0.02. Then K=2/0.02=100K = 2/0.02 = 100 cells and 100 hidden units.
    4. Describe t∘tt \circ t for the tent map on [0,1][0, 1].
      AnswerA sawtooth with 4 pieces: values 0,1,0,1,00, 1, 0, 1, 0 at x=0,14,12,34,1x = 0, \tfrac14, \tfrac12, \tfrac34, 1, slopes ±4\pm 4.
    5. Can a ReLU network approximate sin⁡x\sin x uniformly on all of R\mathbb{R}?
      AnswerNo. Beyond its last joint the network is affine. If the slope there is nonzero, the error grows without bound. If it is zero, the network is a constant cc there, and sup⁡∣sin⁡x−c∣≥1\sup|\sin x - c| \ge 1.
    6. A linear autoencoder 784→64→784784 \to 64 \to 784 has no activations. Which maps can it represent?
      AnswerOnly affine maps x↦xW+bx \mapsto xW + b with rank⁡(W)≤64\operatorname{rank}(W) \le 64. Trained with squared error on centered data, its best solution projects onto the top-64 principal subspace, as PCA does ([linear algebra, lesson 09](/linear-algebra/09-pca-randomized-svd/)).
    Recall cardsAnswer in your head first, then reveal. Add the cards to your review deck to see them again just before you would forget.
    1. State the universal approximation theorem (Leshno et al. 1993) with its conditions.

    2. Why does an MLP without activations collapse to one layer?

    3. Where is the joint of relu⁡(wx+b)\operatorname{relu}(wx + b)?

    4. At most how many linear pieces does a one-hidden-layer ReLU network R→R\mathbb{R} \to \mathbb{R} with HH units have?

    5. In the interpolating ReLU network through knots with slopes s1,…,sKs_1, \dots, s_K, what is the output weight ckc_k of the unit with joint xkx_k?

    6. How many linear pieces does the tent map composed kk times have, and how many ReLU units does it use?

    7. Count the parameters of the transformer feed-forward block D→4D→DD \to 4D \to D.

    8. Name three things the universal approximation theorem does not give.

    9. Piecewise-linear interpolation of a smooth ff with knot spacing hh: what is the error bound, and what happens when you double the number of units?

    10. What is the parameter count of an MLP with widths n0,n1,…,nLn_0, n_1, \dots, n_L?

    Open the review →

    9. Interview angle #

    • "Why do we need nonlinearities?" — Without them, any depth collapses to one affine map, with rank at most the narrowest width.
    • "State the universal approximation theorem. Why use deep networks then?" — One hidden layer with a non-polynomial activation approximates any continuous function on a compact set. It is existence only, with no width bound. Depth can be exponentially more efficient (the sawtooth), and in practice deep networks train and generalize better.
    • "How many linear regions does a ReLU network have?" — In 1-D: at most H+1H + 1 for one layer of HH units, at most (D+1)K(D + 1)^K for KK layers of width DD; the tent map reaches 2k2^k with 2k2k units.
    • "Count the parameters of this MLP." — ∑l(nl−1+1) nl\sum_l (n_{l-1} + 1)\, n_l. Do not forget the biases.
    • "Can a ReLU network extrapolate x2x^2?" — No: far from its joints it is affine, so it grows linearly, not quadratically.

    10. Practice #

    The notebook for this lesson runs in Colab. It uses NumPy (PyTorch only for one optional check). Each exercise has a check cell and a folded solution:

    1. mlp_forward: the forward pass of an MLP in the row convention, with the shapes of every layer.
    2. count_params: the parameter count, checked against the formula (and against nn.Sequential when PyTorch is installed).
    3. relu_interpolant: the weights of the one-hidden-layer network through given knots, checked to be exact on the knots.
    4. The error of the interpolant of sin⁡\sin against the number of units: measure the slope on a log-log plot and compare it with the h2h^2 rate.
    5. sawtooth: build t(k)t^{(k)} as a deep network with 2k2k units and count its pieces.

    11. Watch and read #

    The layer picture of an MLP: weights, biases and activations as numbers flowing through layers.
    Open on YouTube · the player loads from youtube-nocookie.com when you press play
    A network output built as a sum of bent and scaled activation curves, the same idea as the hinges here.
    Open on YouTube · the player loads from youtube-nocookie.com when you press play
    Universal approximation as a picture, and why "can represent" is not "will learn".
    Open on YouTube · the player loads from youtube-nocookie.com when you press play
    The perceptron, why nonlinear activations are needed, and how layers are stacked; the second half previews the next lesson (losses and training).
    Open on YouTube · the player loads from youtube-nocookie.com when you press play
    • Michael Nielsen, Neural Networks and Deep Learning, chapter 4: A visual proof that neural nets can compute any function (free online book): the same construction with step-like units.
    • Simon Prince, Understanding Deep Learning (free PDF): chapter 3 (shallow networks, universal approximation) and chapter 4, §4.5 (shallow against deep, linear regions). The notebooks for chapter 3 draw the regions of small networks.
    • Matus Telgarsky, Benefits of depth in neural networks (2016): §1.1 and §3 (the triangle maps and the oscillation count).
    • The theorem of section 3: Leshno, Lin, Pinkus and Schocken, "Multilayer feedforward networks with a nonpolynomial activation function can approximate any function", Neural Networks 6 (1993). The journal version is not free; chapter 3 of Prince's book above gives the statement and the references.