A neural network (more specifically, a multilayer perceptron) implementation in C++, in addition to a self-implemented multi-threaded matrix math class to vectorize calculations.
Under the Math namespace (see Matrix.hpp or Vector.hpp in include). The these custom structs supports several common operations used in linear algebra as well as some utilities:
- Initialization with C++
std::vectorof doubles *, -, +, /and*=, -=, +=, /=operators between matrices and doubles*, -, +and-=, +=between matrices&Hadamard/element-wise products- A
Math::Vectorclass to encapsulate row/column vectors as a special sub-class of matrices - Random matrix generation (default random engine, not optimized for better numerical distribution)
- Direct type casting into a double or
std::vectorof doubles - Some other mathematical functions
A ThreadPool class is defined for multi-threading optimizations in and outside of the matrix class, the use of which is controlled by benchmarked calculations.
Under the NeuralNetwork namespace consists of several components
MultilayerPerceptronclass with fully vectorized calculationsLayerclass with fully vectorized calculations and value storageNeurondeprecated class (replaced by vectorized values stored inLayer)ActivationFn::ActivationFndifferent activation functionsCostFn::CostFndifferent cost functions
Other notable components include
Datafor reading and storing data in a vectorized mannerThreadpoolfor optimizing thread usage
Training on MNIST
- 99% accuracy and 95% validation accuracy in 40-50 epochs
- Around 1.5 seconds per epoch (60000 data instances), which could use major improvements
- Certain classes need refactoring to improve reliability
- Multithreading does not provide satisfying performance increases for matrix calculations
- Current implementation of cost functions class does not support softmax
- Implement softmax rather than using sigmoid
- Automatic differentiation
- CUDA optimizations rather than CPU multi-threading
- Implement configurable metrics, optimizers (momentum, ADAM, etc.)