Skip to content

Par-star/Digit-recognizer

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Handwritten Digit Recognizer (PyTorch)

Draw a digit from 0-9 and watch a PyTorch CNN, trained on MNIST, predict what you wrote — along with its confidence for every possible digit.

What's inside

File Purpose
model.py The CNN architecture: 2 conv layers + max-pooling + dropout + 2 fully-connected layers.
train_model.py Downloads MNIST via torchvision, trains the model, and saves digit_model.pth.
digit_app.py The Tkinter desktop drawing app: draw a digit, it's preprocessed into MNIST-style 28x28 input, and the trained model predicts it.
streamlit_app.py The same experience as a browser-based web app (uses streamlit-drawable-canvas for drawing).

Setup

Two frontends are included, sharing the same model.py and trained checkpoint — pick whichever you prefer:

Web (Streamlit) — recommended, no extra OS packages needed:

pip install -r requirements.txt
python train_model.py         # downloads MNIST and trains — a few minutes on CPU
streamlit run streamlit_app.py

Opens in your browser at http://localhost:8501.

Desktop (Tkinter):

pip install -r requirements.txt
python train_model.py   # downloads MNIST and trains — a few minutes on CPU
python digit_app.py     # opens the drawing app

train_model.py only needs to be run once — it saves digit_model.pth, which digit_app.py loads on every subsequent run. Test-set accuracy is typically ~99% after 6 epochs.

How the drawing becomes model input

  1. You draw on a 280x280 black canvas with a white brush.
  2. The drawing is cropped to its bounding box, padded back to a square with a margin (so the digit doesn't touch the edges, like real MNIST digits), then resized down to 28x28.
  3. Pixel values are normalized using MNIST's mean/std (0.1307/0.3081) — the same normalization the model was trained with.
  4. The 28x28 tensor is passed through the CNN, and a softmax turns the raw logits into a probability distribution over digits 0-9.

The app also shows you exactly what the model sees — the actual 28x28 image after preprocessing — which is a good way to understand why a messy drawing sometimes gets misclassified: what you drew and what the model receives can look surprisingly different at low resolution.

Architecture

Input (1x28x28)
  -> Conv2d(1->32, 3x3) -> ReLU -> MaxPool2d(2x2)   # 28x28 -> 14x14
  -> Conv2d(32->64, 3x3) -> ReLU -> MaxPool2d(2x2)  # 14x14 -> 7x7
  -> Dropout(0.25)
  -> Flatten -> Linear(64*7*7 -> 128) -> ReLU -> Dropout(0.5)
  -> Linear(128 -> 10)  # raw logits, softmax applied at inference

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages