goektan.dev
University ProjectB.Sc. coursework · Solo — university project

MNIST Digit Recognizer.

Live digit recognizer — draw on canvas, CNN predicts in real time.

Machine LearningPyTorchComputer VisionUniversity Project
MNIST Digit Recognizer — primary screenshot
01Overview

A CNN trained on the classic MNIST handwritten-digit dataset, paired with a small Gradio app that turns a browser drawing canvas into a live classifier. Draw a digit with mouse or touch, the model predicts the class and surfaces the top-3 probabilities as the strokes appear. Built for the Foundations of Deep Learning module — the goal was to go past 'train a model in a notebook' and put a working demo on top.

02The problem

What it solves.

MNIST itself is an introductory benchmark — the interesting question is not the accuracy number but everything around it: getting a non-trivial CNN to converge well, then bridging the gap between the model's training distribution (clean centered 28×28 digits) and what a user actually draws on a canvas (arbitrary stroke widths, off-center, varying sizes). Without that bridging step, the model looks much worse in practice than its test accuracy suggests.

03The build

How it's solved.

  1. 01

    CNN architecture: 2 convolutional blocks with BatchNorm + Dropout (~470k trainable parameters), followed by fully-connected layers — small enough to train in minutes, deep enough to handle the variety.

  2. 02

    Trained for 8 epochs on the standard MNIST training set with batch size 128. Reached ~99.3% test accuracy.

  3. 03

    Gradio drawing canvas (`app.py`) loads the trained weights from `best_model.pt` and exposes the model as a web app. Works on desktop with mouse and on iPad / mobile with touch.

  4. 04

    Live preprocessing pipeline that matches what the model was trained on: grayscale → invert (canvas is dark-on-white, MNIST is white-on-black) → crop to digit bounding box → re-center in a 28×28 frame → normalize with MNIST mean/std.

  5. 05

    Full evaluation: training curves, classification report, confusion matrix, and a grid of the hardest misclassified test examples — documented in the notebook.

04Highlights

What makes it interesting.

Live drawing canvas, not just a notebook

The model lives in a Gradio app that takes raw canvas input and runs the full preprocessing pipeline in real time. Top-3 probabilities update live as you draw — the model getting a digit right with 100% versus splitting between two candidates teaches you something the test-set accuracy alone doesn't.

~99.3% test accuracy with a small model

2 conv blocks + BatchNorm + Dropout, ~470k parameters, 8 epochs. Demonstrates that for MNIST, depth matters less than getting regularization and normalization right.

Preprocessing bridges the train/serve gap

A model that scores 99% on test set still fails on canvas input if you skip preprocessing. The crop-and-recenter step alone fixes the most common failure mode — drawings that are correct but slightly off-center.

06Stack

Tech.

Language
Python
ML
PyTorchtorchvision
Numerics
NumPyscikit-learn
Plotting
Matplotlib
Web app
Gradio (drawing canvas)Pillow
Tooling
JupyterGit
Questions about this project?Get in touch