Feed Forward Neural Network From Scratch

Feed-Forward Neural Network from scratch

This is a FeedForward Neural Network with back-propagation written in C++ with no external libraries. The aim for this project was to create a simple version of TensorFlow's Keras sequential neural network from scratch in C++. As a challenge, I did not refer to any of TF's source code or implementation.

Classes

In Dependencies folder:

  • Matrix: This is a simple matrix class that allows for matrix operations and several other useful methods.
    • at(row,col) : returns value at specified row and column (0-indexed).
    • Transpose() : returns a transposed copy of current matrix.
    • static Matrix::Zero(rows,cols) and Matrix::One(rows,cols) : return a matrix of all zeroes or ones respectively provided number of rows and columns.
    • set_values(vector,rows,cols) : initialize a matrix with a 2d vector of floats (can accept 1d vector of floats).
  • Layer: Basic element of the NN class. It provides a handful of activation functions.
    • Activation Functions:
      • Sigmoid (Default)
      • ReLU
    • Weight Initialization:
      • Normalized Xavier
    • Some Methods:
      • forward(Matrix) : returns the output of activation(Weights*Matrix + Bias) as a Matrix.
      • backward(Matrix,float) : calculates delta_W and delta_B for both weights and biases respectively.
      • summary() : prints a summary of the layer properties (units, input shape, etc.).

Neural Network:

  • Cost function: MSE
  • Methods:
    • forward_pass(Matrix) : returns output of one forward pass using the neural network given Matrix input.
    • back_prop(Matrix,float) : performs one backward pass and updates weights and biases of all layers given expected Matrix and learnRate float.
    • train(Matrix,Matrix,int,float) : trains neural network given X_train and y_train matrices provided number of epochs and learnRate. (Please refer to data set preparation section for more details)
    • test(Matrix) : prints neural network output after 1 pass given input. (equivalent to printing forwad_pass).
    • summary() : prints a summary of all the neural network properties. (shows weight and biases matrices of each layer).

Data Set Preparation

In order to train our model we would require a data set. The method train() expects 2 Matrix instances. Each of the matrices should be as follows.

For the matrix X Each column would represent one input to the neural network (a bit counter intuitive, I know

😄

). On the other hand, it would represent the expected output for y.

Note: when it comes to test() method it should be provided with a Column vector instance of class Matrix.

Instructions

To initialize a neural network:

#include                              "Neural Network/NeuralNetwork.h"                            int              main(){                              //Create array of layers                              //                Layer(units, input_shape, activation, weight_initialization)                              //                all strings are typed in **lower-case**                              //                You need to only specify input shape in first layer              Layer Layers[] = {              Layer(2,2,                "relu"              ,                "nx"              ),              Layer(1,                "relu"              )   };                              //Initialize neural network with array and size              NN              model(Layers,              2); }

This would create an architecture shown in the picture below.

image

After that, you would want to prepare a dataset. A way you could do that is by doing the following:

              Matrix              X(2,              4), Y(1,              4);   X.at(0,              0) =              0;   X.at(1,              0) =              0;   X.at(0,              1) =              1;   X.at(1,              1) =              0;   X.at(0,              2) =              0;   X.at(1,              2) =              1;   X.at(0,              3) =              1;   X.at(1,              3) =              1;       Y.at(0,              0) =              1;   Y.at(0,              1) =              1;   Y.at(0,              2) =              1;   Y.at(0,              3) =              0;

This would create the equivalent matrices shown below.

image

If you noticed, it acts as the logical table of a NAND gate!.
Now, we want to train our model. We can use the train() method.

              int              epochs =              10000;              float              learnRate =              0.05;                              //Display train data set              cout <<                "X_train:\n                "              << X <<                "Y_train:\n                "                            << Y<<endl;                              //Train                            model.train(X, Y, epochs, learnRate);

You would see this on your screen. It will also print a progress bar that would gradually print 10 "#" hashes, each representing 10% closer to completion.

When it comes to testing, all you need is have column vectors of your input, then use test() method.

                              //Test              cout <<                              "                \nTesting:\n                "              ;   Matrix test;   test = X.Column(0);   cout <<                              "Y0:"              ;   model.test(test);   test = X.Column(1);   cout <<                              "Y1:"              ;   model.test(test);   test = X.Column(2);   cout <<                              "Y2:"              ;   model.test(test);   test = X.Column(3);   cout <<                              "Y3:"              ;   model.test(test);   cout <<                              "                \nExpected to be close to:                "                            <<Y;

Then, you should have something like this.

image

If you want, you could print a model's summary using the summary() method as shown below.

                              //Printing summary of model              model.summary();

image

Tasks

  • Add ability to save and load a model.
  • Implement Dropout layers.
  • Implement BatchNormalization layers.
  • Add ability to change cost function.
  • Add Adam optimizer.
  • Optimize matrix multiplication. (maybe use Strassen's Algorithm)

License

MIT License

youngannexclock51.blogspot.com

Source: https://github.com/FahdSeddik/FeedForward-NeuralNetwork-from-scratch

0 Response to "Feed Forward Neural Network From Scratch"

Post a Comment

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel