Skip to content

About

Numera: draw a digit and a PyTorch CNN recognizes it in real time. 99.43% MNIST test accuracy, FastAPI + Next.js, deployed on Hugging Face Spaces.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

🔢 Numera — Digit Classifier

Draw any digit (0–9) on the canvas. AI predicts it instantly.

Python TypeScript PyTorch Docker Hugging Face License

Live Demo →

Hosted on a free Hugging Face Space: if it has been idle, it may take a moment to wake up.



Numera on desktop: a hand-drawn 3 recognized with 91.8% confidence  Numera on mobile


✨ Features

  • 🖊️ Interactive canvas — draw digits freehand in the browser
  • ⚡ Instant prediction — real-time inference with no page reloads
  • 🧠 CNN model — trained on MNIST, 99.43% test accuracy with only 161K parameters
  • 🌐 Full-stack — TypeScript/React frontend + Python backend
  • 🐳 Dockerized — single container runs the entire app
  • 🤗 Hugging Face Spaces — live and publicly accessible

🏗️ Architecture

Numera/
├── UI/                  # Frontend — TypeScript / React
├── main.py              # Python backend (API server)
├── model.py             # CNN architecture (PyTorch)
├── model.pt             # Pre-trained model weights
├── MNIST_Training.ipynb # Training notebook
├── scripts/benchmark.py # Parameter count, size and CPU latency
├── requirements.txt     # Python dependencies
├── Dockerfile           # Container definition
└── README.md

How it works

How Numera works: draw, send image, preprocess, CNN inference, softmax, display

User draws on canvas
        ↓
Canvas exported as PNG → Next.js API route (/api/predict)
        ↓
POST request → FastAPI backend (main.py)
        ↓
Image converted to grayscale, resized to 28×28, normalized
        ↓
CNN model (model.py + model.pt) runs inference
        ↓
Predicted digit returned → displayed in UI

🚀 Getting Started

Prerequisites

  • Docker (recommended)
  • Or: Python 3.10+ and Node.js 18+

▶️ Run with Docker (recommended)

# Clone the repo
git clone https://github.com/abdurafay19/Digit-Classifier.git
cd Digit-Classifier

# Build and run
docker build -t numera .
docker run -p 7860:7860 numera

Open http://localhost:7860 in your browser.


▶️ Run Locally (without Docker)

1. Backend

pip install -r requirements.txt
uvicorn main:app --port 8000

2. Frontend

cd UI
npm install
npm run dev

Open http://localhost:3000.


🧠 Model

The classifier is a CNN trained from scratch on the MNIST dataset.

Architecture

Four convolutional blocks followed by a small classifier head. Every conv block is Conv2d → BatchNorm2d → ReLU → MaxPool2d(2) → Dropout2d(0.25).

Block Layer Output shape Parameters
Input 28×28 grayscale image 1 × 28 × 28 —
Conv block 1 Conv2d 1→32, 3×3, padding 1 32 × 14 × 14 384
Conv block 2 Conv2d 32→64, 3×3, padding 1 64 × 7 × 7 18,624
Conv block 3 Conv2d 64→128, 3×3, padding 1 128 × 3 × 3 74,112
Conv block 4 Conv2d 128→256, 1×1 256 × 1 × 1 33,536
Classifier Flatten → Linear 256→128 → ReLU → Dropout(0.25) 128 32,896
Output Linear 128→10 (logits) 10 1,290
Total 160,842

Trained for 50 epochs with AdamW (lr 3e-3, weight decay 1e-4), a OneCycle cosine schedule, label smoothing 0.1 and random rotation/affine augmentation. See MNIST_Training.ipynb.

Performance

Model results: 99.43% test accuracy, ~161K parameters, 0.66 MB model file, and per-digit accuracy

Metric Value
Test accuracy 99.43% (9,943 / 10,000 MNIST test images)
Parameters 160,842
Model size 643 KB (model.pt, 658,805 bytes)
CPU inference ~2 ms per image

Per-class test accuracy:

Digit 0 1 2 3 4 5 6 7 8 9
Accuracy 100.0% 99.7% 99.3% 99.8% 99.4% 99.2% 99.1% 99.2% 99.4% 99.1%

Inference time is the model's forward pass for a single image (batch size 1) on CPU, measured with scripts/benchmark.py on an Intel Core i5-5200U laptop CPU (PyTorch 2.1.2, 2 threads). The mean ranged from 1.2 to 2.2 ms across runs. It excludes image preprocessing and the network round trip. To reproduce:

python scripts/benchmark.py

☁️ Deployment

This project is deployed on Hugging Face Spaces using the Docker SDK.

The Dockerfile builds and serves the full app (UI + backend) in a single container on port 7860.

To deploy your own fork:

  1. Create a Space at huggingface.co/spaces with Docker as the SDK
  2. Push this repo:
git remote add space https://huggingface.co/spaces/your-username/Digit-Classifier
git push space main

🤝 Contributing

Contributions are welcome! Ideas:

  • 🧠 Improve the CNN (residual connections, data augmentation)
  • 🎨 Add confidence score display or prediction history
  • 🐳 Reduce Docker image size
  • 📱 Improve mobile canvas experience
git checkout -b feature/your-feature
git commit -m "feat: describe your change"
git push origin feature/your-feature
# Open a Pull Request

👤 Author

Abdul Rafay — CS student at ITU and AI Engineer

LinkedIn GitHub


⚖️ License

Released under the MIT License.

About

Numera: draw a digit and a PyTorch CNN recognizes it in real time. 99.43% MNIST test accuracy, FastAPI + Next.js, deployed on Hugging Face Spaces.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages