Skip to content

DagaVedant/EMNIST-Character-Classifier

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

EMNIST Character Classifier

A CNN trained from scratch on the EMNIST Balanced dataset to classify handwritten digits and letters. Includes a full training pipeline with live experiment tracking via Weights & Biases, and an interactive web app where you draw a character and get a prediction instantly.


Features

  • Handwritten digit + letter classification (47 classes)
  • CNN built in PyTorch with BatchNorm and Dropout
  • Training augmentation — random rotation, translation, and scaling
  • Live experiment tracking with Weights & Biases (loss, accuracy, LR, gradients, sample predictions)
  • Best model auto-saved to checkpoints during training
  • Per-class accuracy breakdown with confusion matrix
  • Local inference server (Flask) + canvas drawing web app
  • All hyperparameters controlled from a single config file — no hardcoded values

Tech Stack

  • Python
  • PyTorch + Torchvision
  • Weights & Biases
  • Flask + Flask-CORS
  • scikit-learn
  • PyYAML
  • Pillow
  • NumPy
  • Jupyter Notebook

Project Structure

emnist-classifier/
│
├── data/
│   ├── raw/                  ← EMNIST downloads here automatically
│   └── processed/
│
├── src/
│   ├── model.py              ← CNN architecture
│   ├── train.py              ← Training loop + WandB logging
│   ├── evaluate.py           ← Test evaluation + per-class report
│   ├── dataset.py            ← Data loading, transforms, augmentation
│   └── utils.py              ← Config loader, checkpointing, AverageMeter
│
├── configs/
│   └── config.yaml           ← All hyperparameters live here
│
├── notebooks/
│   └── exploration.ipynb     ← Visualize samples and class distribution
│
├── app/
│   ├── server.py             ← Local Flask inference server
│   └── index.html            ← Drawing web app
│
├── checkpoints/              ← best_model.pth saved here after training
├── requirements.txt
└── .gitignore

Dataset

This project uses the EMNIST Balanced dataset:

  • 47 classes — digits (0–9) and letters (visually ambiguous pairs like C/c are merged)
  • 112,800 training samples, 18,800 test samples
  • 28x28 grayscale images, same format as MNIST

Dataset downloads automatically via torchvision.datasets.EMNIST on first run.

Classes: 0 1 2 3 4 5 6 7 8 9
         A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
         a b d e f g h n q r t

Setup

1. Clone

git clone https://github.com/DagaVedant/EMNIST-Character-Classifier.git
cd emnist-classifier

2. Install dependencies

pip install -r requirements.txt

3. Log in to Weights & Biases

Free account at wandb.ai, then:

wandb login

To disable WandB, set wandb.enabled: false in configs/config.yaml.


Training

python src/train.py
  • Downloads EMNIST automatically (~550MB, one time)
  • Trains for 15 epochs on GPU (GTX 1650 ≈ 20–30 min)
  • Saves best checkpoint to checkpoints/best_model.pth
  • Streams all metrics to WandB in real time

Evaluation

# Console report only
python src/evaluate.py

# Also log confusion matrix to WandB
python src/evaluate.py --wandb

Running the Web App

# Start the inference server (requires a trained checkpoint)
python app/server.py

Then open app/index.html in your browser. Draw a character on the canvas and click Classify to see the top 5 predictions with confidence bars.


How It Works

Raw EMNIST images (28x28 grayscale)
        │
        ├─ Orientation fix (EMNIST is rotated by default)
        ├─ Augmentation: rotation ±10°, translate 5%, scale 0.9–1.1
        ├─ Normalize
        │
        ▼
   Conv Block 1: Conv→BN→ReLU→Conv→BN→ReLU→MaxPool→Dropout
        │
   Conv Block 2: Conv→BN→ReLU→Conv→BN→ReLU→MaxPool→Dropout
        │
   Classifier:   Flatten→Linear(512)→ReLU→Dropout→Linear(47)
        │
        ▼
   Top-5 predictions with confidence scores

Training — Adam optimizer with ReduceLROnPlateau scheduler. Validation split held out from training data. Best model saved automatically based on val accuracy.

Inference — canvas drawing is sent as a base64 PNG to the Flask server, preprocessed (inverted, cropped to bounding box, resized to 28x28), and passed through the model.


Configuration

Everything lives in configs/config.yaml:

Setting Default What it does
training.epochs 15 Number of full passes through data
training.batch_size 128 Images per training step
training.learning_rate 0.001 Initial learning rate
training.weight_decay 0.0001 L2 regularization
model.conv_channels [32, 64] Output channels per conv block
model.fc_hidden 512 Hidden size of FC layer
model.dropout_conv 0.25 Dropout after each conv block
model.dropout_fc 0.5 Dropout before output layer
data.val_split 0.1 Fraction of train data used for validation
wandb.log_interval 50 Log batch loss every N steps

Model Performance

The model is evaluated using:

  • Overall test accuracy
  • Per-class precision, recall, and F1
  • Confusion matrix (via WandB)

Expected test accuracy: ~85–88% on EMNIST Balanced.


Future Improvements

  • Add symbols and custom shape classes with synthetic data generation
  • Export model to ONNX for faster inference
  • Deploy web app publicly with a cloud-hosted model
  • Add real-time classification as you draw (no click needed)
  • Experiment with ResNet or EfficientNet backbones

License

This project is open-source and available under the MIT License.


Author

Developed as a personal machine learning project exploring CNNs, experiment tracking, and end-to-end model deployment.

About

CNN trained on EMNIST Balanced to classify handwritten digits and letters. PyTorch training pipeline with WandB experiment tracking and an interactive drawing web app.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors