An end-to-end solution for digit classification with Convolutional Neural Networks, fully containerized with Docker
This repository provides a Dockerized implementation of a Convolutional Neural Network (CNN) for recognizing handwritten digits using the MNIST dataset. The project ensures a reproducible environment by leveraging Docker for both development and execution.
The MNIST dataset contains 70,000 grayscale images of handwritten numbers (60,000 for training and 10,000 for testing), each sized at 28×28 pixels. The CNN model developed here is capable of classifying these digits with an accuracy exceeding 99%.
This project is designed to help you:
- Grasp the structure and benefits of CNNs compared to standard neural networks for image tasks
- Build and train a CNN using TensorFlow/Keras
- Visualize and interpret the internal feature maps of a CNN
- Compare CNN performance with that of a basic ANN
- Learn how to use Docker for consistent machine learning environments
- Docker and Docker Compose must be installed
- Familiarity with Python and neural network basics
- Understanding of image classification principles
Folder PATH listing
.
+---data <-- Contains MNIST dataset files
| mnist <-- Raw and processed MNIST data (created at runtime)
| mnist_samples <-- Example images from MNIST for visualization
| README.md <-- Data directory documentation
|
+---figures <-- Plots and visualizations
| confusion_matrices <-- Confusion matrix images
| feature_maps <-- CNN feature map images
| test_samples.png <-- Feature map activations for test data
| confusion_matrix.png <-- Model performance plot
| feature_maps.png <-- Overview of feature maps
| mnist_samples.png <-- Grid of MNIST digit samples
| prediction_samples.png <-- Model prediction examples
| README.md <-- Visualizations documentation
| simple_cnn_confusion_matrix.png <-- Confusion matrix for simple CNN
| simple_cnn_misclassified.png <-- Misclassified digit examples
| simple_cnn_training_history.png <-- Training metrics for simple CNN
| training_history.png <-- Training/validation metrics
|
+---models <-- Model code and saved weights
| architectures <-- CNN architecture code
| configs <-- Model configuration files
| evaluation <-- Model evaluation scripts
| training <-- Model training scripts
| __init__.py <-- Package initializer
| mnist_cnn_best.h5 <-- Best model (by validation accuracy)
| mnist_cnn_final.h5 <-- Final trained model
| model_factory.py <-- Model creation factory
| model_registry.py <-- Model registry
| README.md <-- Models documentation
| simple_cnn_final.h5 <-- Trained simple CNN model
|
+---notebooks <-- Jupyter notebooks for exploration
| 01_data_exploration.ipynb <-- Data exploration/visualization
| 02_model_training.ipynb <-- Model training/evaluation
| figures/ <-- Notebook-generated figures
| models/ <-- Notebook-saved models
| README.md <-- Notebooks documentation
|
+---scripts <-- Standalone Python scripts
| data_prep.py <-- Download/preprocess MNIST
| extract_sample_images.py <-- Extract images for visualization
| README.md <-- Scripts documentation
| train_cnn.py <-- Train the CNN
| visualize_features.py <-- Create feature map visualizations
|
+---utils <-- Helper functions
| README.md <-- Utilities documentation
| toc_generator.py <-- Markdown TOC generator
|
| .dockerignore <-- Docker ignore rules
| .gitignore <-- Git ignore rules
| docker-compose.yml <-- Docker Compose service config
| Dockerfile <-- Docker build instructions
| LICENSE <-- License details
| README.md <-- Project overview and guide
| requirements.txt <-- Python dependencies
| start.sh <-- Docker container startup script
Clone the repository and move into the project folder:
git clone <repository-url>
cd CNN_MNIST_Dockerized
You can start the Docker container in two ways:
Make the script executable and run it to build and start the container:
chmod +x start.sh
./start.sh
Alternatively, build and run the container manually:
docker-compose up --build -d
Notes:
--build
: Forces Docker to rebuild the image, applying any updates-d
: Runs the container in the background
To confirm the container is running:
docker-compose ps
Ensure the status is "Up" and port 8889 is mapped to 8888 inside the container.
Open your browser and go to:
http://localhost:8889
Port 8889 on your machine is mapped to 8888 in the container. Always use 8889 in your browser. No password or token is needed, as authentication is disabled for convenience.
For enhanced development, you can attach VS Code to the running container:
- Press
Ctrl+Shift+P
to open the command palette - Search for and select
Dev Containers: Attach to Running Container…
- Pick the container named
cnn_mnist_dockerized-cnn_mnist-1
- A new VS Code window will open
- Click
Open Folder
, navigate to/app
, and confirm - Install recommended extensions:
Docker
,Dev Containers
,Python
, andJupyter
- You can now edit and run code directly in the container
To run the full MNIST CNN workflow:
# Inside the container
python scripts/data_prep.py
python scripts/extract_sample_images.py
python scripts/train_cnn.py
python scripts/visualize_features.py
Alternatively, you can use the Jupyter Lab interface to run the notebooks interactively.
When finished, stop and remove the container:
docker-compose down
This will stop and delete the container, but your data remains safe due to volume mounting.
- Rebuild after changes:
docker-compose up --build -d
- Update requirements.txt after adding packages:
# Inside the container pip freeze > requirements.txt
- Pull the latest base image:
docker-compose build --pull
# List all images
docker images
# Remove specific images
docker rmi <image1> <image2>
# Remove all unused images
docker image prune -a
# List running containers
docker ps
# List all containers (including stopped)
docker ps -a
# List only container IDs
docker ps -aq
# Remove specific containers
docker rm <container1> <container2>
# Remove all containers
docker rm $(docker ps -aq)
# Start/stop containers
docker start <container_id>
docker stop <container_id>
# View logs
docker logs <container_id>
# Run a command in a running container
docker exec -it <container_id> bash
Tip: You can use just the first few characters of a container ID.
The MNIST dataset is downloaded and processed automatically by the scripts. Data is normalized and split into training, validation, and test sets.
The CNN includes:
- Several convolutional layers with suitable filter sizes
- Max pooling for downsampling
- Dropout for regularization
- Dense layers for classification
- Softmax output for 10 digit classes (0-9)
Training uses:
- Data augmentation (rotation, zoom, shift)
- Categorical cross-entropy loss
- Adam optimizer
- Early stopping and model checkpointing
- Validation accuracy and loss tracking
Visualizations include:
- Example MNIST digits
- Training/validation metrics
- Confusion matrix
- CNN feature maps
- Correct and incorrect predictions
Below are some outputs and visualizations from the model:
Shows accuracy and loss for training and validation:
Displays classification results for all digits:
Examples of incorrect predictions:
Feature map visualizations from convolutional layers:
- Change the CNN structure and see how it impacts results
- Compare CNN with a simple MLP
- Try different data augmentation methods
- Visualize feature maps from various layers to understand CNN learning
- Docker Memory Limits: If Docker crashes, increase its memory allocation in settings
- Slow Training: For faster runs, enable GPU access for Docker if available
- Jupyter Lab Not Loading: Make sure port 8889 is free
- Permission Errors: If you see "Permission denied" when creating folders, check your user permissions or run Docker with
--user $(id -u):$(id -g)
to match host and container permissions.
- CS231n: Convolutional Neural Networks for Visual Recognition
- TensorFlow Documentation
- Deep Learning Book by Ian Goodfellow
This project is distributed under the MIT License. See the LICENSE file for more details.