This is a stdlib-only Python recreation of the kind of test Frank Rosenblatt ran on the Mark I Perceptron. The Mark I had a 20×20 photocell “retina”. Wikipedia’s Mark I Perceptron article cites Rosenblatt, “Perceptron Simulation Experiments”, Proc. IRE 48(3), 1960, for this result: the letter X vs the letter E, with 100% accuracy “when trained with only 20 images (10 images of each letter)”. Our retina is 5×5. We also use 10 smudged examples of each letter.
python3 perceptron.py # default: 3 smudged pixels per letter
python3 perceptron.py --noise 5 # messier handwriting
It needs Python 3.12 or newer and no other packages. It runs in under 0.1 seconds.
ACT 1 - RULES (programmed): 'full left edge means E'
accuracy on 1000 smudged letters: 74.6%
ACT 2 - LEARNING: perceptron rule on 20 smudged examples
pass 1: 2 mistakes
pass 2: 0 mistakes
accuracy on 1000 NEW smudged letters: 100.0%
learned weight map (+ votes X, - votes E):
0---+ (X #...# E #####)
-+0++ (X .#.#. E #....)
-00-+ (X ..#.. E ####.)
-00+0 (X .#.#. E #....)
0---+ (X #...# E #####)
ACT 3 - LIMITS: can one perceptron learn XOR?
pass 1: 2 mistakes weights=[-1, 0] bias=0
pass 2: 3 mistakes weights=[-1, 0] bias=1
pass 3: 4 mistakes weights=[-1, 0] bias=1
pass 4: 4 mistakes weights=[-1, 0] bias=1
pass 1000: 4 mistakes weights=[-1, 0] bias=1
after 1000 passes it still makes 4 mistakes per pass.
Its corrections cancel out, so it loops forever. No straight line
puts (0,1),(1,0) on one side and (0,0),(1,1) on the other.
Two layers of hand-wired threshold neurons (OR, NAND -> AND):
00->0 01->1 10->1 11->0
...but in 1969 nobody had a good way to TRAIN the hidden layer.
That is the cliffhanger for Lesson 06: blame flows backward.
We also tried other noise levels (pixels flipped per letter):
| Noise | Rule accuracy | Perceptron accuracy |
|---|---|---|
| 2 | 80.3% | 100.0% |
| 4 | 70.8% | 94.7% |
| 5 | 64.0% | 99.8% |
| 6 | 60.8% | 99.2% |
XOR never converged at any noise level.
---. Ask why: those pixels are dark in E but not in X.EXPERIMENTS.md.