An AI-driven web app for handwritten digit recognition using the MNIST dataset. It leverages TensorFlow for deep learning model training and Gradio to create an intuitive, interactive UI. Users can draw digits and receive instant predictions, showcasing practical AI deployment and real-time inference capabilities.
- Overview
- Features
- Demo
- Architecture
- Project Structure
- Installation
- Environment Variables
- Usage
- Model Details
- Gradio Interface
- Configuration
- Testing
- Deployment
- Customization
- Performance Tips
- Code Walkthrough
- Troubleshooting
- FAQ
- Contributing
- License
- References
- Acknowledgements
- Contact
-
main.py
The main entry point for the application. It loads the trained Keras model and launches a Gradio web interface, allowing users to draw digits and receive instant predictions. -
configs/system-variables.py
Contains system configuration variables such as the model path, input size, and other settings that control the app’s behavior. -
configs/__init__.py
Marks theconfigsdirectory as a Python package.
-
model.keras
The pre-trained Keras model file used for digit classification. -
training.ipynb
A Jupyter notebook for training and evaluating the model on the MNIST dataset. Users can retrain the model, experiment with different architectures, and save new models.
-
gradio.md
Documentation on using Gradio for the user interface, including setup and customization tips. -
mnist-dataset.md
Information about the MNIST dataset, its structure, and how it is used in this project. -
tensorflow.md
Guidance and notes on using TensorFlow within the project, including installation and troubleshooting.
-
README.md
The main documentation file, providing an overview, setup instructions, usage, customization, deployment, troubleshooting, and more. -
requirements.txt
Lists all Python dependencies required to run the project, such as TensorFlow and Gradio. -
LICENSE
The MIT License file, specifying the terms for open-source use and distribution.
-
Interactive Gradio UI:
Users can draw digits in their browser and receive real-time predictions from the trained model. -
Deep Learning Model:
Utilizes a Convolutional Neural Network (CNN) trained on the MNIST dataset for high-accuracy digit recognition. -
Easy Retraining:
The included Jupyter notebook allows users to retrain the model or experiment with new architectures. -
Configurable:
System variables and settings can be easily adjusted in the configuration files. -
Well-Documented:
Comprehensive guides and code comments are provided for easy understanding and customization.
Handwritten-Digits-Classification/
│
├── app/
│ ├── configs/
│ │ ├── __init__.py
│ │ └── system-variables.py
│ └── main.py
│
├── docs/
│ ├── gradio.md
│ ├── mnist-dataset.md
│ └── tensorflow.md
│
├── models/
│ ├── model.keras
│ └── training.ipynb
│
├── README.md
├── requirements.txt
└── LICENSE
This project demonstrates a complete pipeline for handwritten digit recognition using deep learning. It includes:
- Training a neural network on the MNIST dataset.
- Saving and loading the trained model.
- Deploying the model as a web app using Gradio, allowing users to draw digits and get instant predictions.
The project is ideal for learning about computer vision, neural networks, and deploying AI models in real-world applications.
- 🧠 Deep Learning Model: Built with TensorFlow/Keras, trained on MNIST.
- 🖼️ Interactive UI: Draw digits directly in your browser using Gradio.
- ⚡ Real-Time Inference: Instant predictions as you draw.
- 🔄 Easy Retraining: Jupyter notebook provided for model retraining.
- 🛠️ Configurable: System variables and settings are easily adjustable.
- 📦 Portable: Simple requirements, easy to run locally.
- 📝 Well-Documented: Includes guides and code comments for easy understanding.
- 🧪 Tested: Model and app tested for accuracy and usability.
- 🌐 Deployable: Ready for deployment on cloud or local servers.
- 🔒 Secure: No user data is stored or transmitted externally.
Live Demo: Coming soon!
flowchart TD
A[User draws digit in browser] --> B[Gradio UI]
B --> C[Image Preprocessing]
C --> D[Trained TensorFlow Model]
D --> E[Prediction Output]
E --> F[Display result in UI]
- Frontend: Gradio web interface for drawing and displaying results.
- Backend: Python server running TensorFlow model for inference.
- Model: CNN trained on MNIST dataset.
Handwritten-Digits-Classification/
│
├── app/
│ ├── configs/
│ │ ├── __init__.py
│ │ └── system-variables.py
│ └── main.py
│
├── docs/
│ ├── gradio.md
│ ├── mnist-dataset.md
│ └── tensorflow.md
│
├── models/
│ ├── model.keras
│ └── training.ipynb
│
├── README.md
├── requirements.txt
└── LICENSE
- app/: Main application code and configuration.
- docs/: Documentation and guides.
- models/: Trained model and training notebook.
- requirements.txt: Python dependencies.
git clone https://github.com/NhanPhamThanh-IT/Handwritten-Digits-Classification.git
cd Handwritten-Digits-Classificationpython -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activatepip install -r requirements.txtYou can configure the following environment variables (optional):
| Variable | Description | Default Value |
|---|---|---|
| MODEL_PATH | Path to the trained model file | models/model.keras |
| GRADIO_PORT | Port for Gradio web server | 7860 |
| DEBUG | Enable debug mode (True/False) | False |
Set them in your shell or in a .env file (if using python-dotenv).
If you want to retrain the model, open the Jupyter notebook:
jupyter notebook models/training.ipynbFollow the notebook instructions to train and save a new model.
python app/main.pyThis will launch the Gradio interface in your browser. Draw a digit and see the prediction in real time!
GRADIO_PORT=8080 python app/main.py- Dataset: MNIST
- Architecture: Convolutional Neural Network (CNN)
- Framework: TensorFlow / Keras
- Input: 28x28 grayscale images
- Output: Digit class (0-9)
- Training Notebook:
models/training.ipynb - Saved Model:
models/model.keras
import tensorflow as tf
from tensorflow.keras import layers, models
model = models.Sequential([
layers.Input(shape=(28, 28, 1)),
layers.Conv2D(32, (3, 3), activation='relu'),
layers.MaxPooling2D((2, 2)),
layers.Conv2D(64, (3, 3), activation='relu'),
layers.MaxPooling2D((2, 2)),
layers.Flatten(),
layers.Dense(64, activation='relu'),
layers.Dense(10, activation='softmax')
])The app uses Gradio to provide a user-friendly web interface:
- Draw Area: Use your mouse or touchscreen to draw a digit.
- Predict Button: Instantly see the model's prediction and confidence.
- Clear Button: Reset the canvas to try again.
import gradio as gr
import numpy as np
from tensorflow.keras.models import load_model
model = load_model('models/model.keras')
def predict_digit(image):
image = image.reshape(1, 28, 28, 1) / 255.0
prediction = model.predict(image)
return {str(i): float(prediction[0][i]) for i in range(10)}
iface = gr.Interface(
fn=predict_digit,
inputs=gr.Image(shape=(28, 28), image_mode='L', invert_colors=True, source='canvas'),
outputs=gr.Label(num_top_classes=3),
live=True,
title="Handwritten Digit Recognition",
description="Draw a digit (0-9) and the model will predict it!"
)
iface.launch()For more details, see docs/gradio.md.
System variables and settings can be adjusted in:
app/configs/system-variables.py
You can modify parameters such as model path, input size, etc.
To test the model or app:
- Unit Tests: (Add your own tests in a
tests/directory) - Manual Testing: Run the app and try drawing various digits.
- Model Evaluation: Use the notebook to evaluate accuracy on the MNIST test set.
- Add a
Procfile:web: python app/main.py - Push to Heroku and set buildpacks for Python.
- Create a
Dockerfile:FROM python:3.10 WORKDIR /app COPY . . RUN pip install -r requirements.txt EXPOSE 7860 CMD ["python", "app/main.py"]
- Build and run:
docker build -t digit-classifier . docker run -p 7860:7860 digit-classifier
- Change Model: Edit and retrain in
models/training.ipynb. - Change UI: Modify Gradio interface in
app/main.py. - Add Features: E.g., upload image, batch prediction, etc.
- Use GPU for faster training (see TensorFlow docs).
- Optimize model size for faster inference.
- Use quantization or pruning for deployment on edge devices.
- app/main.py: Entry point for the Gradio app. Loads the model and defines the prediction function.
- models/training.ipynb: Jupyter notebook for training and evaluating the model.
- app/configs/system-variables.py: Stores configuration variables (e.g., model path).
- docs/: Contains additional documentation on Gradio, MNIST, and TensorFlow.
-
Gradio not launching?
- Ensure all dependencies are installed.
- Try running
python -m pip install --upgrade pipand reinstall requirements.
-
Model not found?
- Make sure
models/model.kerasexists, or retrain using the notebook.
- Make sure
-
Jupyter not found?
- Install with
pip install notebook.
- Install with
-
Other issues?
- Check the docs/ folder for more help.
Q: Can I use my own dataset?
A: Yes! Modify the training notebook to load your dataset and retrain the model.
Q: How do I improve accuracy?
A: Try deeper networks, data augmentation, or hyperparameter tuning in the notebook.
Q: Can I deploy this app online?
A: Yes! Gradio supports easy deployment to Hugging Face Spaces, or you can use services like Heroku, AWS, or Azure.
Q: How do I change the model architecture?
A: Edit the model definition in models/training.ipynb and retrain.
Q: Why is my prediction always wrong?
A: Make sure you draw clearly within the box, and the model is properly loaded.
Q: How do I run on a different port?
A: Set the GRADIO_PORT environment variable.
Contributions are welcome! Please open issues or pull requests for suggestions, bug fixes, or improvements.
- Fork the repository.
- Create a new branch (
git checkout -b feature/your-feature). - Make your changes.
- Commit and push (
git commit -am 'Add new feature' && git push origin feature/your-feature). - Open a pull request.
This project is licensed under the MIT License. See LICENSE for details.
- Inspired by classic MNIST digit recognition projects.
- Thanks to the open-source community for tools and datasets.
For questions or support, please open an issue or contact [email protected].
The app can be extended to provide a REST API for predictions.
| Endpoint | Method | Description | Input | Output |
|---|---|---|---|---|
/predict |
POST | Predict digit from image | 28x28 image | JSON result |
Example Request:
curl -X POST -F "[email protected]" http://localhost:7860/predict-
Add New Preprocessing Steps:
Edit the image preprocessing logic inapp/main.pyto include noise reduction, thresholding, or resizing. -
Support for Color Images:
Change the input shape and preprocessing to handle RGB images. -
Batch Prediction:
Modify the Gradio interface to accept and predict multiple images at once. -
Logging and Monitoring:
Integrate tools like TensorBoard or Weights & Biases for experiment tracking.
- Ensure the app is run behind a secure proxy (e.g., Nginx) in production.
- Use HTTPS for all external deployments.
- Validate and sanitize all user inputs.
- Do not expose sensitive environment variables or model internals.
- v1.0.0: Initial release with Gradio UI and MNIST model.
- v1.1.0: Added configuration file and environment variable support.
- v1.2.0: Improved documentation and added Docker support.
