You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This repository contains a neural network written from scratch in rust using the nalgebra crate.
It is part of a blog series currently in progress here.
You may find it useful to read the blogs if you hope to understand the code, otherwise I hope it is readable enough to be understood without them.
Running 🏃
This project can currently only be run by using cargo:
git clone https://github.com/max-amb/number_recognition.git
cd number_recognition
cargo run
Nix
If you are using nix there is no need to try install dependencies as they are all contained in the flake.nix.
You can enter this dev shell as follows:
git clone https://github.com/max-amb/number_recognition.git
cd number_recognition
nix develop
Speed comparison with pytorch
The data for training runs can be found in ./results/.
The tests were done utilising hyperfine utilising the following commands:
The network that the models were tested on followed a $[728] \to [256] \to [10]$ architecure and utilised stochastic gradient descent and He initialisation.
The program exited when the accuracy on test data exceeded $96%$.
The test data was checked every epoch.
I have attempted to ensure all parameters in the models are the same but if you spot any disparity please email me or raise an issue.
The results in green are results from the parallelised rust version, orange is the non-parallelised rust version and blue is the pytorch version (also non-parallelised).
Below is a graph displaying the results
Now, when parallelised, using the same conditions as above, the parallelised version was about $10\times$ faster than the non parallelised training
Testing data
This section hopes to detail how I obtained my testing data. If you are unsure of anything I recommend you read my blog post which walks through the mathematics!
Initial conditions
We start with a network with 3 layers (one input, one hidden and one output).
They have sizes: 3, 2, and 3.
The weights look like this:
For the activation functions, we use a leaky relu ($\alpha = 0.2$), denoted $ReLU$, for the hidden layers and a logistical sigmoid function, denoted $\sigma$, for the output layer.
Everything is shortened to 3 decimal points for conciseness, but the full output can be found in the wolfram outputs.