AI Knowledge Tree

The perceptron

Run the perceptron update rule and prove convergence on linearly separable data with Novikoff's theorem.

⏱ 28 min

The perceptron is the simplest classifier with a learning rule[1]: a linear discriminant trained by walking through the data and nudging the weight vector each time it misclassifies. It is a useful first stop because the algorithm is trivial, its convergence proof is short, and the geometric intuition (margin matters) seeds the SVM that comes next.

The classifier

For binary labels yi∈{−1,+1}y_i \in \{-1, +1\} and features xi∈Rdx_i \in \mathbb{R}^d (with a constant 1 appended for an intercept), predict

y^=sign⁡(w⊤x).\hat y = \operatorname{sign}(w^\top x).

A point is classified correctly when yi w⊤xi>0y_i\, w^\top x_i > 0. The decision boundary is the hyperplane w⊤x=0w^\top x = 0.

The update rule

Start with w=0w = 0 and pass through the data. On a mistake (a point with yi w⊤xi≤0y_i\, w^\top x_i \le 0), update

w←w+yixi.w \leftarrow w + y_i x_i.

Geometrically: rotate ww slightly toward the side of the misclassified point. Repeat until no mistakes occur in a full pass.

Novikoff's convergence theorem

If the data are linearly separable with a margin γ>0\gamma > 0, the perceptron makes a bounded number of mistakes[2].

Theorem. Assume there is a unit-norm vector w⋆w^\star (∥w⋆∥=1\lVert w^\star\rVert = 1) and γ>0\gamma > 0 such that yi w⋆⊤xi≥γy_i\, w^{\star\top} x_i \ge \gamma for all ii, and that ∥xi∥≤R\lVert x_i\rVert \le R for all ii. Then the perceptron converges after at most (R/γ)2(R/\gamma)^2 updates.

Proof. Let w(k)w^{(k)} be the weight after kk updates. Two invariants:

Lower bound on alignment with w⋆w^\star. Each update with example (xi,yi)(x_i, y_i) increases w⊤w⋆w^\top w^\star by yi xi⊤w⋆≥γy_i\, x_i^\top w^\star \ge \gamma. So w(k)⊤w⋆≥kγw^{(k)\top} w^\star \ge k\gamma, and by Cauchy-Schwarz ∥w(k)∥≥kγ\lVert w^{(k)}\rVert \ge k\gamma.

Upper bound on weight norm. The squared norm grows by

∥w+yixi∥2=∥w∥2+2yiw⊤xi+∥xi∥2≤∥w∥2+R2,\lVert w + y_i x_i\rVert^2 = \lVert w\rVert^2 + 2 y_i w^\top x_i + \lVert x_i\rVert^2 \le \lVert w\rVert^2 + R^2,

using that updates happen only on mistakes (yiw⊤xi≤0y_i w^\top x_i \le 0). So ∥w(k)∥2≤kR2\lVert w^{(k)}\rVert^2 \le k R^2, i.e. ∥w(k)∥≤k R\lVert w^{(k)}\rVert \le \sqrt k\, R.

Combining, kγ≤∥w(k)∥≤k Rk\gamma \le \lVert w^{(k)}\rVert \le \sqrt k\, R, so k≤(R/γ)2k \le (R/\gamma)^2. ■\qquad\blacksquare

The bound depends on the margin γ\gamma, not on the dataset size or dimension. A large margin makes learning fast; a tiny margin makes it slow. This is exactly the geometric quantity the SVM will maximize.

What the perceptron does not do

  • It does not give probabilities.
  • On nonseparable data it cycles forever (no convergence). Variants like the averaged perceptron or kernel perceptron address this.
  • The hyperplane it finds is any separating hyperplane, not the maximum-margin one. The next lesson fixes this by explicitly maximizing the margin.
The perceptron walks a separating hyperplane into place, nudging the weight vector by each misclassified point until the two classes are split.
The perceptron walks a separating hyperplane into place, nudging the weight vector by each misclassified point until the two classes are split.

Check it on arrays

python · numpy
import numpy as np

rng = np.random.default_rng(0)

# Linearly separable dataset
n_per = 100
X_pos = rng.normal(loc=[2.5, 1.0], size=(n_per, 2))
X_neg = rng.normal(loc=[-1.5, -1.0], size=(n_per, 2))
X = np.vstack([X_pos, X_neg])
X = np.column_stack([np.ones(len(X)), X])
y = np.array([1] * n_per + [-1] * n_per)

def perceptron(X, y, max_passes=100):
    w = np.zeros(X.shape[1])
    mistakes = 0
    for _ in range(max_passes):
        any_mistake = False
        for i in range(len(y)):
            if y[i] * (w @ X[i]) <= 0:
                w += y[i] * X[i]
                mistakes += 1
                any_mistake = True
        if not any_mistake:
            return w, mistakes
    return w, mistakes

w, mistakes = perceptron(X, y)
print(f"converged after {mistakes} mistakes")

# Margin and bound: estimate gamma and R, check Novikoff prediction
acc = np.mean(np.sign(X @ w) == y)
print(f"training accuracy: {acc:.3f}")

R = np.max(np.linalg.norm(X, axis=1))
margins = y * (X @ w) / np.linalg.norm(w[1:])         # geometric margins (ignore intercept)
gamma = margins.min()
bound = (R / gamma)**2 if gamma > 0 else float("inf")
print(f"R = {R:.2f}, geometric margin gamma = {gamma:.3f}")
print(f"Novikoff bound (R/gamma)^2 = {bound:.0f}, actual mistakes = {mistakes}")

The perceptron separates the two Gaussian blobs, achieves 100% training accuracy, and the actual mistake count sits below the Novikoff bound.

Exercises

Exercise 1. Two one-dimensional points are given: x+=1x_+ = 1 with y+=+1y_+ = +1 and x−=−1x_- = -1 with y−=−1y_- = -1. Using w⋆=1w^\star = 1 (unit norm in 1D), compute the margin γ\gamma and radius RR, then the Novikoff bound on the number of perceptron updates.

Solution

Step 1. The functional score of each point under w⋆=1w^\star = 1 is yi w⋆xiy_i\, w^\star x_i. For x+=1x_+ = 1: (+1)(1)(1)=1(+1)(1)(1) = 1. For x−=−1x_- = -1: (−1)(1)(−1)=1(-1)(1)(-1) = 1. Both equal 11, so the margin is γ=min⁡iyiw⋆xi=1\gamma = \min_i y_i w^\star x_i = 1.

Step 2. The radius bounds the input norm: R=max⁡i∣xi∣=1R = \max_i |x_i| = 1.

Step 3. Novikoff's theorem caps the updates at

(Rγ)2=(11)2=1.\left(\frac{R}{\gamma}\right)^2 = \left(\frac{1}{1}\right)^2 = 1.

A single mistake suffices: starting from w=0w = 0, the first misclassified point updates ww to a separating direction, after which both points are correct.

Exercise 2. Show that scaling every input by a constant c>0c > 0 (so xi↦c xix_i \mapsto c\, x_i) leaves the geometric margin γ/R\gamma/R unchanged, hence leaves the Novikoff bound unchanged.

Solution

Step 1. Under xi↦c xix_i \mapsto c\, x_i, the separating direction w⋆w^\star is unchanged (the same hyperplane through the origin separates the rescaled data). The functional margin scales: yi w⋆⊤(c xi)=c (yi w⋆⊤xi)≥cγy_i\, w^{\star\top}(c\, x_i) = c\, (y_i\, w^{\star\top} x_i) \ge c\gamma, so the new margin is γ′=cγ\gamma' = c\gamma.

Step 2. The radius scales the same way: ∥c xi∥=c∥xi∥≤cR\lVert c\, x_i\rVert = c\lVert x_i\rVert \le cR, so R′=cRR' = cR.

Step 3. The Novikoff bound depends on the ratio:

(R′γ′)2=(cRcγ)2=(Rγ)2.\left(\frac{R'}{\gamma'}\right)^2 = \left(\frac{cR}{c\gamma}\right)^2 = \left(\frac{R}{\gamma}\right)^2.

The cc cancels. Rescaling all inputs cannot make the perceptron converge in fewer steps; only the dimensionless ratio R/γR/\gamma controls the bound.

Exercise 3 (code). The XOR labels are not linearly separable. Run the perceptron on the four XOR points for up to 1000 passes and confirm it never completes a mistake-free pass (it cycles), and that no setting of ww it reaches classifies all four correctly.

Solution
python · numpy
import numpy as np

# Bias-augmented XOR: first column is the constant intercept feature
X = np.array([[1, 0, 0], [1, 0, 1], [1, 1, 0], [1, 1, 1]], float)
y = np.array([-1, 1, 1, -1])           # XOR: differ -> +1, same -> -1

def perceptron(X, y, max_passes):
    w = np.zeros(X.shape[1])
    converged = False
    for _ in range(max_passes):
        any_mistake = False
        for i in range(len(y)):
            if y[i] * (w @ X[i]) <= 0:
                w += y[i] * X[i]
                any_mistake = True
        if not any_mistake:
            converged = True
            break
    return w, converged

w, converged = perceptron(X, y, max_passes=1000)
acc = np.mean(np.sign(X @ w) == y)
print(f"converged: {converged}, accuracy at stop: {acc:.2f}")
assert not converged                    # no mistake-free pass in 1000 tries
assert acc < 1.0                        # the final w cannot separate XOR

The loop exhausts all 1000 passes without a clean sweep: XOR has no linear separator, so Novikoff's premise (a positive margin) fails and the convergence guarantee does not apply. This is the gap the next lessons close by lifting the data into a richer feature space.

The next lesson asks for more: among all separating hyperplanes, which one is the best by a margin argument?


References

  1. [1]Rosenblatt, F. (1958). "The perceptron: a probabilistic model for information storage and organization in the brain". Psychological Review, 65(6), 386-408. The original perceptron model and learning rule (doi:10.1037/h0042519).↩
  2. [2]Bishop, C. M. (2006). Pattern Recognition and Machine Learning. Springer. §4.1.7 states and proves the perceptron convergence theorem.↩