After the AND gate I wanted to see what the perceptron does on actual pictures. So I pointed it at images of cats and dogs: 300 for training and 70 for testing, which are small silhouette drawings rather than photographs. I wrote the whole thing myself in Python with NumPy, using torchvision only to load and shrink the images.
Each picture is squashed to 32 × 32 pixels, turned to grayscale and flattened into a list of 1,024 brightness values. The model is one weight per pixel plus a bias, all starting at zero. It adds up weight × brightness, answers 1 if the total is above 0 and 0 if not, and nudges the weights by learning rate × error × pixels whenever it is wrong. I trained it for 100 passes over the training folder, reshuffling the order each time, then loaded a separate test folder it had never seen. The code is unchanged below.
- Data
- 300 train + 70 test drawings, half cats and half dogs
- Input
- 32 × 32 grayscale = 1,024 numbers
- Model
- 1,024 weights + 1 bias, rule w ← w + 0.01 · error · x
- Training
- 100 epochs, shuffled
</>View the code on GitHubAmlan-Das/rowan-site · ai/catdog/catdog.py→
What the Model Can and Cannot See
One weight per pixel means the model only knows how bright each fixed position is. It has no idea of ears, eyes or shape, and a cat shifted a few pixels lands on different weights. The training and test drawings are all variations of one icon per class, so a good score here says little about real photographs. That is the limit of this design, and it is what the AlexNet project below goes after: small shared filters that look for shapes anywhere in the picture.