Skip to content
AI360Xpert
Core ML

Multi-Layer Perceptron

A hidden layer invents new coordinates, and in those coordinates one straight line is enough. Depth is a change of representation, not extra parameter room.

The four exclusive-or cases have no separating line in the original mat coordinates, and the same four cases in the coordinates the hidden layer builds are split by one straight line
The four exclusive-or cases have no separating line in the original mat coordinates, and the same four cases in the coordinates the hidden layer builds are split by one straight line

Why Does This Exist?

Two pressure mats in a warehouse doorway, one inside and one outside, and the alert should fire when exactly one is pressed. A single perceptron can't draw that boundary. The alert cases sit on opposite corners of a square with the quiet cases on the other diagonal, and no straight line splits that pattern. That's the wall the last page ended on.

Clearing it takes two extra units.

Give the first the weights (1,1)(1, -1) and the second (1,1)(-1, 1), then clip both at zero. Unit one is nonzero only when the inside mat is pressed and the outside one isn't; unit two only in the reverse case. Each detects a pattern — an asymmetry between the mats — rather than reading an input.

Now describe the four situations using only what those two units report. Both quiet gives (0,0)(0,0). Both pressed also gives (0,0)(0,0). Inside only gives (1,0)(1,0), outside only (0,1)(0,1). The alert cases now sit at two separate corners while both quiet cases have collapsed onto the origin, so a straight line splits them: alert when the two numbers sum above 0.5.

Nothing about the doorway changed. The coordinates did. That reframe is the page — a hidden layer is a learned change of representation, and the output layer is an ordinary linear model working in the space that change produced.

Think of It Like This

Folding the paper before you cut it

Four dots on a sheet of paper: two black on one diagonal, two white on the other. Your scissors only cut straight, and you need black on one side and white on the other. Flat on the table it can't be done — every cut strands a dot on the wrong side.

So fold. Crease the sheet along the diagonal running through both black dots. The white dots come down on top of each other, out at the same distance, with both black dots on the crease itself. One straight cut parallel to the fold, done.

The scissors never bent. The paper moved. That's a hidden layer: it folds the input space, and the crease sits where one of its units switches from off to on. More layers, more creases — which is how a boundary gets as intricate as the data demands while every piece of it stays flat.

How It Actually Works

One layer, three operations

Multiply, shift, bend:

h()=ϕ(W()h(1)+b())h^{(\ell)} = \phi\big(W^{(\ell)} h^{(\ell-1)} + b^{(\ell)}\big)

h()h^{(\ell)} is the vector leaving layer \ell, h(1)h^{(\ell-1)} is what arrived from below, W()W^{(\ell)} is that layer's weight matrix, b()b^{(\ell)} its bias vector, and ϕ\phi (phi) is the nonlinearity, applied to each entry on its own. Chain them; the last output is the prediction.

Shapes are where people lose an afternoon, so here's one network in full. Tile 64 mats across the warehouse floor and sort each moment into one of four things: empty, a person walking, a pallet jack, a stack of boxes. 128 moments per batch.

  • The input batch is 128 rows by 64 columns.
  • W(1)W^{(1)} is 64 by 32 with 32 biases, so layer one passes on 128 by 32.
  • W(2)W^{(2)} is 32 by 16, so layer two passes on 128 by 16.
  • W(3)W^{(3)} is 16 by 4, so the output is 128 by 4 — one score per class per moment.

The batch dimension rides through untouched, and every weight matrix reads the width below it and writes the width above it. That's the entire shape rule. Total parameters: 2,676.

The nonlinearity is load-bearing

Remove ϕ\phi and stack two layers. You get W(2)(W(1)x)W^{(2)}(W^{(1)}x), and matrix multiplication is associative, so that's (W(2)W(1))x(W^{(2)}W^{(1)})x — one matrix, one linear layer. Depth with nothing between the layers buys literally nothing; a hundred of them still draws one flat boundary. In the doorway network the product of those two weight matrices is the zero matrix, so the version without clipping answers "no alert" to all four cases forever. Which ϕ\phi to pick is its own page.

What depth actually buys

One hidden layer, wide enough, gets within any error you name of any continuous function on a bounded closed region. Cybenko proved it for sigmoid-shaped units in 1989, Hornik generalised it in 1991, and it gets quoted as though it settles something.

It settles one thing: such a network exists. It says nothing about whether gradient descent finds it, how many units "wide enough" turns out to be — sometimes exponentially many — or how much data pins those parameters down.

Depth wins anyway, for a statable reason. Targets built in stages need exponentially fewer units in layers than flattened into one, which Telgarsky made precise in 2016. On the floor grid: layer one finds pressure edges, layer two assembles outlines, layer three names them. A single wide layer can't share that work, so it memorises every outline at every position and the unit count explodes.

Show Me the Code

Hand-set weights, so the only variable is the clipping.

import numpy as np
X = np.array([[0.0, 0], [0, 1], [1, 0], [1, 1]])  # inside mat, outside matW1 = np.array([[1.0, -1.0], [-1.0, 1.0]])  # unit 1: inside only.  unit 2: outside onlyW2 = np.array([[1.0], [1.0]])  # either asymmetry means somebody is standing there

def alerts(X: np.ndarray, nonlinear: bool) -> np.ndarray:    H = X @ W1    if nonlinear:        H = np.maximum(H, 0.0)  # drop this line and the two matrices merge into one    return (H @ W2 - 0.5).ravel() > 0

print("with ReLU   ", alerts(X, True).astype(int))print("without ReLU", alerts(X, False).astype(int))print("collapsed to", (W1 @ W2).ravel())# -> with ReLU    [0 1 1 0]# -> without ReLU [0 0 0 0]# -> collapsed to [0. 0.]

Same parameters, same architecture. One line of clipping separates the pattern you wanted from a model that says nothing to anything.

Watch Out For

Depth with no activation between the layers

The symptom is a network that matches linear regression on the same features to three decimals and stays there while you add width, add layers, train ten times longer. Nothing errors. Loss falls, then flattens where a closed-form fit would have landed in one line.

Check that an activation sits between every pair of consecutive linear layers. In hand-rolled code the usual cause is computing the activation and discarding the result, or applying it only after the final layer, where it does nothing underneath. One deliberate exception: a narrow linear projection feeding another linear layer to cut parameter count. Still one linear map.

Reading universal approximation as a guarantee

"A network can approximate any function" gets used to justify not thinking about architecture. It's an existence claim, so it can't be violated and it can't help you. The weights it promises may sit where the optimiser never reaches from your initialisation, and the width it needs can grow exponentially with the input dimension.

The tell is widening one hidden layer to 4,096 units instead of adding a second, then blaming the data when the loss plateaus. Read the curves for what they say about capacity: training error near zero means capacity to spare and a generalisation problem, so more width is the wrong lever.

The Quick Version

  • A layer is a matrix multiply, a bias, and a nonlinearity applied entry by entry. An MLP is several in sequence.
  • The hidden layer builds coordinates where the answer is linearly separable, and the output layer is a linear model in that new space.
  • Exclusive-or needs two hidden units, each detecting a pattern rather than reading an input.
  • Without the nonlinearity, any stack of linear layers collapses into one matrix.
  • Batch rides through untouched; each matrix reads the width below and writes the width above.
  • Universal approximation promises existence. Not that the optimiser finds it, not that the width is affordable.

Related concepts