Module A · Lecture 03

The Perceptron & Biological Inspiration

The first trainable artificial neuron — a loose analogy to a biological neuron, a precise learning rule, and a hard limitation that shaped 15 years of AI history.

⏱ ~60 min 🧩 Builds on: Lectures 1–2 🎯 CO1
🧭 Why we're learning this now

Lecture 2 defined what learning means in the abstract. Now let's build the smallest possible thing that actually does it: a single trainable neuron. Understanding exactly what one neuron can and cannot do turns out to be the fastest route to understanding why we need more than one.

  • Describe the biological-neuron analogy behind artificial neurons, and state clearly where the analogy stops.
  • State the McCulloch-Pitts neuron (1943) and Rosenblatt's Perceptron (1958) and the equation each computes.
  • Derive and apply the perceptron learning rule to update weights from a misclassified example.
  • Interpret a trained perceptron geometrically as a linear decision boundary (hyperplane).
  • Hand-train a perceptron on the AND logic gate and verify the result numerically.
  • Explain why the perceptron cannot represent XOR, and why this motivated multi-layer networks.

1. A Biological Analogy (Not a Literal Model)

Artificial neurons take their name — and a loose structural inspiration — from biological neurons, but the resemblance is a starting metaphor, not an engineering blueprint. It is still a useful way to build intuition for the first time:

The analogy
  • Dendrites receive signals from other neurons  →  inputs \(x_1,\dots,x_n\) to an artificial neuron.
  • Soma (cell body) accumulates incoming signal and "decides" whether to fire  →  the weighted sum \(\sum_i w_i x_i + b\) followed by an activation function.
  • Axon carries the neuron's output signal onward  →  the neuron's scalar output, passed as input to the next layer.
⚠ Where the analogy breaks down

Real biological neurons communicate with complex, timed electrochemical spike trains, are wired by evolution and experience into recurrent, densely interconnected circuits, and adapt through mechanisms far richer than a single scalar weight update. Treat "artificial neuron" as a name inspired by biology, not a simulation of it.

2. The McCulloch-Pitts Neuron (1943)

The first mathematical model of a neuron predates the perceptron by 15 years. McCulloch and Pitts (1943) proposed a binary threshold unit: sum the binary inputs, and fire (output 1) if the sum meets or exceeds a fixed threshold, otherwise stay silent (output 0). It had no learning rule — the threshold and connections were fixed by hand — but it established the core idea that a network of simple binary units could, in principle, compute logical functions.

3. Rosenblatt's Perceptron (1958)

Rosenblatt's key addition was to attach a learning rule to the McCulloch-Pitts idea, and to allow real-valued, adjustable weights instead of fixed connections. The perceptron computes a weighted sum of its inputs, adds a bias, and passes the result through a step function:

$$\hat y = \text{step}(w\cdot x + b), \qquad \text{step}(z) = \begin{cases}1 & z \ge 0 \\ 0 & z < 0\end{cases}$$

Here \(w=[w_1,\dots,w_n]\) are the weights, \(b\) is the bias (equivalent to a threshold), and \(x=[x_1,\dots,x_n]\) is the input vector. Unlike the McCulloch-Pitts neuron, these weights are learned from labeled examples rather than fixed by a designer.

A single perceptron with two inputs — every arrow is a weight, the node applies the weighted sum plus bias, then the step function.

4. The Perceptron Learning Rule

Training a perceptron means repeatedly presenting labeled examples \((x,y)\) and nudging the weights whenever the prediction is wrong:

$$w \leftarrow w + \eta(y-\hat y)\,x \qquad\qquad b \leftarrow b + \eta(y-\hat y)$$

Here \(\eta\) (eta) is the learning rate, a small positive number controlling the size of each update. Notice what happens in each case: if \(\hat y = y\) (correct), the error term \((y-\hat y)\) is zero and nothing changes. If the perceptron predicted 0 but should have predicted 1, the error is \(+1\) and weights move in the direction of \(x\) (making the weighted sum larger next time). If it predicted 1 but should have predicted 0, the error is \(-1\) and weights move away from \(x\).

5. Geometric Interpretation

The equation \(w\cdot x + b = 0\) defines a straight line in 2D (a hyperplane in higher dimensions). The perceptron's decision rule simply asks which side of that line a point falls on: \(w\cdot x + b \ge 0\) classifies as 1, otherwise 0. Training a perceptron is therefore geometrically equivalent to searching for a straight line that separates the "1" points from the "0" points — which is only possible if the data is linearly separable.

6. Worked Example: Learning the AND Gate

We train a 2-input perceptron on the AND logic function, which is linearly separable. Data (in the order they are processed), starting weights \(w=[0,0]\), bias \(b=0\), learning rate \(\eta=0.1\), threshold convention \(\text{step}(z)=1 \text{ if } z\ge 0\):

x1x2target y (AND)
000
010
100
111

We now trace one full pass over the four examples, in order, updating the weights whenever the prediction is wrong. Every number is written out below — nothing is left hidden.

Initial state

\(w=[0,0]\), \(b=0\), \(\eta=0.1\). We process the 4 AND examples in the order listed in the table above.

Example 1 — x = (0,0), target y = 0

Weighted sum: \(z=w_1x_1+w_2x_2+b=0(0)+0(0)+0=0\). Since \(\text{step}(z)=1\) whenever \(z\ge0\), and here \(0\ge0\), the perceptron predicts \(\hat y=1\) — but the target is \(y=0\), so this is misclassified.

Apply the learning rule with error \(y-\hat y=0-1=-1\):

$$w\leftarrow[0,0]+0.1(-1)[0,0]=[0,0] \qquad\qquad b\leftarrow0+0.1(-1)=\mathbf{-0.1}$$

The weights themselves don't move here, because both inputs are 0 — only the bias moves.

Example 2 — x = (0,1), target y = 0

Weighted sum: \(z=0(0)+0(1)+(-0.1)=-0.1\). Since \(-0.1<0\), \(\text{step}(-0.1)=0=\hat y\), which matches \(y=0\)correct, no update. \(w\) stays \([0,0]\), \(b\) stays \(-0.1\).

Example 3 — x = (1,0), target y = 0

Weighted sum: \(z=0(1)+0(0)+(-0.1)=-0.1\). Again \(\text{step}(-0.1)=0=\hat y=y\)correct, no update. \(w\) stays \([0,0]\), \(b\) stays \(-0.1\).

Example 4 — x = (1,1), target y = 1

Weighted sum: \(z=0(1)+0(1)+(-0.1)=-0.1\). \(\text{step}(-0.1)=0\), but the target is \(y=1\)misclassified again, this time in the opposite direction.

Error \(y-\hat y=1-0=1\):

$$w\leftarrow[0,0]+0.1(1)[1,1]=\mathbf{[0.1,\ 0.1]} \qquad\qquad b\leftarrow-0.1+0.1(1)=\mathbf{0}$$

After one full pass over the data

\(w=[0.1,\ 0.1]\), \(b=0\) — two of the four examples triggered an update (examples 1 and 4), two were already correctly classified (examples 2 and 3). Not yet a valid solution, but the weights have moved in the right direction.

You can replay the same pass interactively below — useful for testing yourself before moving on:

After this single pass, \(w=[0.1, 0.1]\), \(b=0\) — closer to a correct solution, but not there yet (check: for \((0,0)\), \(z=0\ge0\) still predicts 1 instead of 0). Continuing this exact update rule for several more passes over the data converges to weights such as \(w\approx[0.2,\,0.2]\), \(b\approx-0.3\) — one valid separating solution (run the accompanying code to see the full trace and confirm convergence). The plot below shows this converged decision boundary against all four AND points:

The converged decision boundary \(0.2x_1+0.2x_2-0.3=0\) (i.e. \(x_2=1.5-x_1\)) separating the single "1" point (top right) from the three "0" points.

7. The XOR Problem and the First AI Winter

AND, OR, and NOT can all be computed by a single perceptron, because their "1" and "0" outputs are linearly separable. XOR cannot: plot its four points — \((0,0)\to0\), \((0,1)\to1\), \((1,0)\to1\), \((1,1)\to0\) — and no single straight line can separate the two classes; the "1" points sit on opposite corners from each other. Minsky and Papert proved this formally in 1969, and their book's broader critique of the perceptron's limitations contributed to a sharp, decade-long collapse in neural network research funding and interest — the first "AI winter."

The resolution, previewed

A single perceptron draws one straight line. But stacking perceptrons into layers — feeding the output of one layer as the input to another, separated by a nonlinearity — can carve out arbitrarily complex, curved decision regions, including XOR. That architecture, the feedforward network, is exactly the subject of Lecture 4, and the algorithm that trains it (backpropagation) is the subject of Lecture 8.

8. Summary

Key takeaways
  • The perceptron computes \(\hat y=\text{step}(w\cdot x+b)\) — a weighted sum through a hard threshold, loosely modeled on a biological neuron.
  • Its learning rule \(w\leftarrow w+\eta(y-\hat y)x\) only updates weights on misclassified examples, nudging the decision boundary toward the correct side.
  • Geometrically, a trained perceptron is a hyperplane — it can only solve linearly separable problems.
  • XOR is not linearly separable, which killed single-layer perceptron research for a decade until multi-layer networks and backpropagation revived it.

9. Code: Perceptron Learning From Scratch

This NumPy implementation reproduces the AND-gate example above exactly, training until convergence and printing the final weights and bias.

lecture-03-perceptron.py
import numpy as np

def step(z):
    return np.where(z >= 0, 1, 0)

# ---- AND-gate dataset, in the exact order used in the lecture ----
X = np.array([[0, 0], [0, 1], [1, 0], [1, 1]])
y = np.array([0, 0, 0, 1])

w = np.zeros(2)
b = 0.0
eta = 0.1
max_epochs = 20

for epoch in range(1, max_epochs + 1):
    updates = 0
    for xi, yi in zip(X, y):
        z = np.dot(w, xi) + b
        y_hat = step(z)
        error = yi - y_hat
        if error != 0:
            w += eta * error * xi
            b += eta * error
            updates += 1
    print(f"Epoch {epoch}: w={w}, b={b:.3f}, updates={updates}")
    if updates == 0:
        print("Converged -- no updates this epoch.")
        break

print("\nFinal weights:", w, " Final bias:", round(b, 3))
print("\nPredictions on AND:")
for xi, yi in zip(X, y):
    pred = step(np.dot(w, xi) + b)
    print(f"  x={xi} -> predicted={pred}, target={yi}")

⬇ Download lecture-03-perceptron.py   More resources for this lecture →