Deep LearningMulti-Layer Perceptron

Multi-Layer Perceptron

Background
  • Universal approximation theorem (Cybenko 1989, Hornik 1991): a single hidden layer MLP can approximate any continuous function
  • MLPs generalized the perceptron by adding hidden layers and smooth non-linear activations (sigmoid, tanh, ReLU)
  • The core architecture behind feedforward neural networks in all modern deep learning
The Concept

A multi-layer perceptron stacks layers of perceptron-like units with non-linear activations between them. Each layer learns a progressively higher-level feature representation. Training uses backpropagation to compute gradients layer by layer.

How it Links
  • Every deep learning architecture (CNN, RNN, Transformer) contains MLP sub-networks (FFN layers)
  • The universal approximation theorem explains why depth + nonlinearity beats shallow linear models
  • Connects to activation function design (ReLU, GELU, SwiGLU) in modern transformers
Concrete Example
An MLP for digit recognition: the first layer detects edges, the second layer detects curves and line junctions, the third layer detects digit shapes, the output layer assigns a digit label. The layers emerge from training - they are not programmed.
Learning outcomes
  • State the multi-layer perceptron model: a stack of affine transforms interleaved with element-wise non-linear activations.
  • State the universal approximation theorem and explain why width alone is insufficient in practice (Telgarsky 2016).
  • Compare sigmoid, tanh, ReLU, Leaky ReLU, GELU, and Swish on range, gradient at the origin, and vulnerability to vanishing or dying activations.
  • Derive Glorot/Xavier and He weight initialization from a variance-preservation argument and pick the right one for a given activation.
  • Implement an MLP from scratch in NumPy with manual backpropagation and reproduce it in PyTorch and TensorFlow Keras.

TL;DR

TL;DR

A multi-layer perceptron (MLP) is a feedforward neural network: a stack of affine maps Wℓhℓ−1+bℓW_\ell h_{\ell-1} + b_\ell interleaved with element-wise non-linearities σ(⋅)\sigma(\cdot). Cybenko 1989 [1] and Hornik 1991 [2] proved that a single hidden layer of finite width with a sigmoidal (or any non-polynomial squashing) activation can uniformly approximate any continuous function on a compact set. Telgarsky 2016 [3] showed why depth still matters in practice: certain functions need exponentially more parameters when forced into a shallow architecture. Modern MLPs use ReLU [6][7] or its smooth cousins (GELU [8], Swish [9]) and a variance-preserving initialization (Xavier [4] for tanh, He [5] for ReLU). They are trained by backpropagation [10].

Intuition

A single perceptron draws one hyperplane and outputs which side of it you sit on. That is enough for AND or OR but not XOR. Stack two perceptrons: the first carves the input space into half-planes, the second combines those half-planes into a more interesting region. Stack a few more, and you can carve out any continuous region.

The MLP is exactly that picture written in matrices. Every hidden layer takes the previous activations, projects them through a learned weight matrix, adds a bias, then squashes the result through a non-linear activation. Without the non-linearity, the whole stack collapses into a single affine map (composition of linear maps is linear), and you are back to the perceptron. The non-linearity is what makes depth useful.

Three views of an MLP

Three equivalent ways to read the same equation:

  • Function composition. f(x)=fL∘fL−1∘⋯∘f1(x)f(x) = f_L \circ f_{L-1} \circ \cdots \circ f_1(x) where each fℓ(h)=σℓ(Wℓh+bℓ)f_\ell(h) = \sigma_\ell(W_\ell h + b_\ell).
  • Geometric warping. Each layer warps the input space; the final layer just runs a linear classifier on a now-easy representation.
  • Feature learning. Hidden layers learn features; the final layer is the model on those features. The deep-learning bet is that the features you would have hand-engineered fall out of gradient descent.

Math

Definition of the MLP and its forward pass

The model

For an input x∈Rd0x \in \mathbb{R}^{d_0}, an LL-layer MLP is

h0=x,hℓ=σℓ ⁣(Wℓhℓ−1+bℓ)    for ℓ=1,…,L,h_0 = x, \qquad h_\ell = \sigma_\ell\!\bigl(W_\ell h_{\ell-1} + b_\ell\bigr) \;\;\text{for } \ell = 1, \dots, L,

with weights Wℓ∈Rdℓ×dℓ−1W_\ell \in \mathbb{R}^{d_\ell \times d_{\ell-1}}, biases bℓ∈Rdℓb_\ell \in \mathbb{R}^{d_\ell}, and element-wise activation σℓ\sigma_\ell. The output hLh_L is interpreted as a regression target, a classification logit, or (after softmax) a probability vector.

Why a non-linearity is mandatory

If every σℓ\sigma_\ell is the identity, then

hL=WL(WL−1(⋯W1x+⋯ )+bL−1)+bL=(WLWL−1⋯W1) x+b′,h_L = W_L \bigl( W_{L-1} \bigl( \cdots W_1 x + \cdots \bigr) + b_{L-1} \bigr) + b_L = (W_L W_{L-1} \cdots W_1)\, x + b',

a single affine map. Depth without non-linearity buys nothing. Even one layer of element-wise non-linearity unlocks universal approximation.

Backprop in one slide

For a scalar loss L\mathcal{L}, define δℓ=∂L/∂zℓ\delta_\ell = \partial \mathcal{L} / \partial z_\ell where zℓ=Wℓhℓ−1+bℓz_\ell = W_\ell h_{\ell-1} + b_\ell is the pre-activation. Then

δL=∇hLL⊙σL′(zL),δℓ=(Wℓ+1⊤δℓ+1)⊙σℓ′(zℓ),\delta_L = \nabla_{h_L}\mathcal{L} \odot \sigma_L'(z_L), \qquad \delta_\ell = (W_{\ell+1}^\top \delta_{\ell+1}) \odot \sigma_\ell'(z_\ell),∂L∂Wℓ=δℓ hℓ−1⊤,∂L∂bℓ=δℓ.\frac{\partial \mathcal{L}}{\partial W_\ell} = \delta_\ell\, h_{\ell-1}^\top, \qquad \frac{\partial \mathcal{L}}{\partial b_\ell} = \delta_\ell.

This is reverse-mode automatic differentiation specialized to a feed-forward DAG. Cost: one backward pass per loss, with the same asymptotic complexity as one forward pass [10].

Universal approximation: Cybenko 1989 and Hornik 1991

Cybenko’s theorem (sigmoidal version)

A function σ:R→R\sigma : \mathbb{R} \to \mathbb{R} is sigmoidal if σ(t)→1\sigma(t) \to 1 as t→+∞t \to +\infty and σ(t)→0\sigma(t) \to 0 as t→−∞t \to -\infty. Cybenko proved [1]:

Let σ\sigma be any continuous sigmoidal function and let K⊂RdK \subset \mathbb{R}^d be compact. For any continuous f:K→Rf : K \to \mathbb{R} and any ϵ>0\epsilon > 0, there exist a finite NN, weights wj∈Rdw_j \in \mathbb{R}^d, biases bj∈Rb_j \in \mathbb{R}, and coefficients αj∈R\alpha_j \in \mathbb{R} such that

sup⁡x∈K ∣ f(x)  −  ∑j=1Nαj σ(wj⊤x+bj) ∣<ϵ.\sup_{x \in K}\, \Bigl|\, f(x) \;-\; \sum_{j=1}^{N} \alpha_j\, \sigma(w_j^\top x + b_j) \,\Bigr| < \epsilon.

In words: a single hidden layer of finite width with a sigmoidal activation can uniformly approximate any continuous function on a compact set.

The proof is a Hahn-Banach plus Riesz representation argument: assume the closure of finite sums is not dense in C(K)C(K), derive a non-zero signed measure that annihilates every σ(w⊤x+b)\sigma(w^\top x + b), then show that any sigmoidal σ\sigma is discriminatory, contradicting the construction. The constructive content is hidden inside the contradiction; the bound NN is not given.

Hornik’s extension

Hornik 1991 [2] generalized the theorem in two directions:

  1. The activation can be any non-constant, bounded, continuous function (not specifically sigmoidal).
  2. The result extends from C(K)C(K) to Lp(μ)L^p(\mu) for any finite measure μ\mu, with convergence in LpL^p norm.

A polynomial activation cannot do this (the span of polynomials of bounded degree is finite-dimensional), which is why ReLU is fine (non-polynomial, piecewise-linear) but σ(t)=t2\sigma(t) = t^2 is not.

What the theorem does not say

Universal approximation is an existence statement. It is silent on:

  • How wide NN must be. The required width can grow exponentially in the input dimension (curse of dimensionality).
  • Whether SGD finds the approximating weights. Optimization is a separate problem.
  • Generalization. Approximation is on the training data; test error needs additional assumptions (smoothness, margin, low intrinsic dimension).

This is the gap depth fills.

Why depth helps: Telgarsky 2016

Telgarsky [3] constructed a family of functions on [0,1][0, 1] that a deep ReLU network with Θ(k3)\Theta(k^3) layers and constant width can represent exactly, but any shallow network with two layers needs at least

width  ≥  12⋅2k\text{width} \;\ge\; \frac{1}{2} \cdot 2^{k}

to approximate within constant error. The idea is that ReLU networks with depth can implement repeated sawtooth folds: each layer doubles the number of linear pieces, so LL layers give 2L2^{L} pieces with O(L)O(L) parameters, while a shallow net needs Ω(2L)\Omega(2^L) parameters to write the same number of pieces directly.

Concretely, the function fkf_k is a triangle wave folded kk times. A 3-layer ReLU net of width 2 represents one fold; composition of kk such blocks is a (2k+1)(2k+1)-layer net with O(k)O(k) parameters. Reproducing fkf_k with a 2-layer net requires one hidden unit per linear piece, so Ω(2k)\Omega(2^k) units.

The takeaway: width and depth are not parameter-equivalent. Some functions are exponentially cheaper to express with depth, even if width alone is universal.

This complements universal approximation: depth is not strictly necessary in theory, but it is exponentially more efficient on the structured functions we actually want to learn (compositional, hierarchical, with shared sub-features) [11][12].

Activation function zoo

The activation σ\sigma is what makes depth useful, and different choices have very different optimization properties. The shapes you should know cold:

ActivationFormulaRangeGradient at 0Vanishing gradient?Where used today
Sigmoidsigma(z) = 1 / (1 + e^-z)(0, 1)0.25yes (saturates both sides)Output of binary classifiers and gates in LSTM/GRU; not used in hidden layers anymore.
Tanhtanh(z) = (e^z - e^-z) / (e^z + e^-z)(-1, 1)1.0yes (saturates)Hidden layers in classic RNNs; mostly displaced by ReLU.
ReLUmax(0, z)[0, +inf)1 (right) / 0 (left)no (right side has gradient 1)Default for CNNs and most MLPs since 2012.
Leaky ReLUmax(alpha z, z) with alpha approx 0.01(-inf, +inf)1noMitigates the dying-ReLU problem; common in GANs.
GELUz * Phi(z)(-inf, +inf)0.5noDefault in transformers (BERT, GPT-2 onwards).
Swish / SiLUz * sigma(z)(-inf, +inf)0.5noEfficientNet, Stable Diffusion U-Nets, many recent CV models.

A few facts worth memorizing:

  • Sigmoid saturates on both sides. Its derivative σ′(z)=σ(z)(1−σ(z))\sigma'(z) = \sigma(z)(1 - \sigma(z)) is at most 1/41/4, so a deep sigmoid stack multiplies derivatives in [0,1/4][0, 1/4] and the gradient vanishes geometrically with depth.
  • ReLU has gradient 1 on the active side, which is why it trains so much faster than sigmoid [6][7]. The price is the dying-ReLU failure mode: a unit with all-negative pre-activations gets zero gradient and never recovers. Leaky ReLU keeps a small slope on the left to avoid this.
  • GELU and Swish are smooth approximations of ReLU that behave better in transformers because the smooth gradient interacts better with normalization layers and very deep stacks. GELU is essentially zz times the Gaussian CDF; Swish is zz times the sigmoid [8][9].

The shapes are easier to internalize visually than from formulas. The figure below overlays sigmoid, tanh, ReLU, and GELU on a common range:

zsigma(z)sigmoidtanhReLU (scaled)GELU (scaled)

Figure 1. Sigmoid saturates on both sides; tanh saturates symmetrically around 0. ReLU and GELU stay linear on the right (good gradient) and only differ on the left, where GELU’s smooth tail avoids the dying-ReLU problem. ReLU and GELU are scaled by 1/2 vertically to share the figure.

Weight initialization

Even with the right activation, a deep stack will not train if the initial weights are wrong. The standard derivations come from a single principle: keep the variance of activations and gradients constant across layers.

Glorot/Xavier initialization (tanh) and He initialization (ReLU)

Setup

At initialization, treat the input xx to a layer as a random vector with zero mean and unit variance per coordinate, and treat the weights WijW_{ij} as iid with mean zero and variance Var(W)\mathrm{Var}(W), independent of xx. Look at one pre-activation:

zj=∑i=1ninWji xi,z_j = \sum_{i=1}^{n_{\text{in}}} W_{ji}\, x_i,

so E[zj]=0\mathbb{E}[z_j] = 0 and

Var(zj)=nin Var(W) Var(x).\mathrm{Var}(z_j) = n_{\text{in}}\, \mathrm{Var}(W)\, \mathrm{Var}(x).

For the pre-activation variance to equal the input variance we need

Var(W)=1nin.\mathrm{Var}(W) = \frac{1}{n_{\text{in}}}.

Glorot/Xavier (tanh)

For tanh, the activation acts approximately linearly near zero, so the same condition applies on the backward pass with noutn_{\text{out}} in place of ninn_{\text{in}}. Glorot and Bengio [4] compromised between the two by averaging:

Var(W)=2nin+nout.\mathrm{Var}(W) = \frac{2}{n_{\text{in}} + n_{\text{out}}}.

In practice this is sampled either as Wij∼N(0,2/(nin+nout))W_{ij} \sim \mathcal{N}(0, 2/(n_{\text{in}} + n_{\text{out}})) or uniformly on [−6/(nin+nout), 6/(nin+nout)][-\sqrt{6/(n_{\text{in}} + n_{\text{out}})},\, \sqrt{6/(n_{\text{in}} + n_{\text{out}})}] (same variance).

He (ReLU)

ReLU kills half of the pre-activations: Var(ReLU(z))≈12Var(z)\mathrm{Var}(\text{ReLU}(z)) \approx \tfrac{1}{2}\mathrm{Var}(z) when zz is symmetric around zero. To compensate, He et al. [5] doubled the variance:

Var(W)=2nin.\mathrm{Var}(W) = \frac{2}{n_{\text{in}}}.

Why it matters

Without variance preservation:

  • Too small a variance: pre-activations shrink toward zero, gradients shrink with them, and the network is stuck.
  • Too large: pre-activations explode, ReLU gradients become huge for the active half, training diverges.

He init is the default for ReLU/Leaky-ReLU/GELU networks today (torch.nn.init.kaiming_normal_); Xavier remains correct for tanh/sigmoid layers and is still used in attention’s softmax temperature.

Implementations

Three idiomatic implementations of the same network: a from-scratch NumPy MLP with manual backpropagation, a PyTorch nn.Sequential, and a TensorFlow Keras Sequential. The NumPy version is intentionally explicit; the framework versions show the production form.

python
import numpy as np

def init(d_in, d_hid, d_out, seed=0):
  rng = np.random.default_rng(seed)
  # He init for ReLU hidden, Xavier for the linear/sigmoid output.
  W1 = rng.normal(0, np.sqrt(2 / d_in),  size=(d_hid, d_in))
  b1 = np.zeros(d_hid)
  W2 = rng.normal(0, np.sqrt(1 / d_hid), size=(d_out, d_hid))
  b2 = np.zeros(d_out)
  return W1, b1, W2, b2

def relu(z):       return np.maximum(0.0, z)
def relu_grad(z):  return (z > 0).astype(z.dtype)
def sigmoid(z):    return 1.0 / (1.0 + np.exp(-z))

def forward(X, params):
  W1, b1, W2, b2 = params
  Z1 = X @ W1.T + b1            # (n, d_hid)
  H1 = relu(Z1)
  Z2 = H1 @ W2.T + b2           # (n, d_out)
  Yhat = sigmoid(Z2)
  cache = (X, Z1, H1, Z2, Yhat)
  return Yhat, cache

def bce_loss(y, yhat, eps=1e-9):
  return -np.mean(y * np.log(yhat + eps) + (1 - y) * np.log(1 - yhat + eps))

def backward(y, params, cache):
  W1, b1, W2, b2 = params
  X, Z1, H1, Z2, Yhat = cache
  n = X.shape[0]
  dZ2 = (Yhat - y) / n           # sigmoid + BCE simplification
  dW2 = dZ2.T @ H1
  db2 = dZ2.sum(0)
  dH1 = dZ2 @ W2
  dZ1 = dH1 * relu_grad(Z1)
  dW1 = dZ1.T @ X
  db1 = dZ1.sum(0)
  return dW1, db1, dW2, db2

def step(params, grads, lr):
  W1, b1, W2, b2 = params
  dW1, db1, dW2, db2 = grads
  return (W1 - lr*dW1, b1 - lr*db1, W2 - lr*dW2, b2 - lr*db2)

# XOR
X = np.array([[0,0],[0,1],[1,0],[1,1]], dtype=float)
y = np.array([[0],[1],[1],[0]], dtype=float)
params = init(2, 8, 1)
for it in range(2000):
  yhat, cache = forward(X, params)
  grads = backward(y, params, cache)
  params = step(params, grads, lr=0.5)

yhat, _ = forward(X, params)
print("XOR predictions:", yhat.round(3).ravel())
About 50 lines including init, forward, BCE loss, manual backward, and SGD. Mirrors the math 1:1.

Run the from-scratch NumPy MLP live in the browser. It learns XOR within a few hundred steps:

Idle (packages: numpy)
(no output yet)

Real-world uses

The plain MLP is rarely the headline architecture today, but it is everywhere:

DomainUseWhy an MLP works
Tabular learningClick-through rate, churn, credit riskTree ensembles still win on small/medium tabular, but DNNs catch up at scale and via embeddings (DLRM at Meta).
Transformer FFN blockTwo-layer MLP between attention layers (with GELU)About two-thirds of transformer parameters live in these MLPs; they do per-token feature transformation.
CNN classifier headFinal dense layer(s) after global poolingMaps spatial features to class logits.
Recommender embeddingsMLP on concatenated user / item / context embeddingsThe "tower" architecture in two-tower retrieval and the deep arm of Wide & Deep.
Reinforcement learningPolicy and value networksStandard for low-dimensional state spaces; CNN/Transformer encoders feed into the same MLP heads.

Pitfalls

Forget the non-linearity, lose all of deep learning

Stacking LL linear layers with no activation is mathematically a single linear layer (composition of affine maps is affine). Always check that every hidden layer has an activation; this is a surprisingly common bug when refactoring.

Dying ReLU

A ReLU unit whose pre-activation is negative on every minibatch has gradient zero and never recovers. Symptoms: sudden plateaus, fraction of dead units climbing during training. Fixes: He init at the right scale, lower learning rate, or switch to Leaky ReLU / GELU.

Wrong init for the activation

He init for ReLU and Xavier for tanh are not interchangeable. Using Xavier in a deep ReLU stack halves the variance per layer and the network silently fails to train; using He on a tanh stack doubles it and saturates the activations. Match the init to the activation.

Vanishing gradient with sigmoid in deep MLPs

The sigmoid derivative is at most 1/41/4, so a LL-layer sigmoid stack multiplies gradients by at most 4−L4^{-L} in expectation. Gradients vanish geometrically. This is the historical reason MLPs did not train past three layers until ReLU and good init landed in 2010-2015 [7][5].

Default starter MLP

For tabular data: 2-3 hidden layers, 64-512 units each, ReLU or GELU, He init, AdamW with weight decay 1e-4, batch norm or layer norm between layers, dropout 0.1 on the larger layers, cosine LR schedule with warmup. This is a strong baseline before reaching for fancier architectures.

Pop quiz

Check yourself
Score: 0 / 5(0 answered)
  1. 1. What does Cybenko 1989 (and Hornik 1991) actually prove?
  2. 2. Why does Telgarsky 2016 say depth helps when width alone is universal?
  3. 3. Which initialization should you use for a deep ReLU MLP?
  4. 4. What is the dying ReLU problem?
  5. 5. Why does removing all activations collapse an MLP to a linear model?

Interview Q&A

State and sketch a proof of the universal approximation theorem (Cybenko 1989).research

Statement. Let σ:R→R\sigma : \mathbb{R} \to \mathbb{R} be any continuous sigmoidal function. Let K⊂RdK \subset \mathbb{R}^d be compact. For any continuous f:K→Rf : K \to \mathbb{R} and any ϵ>0\epsilon > 0, there exist a finite NN, weights wj∈Rdw_j \in \mathbb{R}^d, biases bj∈Rb_j \in \mathbb{R}, and coefficients αj\alpha_j such that

sup⁡x∈K ∣ f(x)−∑j=1Nαj σ(wj⊤x+bj) ∣<ϵ.\sup_{x \in K}\, \Bigl|\, f(x) - \sum_{j=1}^{N} \alpha_j\, \sigma(w_j^\top x + b_j) \,\Bigr| < \epsilon.

Proof sketch. Let SS be the linear span of all functions of the form x↦σ(w⊤x+b)x \mapsto \sigma(w^\top x + b), restricted to KK. We want to show the closure Sˉ\bar{S} in C(K)C(K) equals C(K)C(K).

Suppose for contradiction Sˉ≠C(K)\bar{S} \neq C(K). By Hahn-Banach there is a non-zero continuous linear functional on C(K)C(K) that vanishes on Sˉ\bar{S}. By Riesz representation this functional is integration against a non-zero signed Borel measure μ\mu on KK, so

∫Kσ(w⊤x+b) dμ(x)=0for all w,b.\int_{K} \sigma(w^\top x + b)\, d\mu(x) = 0 \quad \text{for all } w, b.

Cybenko’s key step is to show that any sigmoidal σ\sigma is discriminatory: the only signed measure satisfying the above is μ=0\mu = 0, contradicting the Hahn-Banach measure being non-zero. The discriminatory property follows by sliding ww to extreme magnitudes so σ(w⊤x+b)\sigma(w^\top x + b) approaches the indicator of a half-space, then varying ww and bb to scan all half-spaces and using uniqueness of measures determined by their values on half-spaces. Therefore Sˉ=C(K)\bar{S} = C(K), completing the proof. [1]

Caveats. The proof is non-constructive (no bound on NN), and the universal-approximation property is silent about optimization (whether SGD finds these weights) and generalization (whether the approximation works off the training set). Hornik 1991 generalizes to any non-constant bounded continuous activation and to LpL^p norms [2].

Derive the backprop equations for a 2-layer MLP with ReLU and softmax cross-entropy.onsite

Forward pass on a single example:

z1=W1x+b1,h1=ReLU(z1),z2=W2h1+b2,p=softmax(z2),z_1 = W_1 x + b_1, \quad h_1 = \mathrm{ReLU}(z_1), \quad z_2 = W_2 h_1 + b_2, \quad p = \mathrm{softmax}(z_2),

with target one-hot yy and loss L=−∑kyklog⁡pk\mathcal{L} = -\sum_k y_k \log p_k.

Output layer. A standard simplification: softmax + cross-entropy makes

∂L∂z2=p−y    :=    δ2.\frac{\partial \mathcal{L}}{\partial z_2} = p - y \;\;:=\;\; \delta_2.

So ∂L/∂W2=δ2h1⊤\partial \mathcal{L} / \partial W_2 = \delta_2 h_1^\top and ∂L/∂b2=δ2\partial \mathcal{L} / \partial b_2 = \delta_2.

Hidden layer. Apply chain rule:

∂L∂h1=W2⊤δ2,δ1=∂L∂z1=(W2⊤δ2)⊙1[z1>0].\frac{\partial \mathcal{L}}{\partial h_1} = W_2^\top \delta_2, \qquad \delta_1 = \frac{\partial \mathcal{L}}{\partial z_1} = \bigl(W_2^\top \delta_2\bigr) \odot \mathbb{1}[z_1 > 0].

Then ∂L/∂W1=δ1x⊤\partial \mathcal{L} / \partial W_1 = \delta_1 x^\top and ∂L/∂b1=δ1\partial \mathcal{L} / \partial b_1 = \delta_1.

Vectorized over a minibatch. Replace xx with X∈RB×dX \in \mathbb{R}^{B \times d} and divide gradients by BB. The whole pass is O(B⋅(d0d1+d1d2))O(B \cdot (d_0 d_1 + d_1 d_2)) time and the same memory as the forward pass. [10]

Why does ReLU avoid the vanishing gradient problem that plagues sigmoid?phone

The sigmoid derivative is σ′(z)=σ(z)(1−σ(z))\sigma'(z) = \sigma(z)(1 - \sigma(z)), which is at most 1/41/4 at z=0z = 0 and decays exponentially in the tails. Backprop multiplies these per-layer derivatives, so a LL-layer sigmoid stack contracts the gradient by at most 4−L4^{-L} in expectation: 10 layers give a 10−6^{-6} shrinkage. The gradient effectively vanishes before it reaches the early layers and they stop learning.

ReLU has derivative exactly 1 on the active side and exactly 0 on the dead side. There is no contraction on the active path, so gradients flow freely through the (typically half-active) layers. The cost is the dying ReLU mode (gradient is hard zero, not just small) which is mitigated by Leaky ReLU, ELU, GELU, or Swish. This shift in 2010-2012 was as important to deep learning’s success as backprop itself [6][7].

Derive the variance-preservation argument behind He init for ReLU.onsite

Treat the input h∈Rninh \in \mathbb{R}^{n_{\text{in}}} as iid with E[hi]=0\mathbb{E}[h_i] = 0 and Var(hi)=vh\mathrm{Var}(h_i) = v_h, and weights WjiW_{ji} as iid with E[W]=0\mathbb{E}[W] = 0 and Var(W)=vW\mathrm{Var}(W) = v_W, independent of hh. The pre-activation zj=∑iWjihiz_j = \sum_i W_{ji} h_i has

Var(zj)=nin vW vh.\mathrm{Var}(z_j) = n_{\text{in}}\, v_W\, v_h.

Now apply ReLU: aj=ReLU(zj)a_j = \mathrm{ReLU}(z_j). If zjz_j is symmetric around zero, aj=zja_j = z_j with probability 1/21/2 and aj=0a_j = 0 with probability 1/21/2, so

Var(aj)=E[aj2]−E[aj]2=12Var(zj)−(12E[zj⋅1[z>0]])2≈12Var(zj),\mathrm{Var}(a_j) = \mathbb{E}[a_j^2] - \mathbb{E}[a_j]^2 = \tfrac{1}{2}\mathrm{Var}(z_j) - \bigl(\tfrac{1}{2}\mathbb{E}[z_j \cdot \mathbb{1}[z > 0]]\bigr)^2 \approx \tfrac{1}{2}\mathrm{Var}(z_j),

ignoring the small mean-shift (rigorous derivation in [5]). To keep Var(aj)=vh\mathrm{Var}(a_j) = v_h, we need

12nin vW vh=vh    ⟹    vW=2nin.\tfrac{1}{2} n_{\text{in}}\, v_W\, v_h = v_h \;\;\Longrightarrow\;\; v_W = \frac{2}{n_{\text{in}}}.

That is the He-normal init. For Xavier (tanh, which acts approximately linearly near zero) the factor of 1/21/2 is absent, giving vW=1/ninv_W = 1/n_{\text{in}}; the symmetric average between forward and backward passes then yields the standard form vW=2/(nin+nout)v_W = 2/(n_{\text{in}} + n_{\text{out}}) [4].

If width alone is universal, why do we use depth at all?research

Three reasons, in increasing depth:

  1. Representation efficiency. Telgarsky 2016 [3] exhibits functions on [0,1][0,1] that a Θ(k)\Theta(k)-deep ReLU net of constant width represents exactly with O(k)O(k) parameters, but any 2-layer ReLU net needs Ω(2k)\Omega(2^k) units. Depth gives compositional reuse: each layer doubles the number of linear pieces with O(1)O(1) extra parameters.
  2. Inductive bias. The functions we want to learn (vision pipelines, language hierarchies) are themselves compositional. A deep architecture aligns the model’s structure with the target’s structure, which improves sample complexity even when the function is realizable shallowly.
  3. Optimization landscape. Counterintuitively, deep nets are often easier to optimize than wide shallow ones with the same capacity. Empirically loss landscapes of overparameterized deep nets exhibit fewer bad local minima (Choromanska et al. 2015 and follow-ups), and the implicit bias of SGD on overparameterized models steers toward solutions that generalize. Wide shallow models do not enjoy the same implicit-bias story [11].

The high-level summary: universal approximation says depth is not strictly necessary; everything else says depth is exponentially more efficient on the structured targets we care about.

Build it yourself

A short project that takes about an evening:

  1. Implement the from-scratch NumPy MLP above for digit classification on MNIST. Two hidden layers of 256 units, ReLU, He init, plain SGD. Target above 96% on the test set.
  2. Swap ReLU for tanh and confirm Xavier init beats He init in that setting; measure the gap.
  3. Replace SGD with Adam (the next page) and watch the convergence speed jump.
  4. Stretch: implement a CNN front end and feed its features into the same MLP head. Compare to the pure-MLP baseline; the gap on MNIST is small but on CIFAR-10 it is enormous.

References

  1. Cybenko, G. (1989). Approximation by superpositions of a sigmoidal function. Mathematics of Control, Signals, and Systems 2(4), 303-314. doi:10.1007/BF02551274
  2. Hornik, K. (1991). Approximation capabilities of multilayer feedforward networks. Neural Networks 4(2), 251-257. doi:10.1016/0893-6080(91)90009-T
  3. Telgarsky, M. (2016). Benefits of depth in neural networks. Conference on Learning Theory (COLT) 2016. arXiv:1602.04485
  4. Glorot, X. and Bengio, Y. (2010). Understanding the difficulty of training deep feedforward neural networks. AISTATS 2010, JMLR W&CP 9, 249-256. https://proceedings.mlr.press/v9/glorot10a.html
  5. He, K., Zhang, X., Ren, S., and Sun, J. (2015). Delving Deep into Rectifiers: Surpassing Human-Level Performance on ImageNet Classification. IEEE International Conference on Computer Vision (ICCV) 2015. arXiv:1502.01852
  6. Nair, V. and Hinton, G. E. (2010). Rectified linear units improve restricted Boltzmann machines. Proc. 27th International Conference on Machine Learning (ICML), 807-814. https://icml.cc/Conferences/2010/papers/432.pdf
  7. Glorot, X., Bordes, A., and Bengio, Y. (2011). Deep sparse rectifier neural networks. AISTATS 2011, JMLR W&CP 15, 315-323. https://proceedings.mlr.press/v15/glorot11a.html
  8. Hendrycks, D. and Gimpel, K. (2016). Gaussian Error Linear Units (GELUs). arXiv preprint. arXiv:1606.08415
  9. Ramachandran, P., Zoph, B., and Le, Q. V. (2017). Searching for Activation Functions. arXiv preprint. arXiv:1710.05941
  10. Rumelhart, D. E., Hinton, G. E., and Williams, R. J. (1986). Learning representations by back-propagating errors. Nature 323, 533-536. doi:10.1038/323533a0
  11. Goodfellow, I., Bengio, Y., and Courville, A. (2016). Deep Learning. MIT Press. https://www.deeplearningbook.org
  12. LeCun, Y., Bengio, Y., and Hinton, G. (2015). Deep learning. Nature 521, 436-444. doi:10.1038/nature14539