This project is a deep learning-based classifier for recognizing images of handwritten Arabic numerals (digits 0-9). It is implemented from scratch in modern C++ and uses the MNIST dataset for training and evaluation. The project demonstrates core deep learning concepts, including custom neural network layers, loss functions, and model serialization.
Neural Network Architecture:
- Layer 1: Dense(784, 128) with ReLU activation
- Layer 2: Dense(128, 64) with ReLU activation
- Layer 3: Dense(64, 10) with Softmax activation (10 output classes for digits 0-9)
Training:
- Batch gradient descent with configurable batch size
- Categorical cross-entropy loss function
- Model checkpointing (save/load weights and biases)
Inference:
- Load trained models from saved weights
- Predict on test images
- Visualize predictions using OpenCV windows
Tencor/
├── numerals_classifier/ # Source code directory
│ ├── numerals_classifier.cpp # Main application file
│ ├── Tensor.h # Tensor library (1D, 2D, 3D)
│ ├── Dense.h # Dense layer implementation
│ ├── Sequential.h # Sequential model container
│ ├── Model.h # Base model class
│ ├── Loss.h # Loss functions (MSE, BCE, CCE)
│ ├── Layer.h # Base layer class and activations
│ ├── MNISTDataLoader.h # MNIST dataset loader
│ ├── ModelSaver.h # Model persistence utilities
│ ├── weights.dat # Saved model weights (after training)
│ ├── biases.dat # Saved model biases (after training)
├── mnist_dataset/ # MNIST dataset files
│ ├── train-images.idx3-ubyte
│ ├── train-labels.idx1-ubyte
│ ├── t10k-images.idx3-ubyte
│ └── t10k-labels.idx1-ubyte
├── build_run.bat # Build and run script
└── README.md # This file
┌────────────────────┐
│ MNIST Dataset │
└─────────┬──────────┘
│
▼
┌────────────────────┐
│ Data Loader │
│ (MNISTDataLoader) │
└─────────┬──────────┘
│
▼
┌────────────────────┐
│ Preprocessing │
│ (Normalization) │
└─────────┬──────────┘
│
▼
┌──────────────────────────────┐
│ Neural Network Construction │
│ (Dense, Activation Layers) │
└─────────┬────────────────────┘
│
▼
┌────────────────────┐
│ Training Loop │
│ (Forward/Backward) │
└─────────┬──────────┘
│
▼
┌────────────────────┐
│ Model Evaluation │
└─────────┬──────────┘
│
▼
┌────────────────────┐
│ Prediction │
└────────────────────┘
- Download OpenCV from: https://opencv.org/releases/
- Extract to a location such as
C:/opencv/ - You should have:
C:/opencv/build/include/C:/opencv/build/x64/vc16/lib/C:/opencv/build/x64/vc16/bin/(add this to your system PATH)
- Add
C:/opencv/build/x64/vc16/binto your system PATH (so DLLs are found at runtime) - Restart your terminal/command prompt after updating PATH
- If your OpenCV or Visual Studio paths differ, edit
build_run.bat:set "OPENCV_INCLUDE=C:/opencv/build/include"set "OPENCV_LIB_PATH=C:/opencv/build/x64/vc16/lib"set "OPENCV_LIB=opencv_world4120.lib"(update version if needed)set "VS_PATH=..."(update if your Visual Studio is in a different location)
- Place the following files in
mnist_dataset/:train-images.idx3-ubytetrain-labels.idx1-ubytet10k-images.idx3-ubytet10k-labels.idx1-ubyte
- If you don't have them, download from: http://yann.lecun.com/exdb/mnist/
- Open a command prompt in the project root (
Tencor/) - Run:
build_run.bat - The script will:
- Set up the Visual Studio compiler environment
- Compile
numerals_classifier.cppwith OpenCV dependencies - Run the executable
- Display MNIST predictions in OpenCV windows
- By default, the project runs in prediction mode using pre-trained weights.
- To train a new model:
- Open
numerals_classifier/numerals_classifier.cpp - In
main(), uncomment the line://trainModel(numTrainImages); - Optionally adjust training parameters:
- Number of training images:
int numTrainImages = 1000; // -1 for all - Epochs, learning rate, batch size: in
model.fit()
- Number of training images:
- Rebuild and run the script again
- After training,
weights.datandbiases.datwill be saved innumerals_classifier/
- Open
Input Layer (28x28 pixels)
│
▼
Dense Layer (128 neurons)
│
▼
Activation (ReLU)
│
▼
Dense Layer (64 neurons)
│
▼
Activation (ReLU)
│
▼
Dense Layer (10 neurons)
│
▼
Activation (Softmax)
│
▼
Output: Digit Class (0-9)
- Neural Network Layers: Custom implementations of dense (fully connected) layers, activation functions, and loss functions.
- Training Loop: Manual implementation of forward and backward propagation, weight updates, and loss calculation.
- Data Handling: Efficient loading and normalization of MNIST images and labels.
- Model Serialization: Save and load model weights for reuse.
Common Issues:
- OpenCV library not found:
- Update
OPENCV_LIBinbuild_run.batto match your OpenCV version (e.g.,opencv_world4120.lib)
- Update
- DLL not found at runtime:
- Ensure
C:/opencv/build/x64/vc16/binis in your system PATH
- Ensure
- Cannot open include file: 'opencv2/opencv.hpp':
- Check that
OPENCV_INCLUDEinbuild_run.batis correct
- Check that
- vcvarsall.bat not found:
- Update
VS_PATHinbuild_run.batto your Visual Studio Build Tools location
- Update
- MNIST dataset files not found:
- Download and place them in
mnist_dataset/as described above
- Download and place them in
- Weights file not found (when predicting):
- Train the model first, or ensure
weights.datandbiases.datexist innumerals_classifier/
- Train the model first, or ensure
This project is provided as-is for educational purposes.
- MNIST dataset by Yann LeCun, Corinna Cortes, and Christopher Burges
- OpenCV library for computer vision capabilities