A custom implementation of a Convolutional Neural Network (CNN) from scratch in Rust, without relying on high-level machine learning frameworks. This project demonstrates how to build, train, and validate a CNN using Rust's powerful features and libraries.
- Introduction
- Features
- Getting Started
- Usage
- Project Structure
- Dependencies
- Contributing
- License
- Acknowledgments
This project showcases a full-fledged implementation of a CNN in Rust, aimed at image classification tasks. It covers the entire pipeline from data loading and preprocessing to model training and validation. The implementation focuses on clarity and educational value, making it a valuable resource for anyone interested in understanding how neural networks work under the hood.
- Custom Neural Network Layers: Implements convolutional, pooling, fully connected, ReLU, and softmax layers from scratch.
- Data Loading and Preprocessing: Loads images from a folder structure, converts them to grayscale, and normalizes pixel values.
- Training and Validation Pipeline: Includes functions for training the model and validating its performance on a separate dataset.
- Parallel Computing: Utilizes Rust's
rayoncrate for parallel computations to speed up training and inference. - Custom Optimizer: Implements the AdamW optimizer for efficient training with weight decay regularization.
- Progress Monitoring: Uses
indicatifto display progress bars during training epochs. - Configurable Parameters: Allows easy adjustment of hyperparameters like learning rate, batch size, and network architecture.
- Rust Toolchain: Ensure you have Rust and Cargo installed. If not, install them from rustup.rs.
# Check if Rust is installed
rustc --version
cargo --version- Image Dataset: A dataset of images organized in a folder structure where each subfolder represents a class, containing images of that class.
-
Clone the Repository
git clone https://github.com/yourusername/your-repo-name.git cd your-repo-name -
Build the Project
cargo build --release
Building in release mode is recommended for performance.
-
Organize Your Dataset
Place your dataset in a folder named
data/at the root of the project. The structure should look like:data/ ├── class1/ │ ├── image1.jpg │ ├── image2.jpg │ └── ... ├── class2/ │ ├── image1.jpg │ ├── image2.jpg │ └── ... └── ... -
Image Requirements
- Images should be in
.jpg,.jpeg, or.pngformat. - Images will be converted to grayscale and resized to
64x64pixels. Ensure your images are at least this size.
- Images should be in
-
Run the Program
cargo run --release
The program will:
- Load and preprocess the images.
- Split the data into training and validation sets (default is 90% training, 10% validation).
- Build the CNN based on the configuration constants.
- Train the model for the specified number of epochs.
- Validate the model after each epoch and print the loss and accuracy.
-
Adjusting Hyperparameters
You can modify the hyperparameters by changing the constants in
main.rs:// Training parameters const EPOCHS: usize = 10; const LEARNING_RATE: f32 = 0.0001; const BATCH_SIZE: usize = 32; // Model input parameters const INPUT_HEIGHT: usize = 64; const INPUT_WIDTH: usize = 64; const NUM_CLASSES: usize = 10; // Convolutional layers configuration const CONV_LAYERS_CONFIG: &[(usize, usize)] = &[(16, 3), (32, 3)]; // Fully connected layers configuration const FC_LAYERS_CONFIG: &[usize] = &[256, NUM_CLASSES];
- EPOCHS: Number of training iterations over the entire dataset.
- LEARNING_RATE: Step size for the optimizer.
- BATCH_SIZE: Number of samples processed before the model is updated.
- CONV_LAYERS_CONFIG: Tuples representing the number of filters and kernel size for each convolutional layer.
- FC_LAYERS_CONFIG: Sizes of the fully connected layers.
-
Monitoring Training Progress
The program displays progress bars for each epoch and prints out the training loss and validation accuracy.
Epoch 1 - Loss: 1.2345 [#########################] 100/100 (00:30<00:00) Validation Loss: 0.9876, Accuracy: 85.00%
- main.rs: Entry point of the program. Handles data loading, model creation, training, and validation.
- data_utils.rs: Functions for loading and preprocessing data.
- layers.r: Contains modules for different neural network layers:
- optimizers.rs: Implementation of the AdamW optimizer.
- Cargo.toml: Project configuration and dependencies.
The project uses several crates to facilitate computations:
- ndarray: For multi-dimensional array manipulations.
- ndarray-rand: To initialize arrays with random values.
- rand: Random number generation.
- rayon: Parallelism for CPU-bound tasks.
- indicatif: Progress bars for CLI applications.
- image: Loading and processing images.
These dependencies are specified in the Cargo.toml file:
[dependencies]
ndarray-rand = "0.15.0"
rand = { version = "0.8.5", features = ["std"] }
ndarray = { version = "0.16.1", features = ["rayon"] }
image = { version = "0.25.2", default-features = false, features = ["jpeg"] }
indicatif = "0.17.8"
rayon = "1.10.0"This project is licensed under the MIT License - see the LICENSE file for details.
- Rust Community: For providing extensive resources and support.
- Crate Authors: Thanks to the authors of the crates used in this project for making development easier.