Project

CNN on MNIST

Python · PyTorch
Overview

A convolutional neural network built from scratch in PyTorch to recognize handwritten digits from the MNIST dataset - 70,000 labeled 28×28 grayscale images split into 60,000 training and 10,000 test samples.

The network stacks two convolution-and-pooling stages (1→32→64 channels, 3×3 kernels, 2×2 max-pooling, ReLU activations) that progressively extract patterns from raw pixels - simple edges first, then more complex shapes like the loops and crossings that distinguish digits such as 6, 8, and 9 - before flattening into a 1600-unit dense layer and a final 10-way classification head.

Trained for 10 epochs with SGD and cross-entropy loss on a CPU-only setup, the model converges cleanly and lands at 98.81% accuracy on the held-out test set - a deliberately minimal architecture chosen to make every design decision easy to reason about and explain.

Notebook walkthrough

The whole project lives in a single annotated notebook - from inspecting the raw MNIST tensors, to defining the network, to training and scoring it:

Result: 98.81% accuracy on the 10,000-image test set - digits the model never saw during training.

What I learned

Before writing any PyTorch, I worked through how a convolution transforms an image by hand, so the architecture above wasn't a black box - it was a direct translation of something I'd already reasoned through. From there I built the rest of the pipeline myself: loading and visualizing the data, defining the network's convolution, pooling, and linear layers, writing the training loop from scratch, plotting the loss curve, and evaluating on held-out data.

What actually stuck isn't the accuracy number - it's that I can now explain what a forward pass does, how loss connects to backpropagation, how gradients flow backward through the network, and what "training" means step by step. That's the foundation everything else in machine learning builds on.