Awesome
handwritten-digits-recognition
Handwritten digits recognition using NN and Ruby 🧠💎
About the project
This project is using neural network written in ruby for handwritten digits recognition. It is complete solution with frontend and backend parts. Model was trained and tested on MNIST handwritten digits set converted into libsvm format dataset. Set contains 60k train and 10k test examples.
Instalation
Application is using Rumale::Torch, which requires to install LibTorch:
Running app with docker
Build image:
docker build -t hdr_app .
Run container:
docker run -p 4567:4567 hdr_app:latest
Running app locally
For MacOS:
brew install automake libtorch
Then execute:
bundle install
For Linux please follow Dockerfile when installing libtorch.
Model & training data
Transforming data to libsvm format
Download MNIST file and extract it in /utils
folder:
Downloading & etracting training set
cd utils/
wget https://www.csie.ntu.edu.tw/~cjlin/libsvmtools/datasets/multiclass/mnist.t.bz2
wget https://www.csie.ntu.edu.tw/~cjlin/libsvmtools/datasets/multiclass/mnist.bz2
bzip2 -d mnist.t.bz2 mnist.bz2
Prepare libsvm files
MNIST files does not contain zero values, which is problematic when using Rumale library. The simple fix is to fill it with zeros, and make sure we have 784 values (28x28 pixels) in one line. For that there is script:
// in utils/
ruby fill_libsvm_with_zeros.rb mnist
ruby fill_libsvm_with_zeros.rb mnist.t
Libsvm files
Libsvm files contain datas in multiple lines with format:
<label> <index1>:<value1> <index2>:<value3> ...
.
.
.
For MNIST data which are just 28x28 pixels images of digits index is the position of pixel (x=index%size
, y=floor(index/size)
) and value is color of pixel (0-white, 255-black).
Training & testing model
Training model
Now you can start training with train.rb
script.
// in utils/
ruby train.rb
Mind that it has parameters such as:
- batch_size
- max_epoch
- validation_split
- layers
For training you can tweak them and see how it impacts the learning process and accuracy.
Testing model
To test model simply run:
// in utils/
ruby test.rb
Make sure scipt is using the right model file, and NN has the same dimensions as in training.
Using different model in app
To use you own model copy your .dat and .pth file to models folder, and rename it to model.dat
and model.pth
.
The default model has ~97% accuracy.