Skip to content

Library for machine learning. More in README.md

Notifications You must be signed in to change notification settings

JRazek/NNEngine

Repository files navigation

NeuralFlows

Library for deep learning. CUDA is not supported by all layers yet. The experimental compile flag COMPILE_WITH_CUDA is set to OFF by default.

creation of a simple network with a <28, 28, 3> input tensor and a seed for pseudo-random generator of value 1 looks following

cn::Network network(28, 28, 3, 1);

From now on we can easily append next layers of to network. For example that's how to create 2 convolutional layers with 2 kernels of size <3, 3, n>, ReLU activation and normalization.

network.appendConvolutionLayer({3, 3}, 2);
network.appendReLULayer();
network.appendBatchNormalizationLayer();
network.appendConvolutionLayer({3, 3}, 2);
network.appendReLULayer();
network.appendBatchNormalizationLayer();

Now after creation of the convolution layers we'd love to add some FFlayers, but firstly we should max pool with <2,2> kernel and flatten the tensor output from the previous layer. At the end we'll put a softmax to get an output as probablility.

network.appendMaxPoolingLayer({2, 2});
network.appendFlatteningLayer();
network.appendFFLayer(10);
network.appendSigmoidLayer();
network.appendFFLayer(10);
network.appendSoftmaxLayer();

Then it is time to finally tell the network that it should get ready and to initialize random weights.

network.ready();
network.initRandom();

Wonderful! We have created a simple CNN. The only problem that it does not know very much and it will behave no better than pseudo-random number generator. In order to fix that issue we should learn it. Fot that purpose we'll use minibatch gradient descent optimizer implemented by a cn::MBGD class.

cn::MBGD mbgd(network, 0.1, 40);//network ref, learning rate, minibatch size

Once we have an input tensor of type either cn::Tensor<byte> or cn::Tensor<double> we are ready to feed our network.

network.feed(tensor);

After each feed we can call an optimizer's method propagate(). It will calculate all the gradients in a network and propagate them once the batch size is full.

mbgd.propagate();

Unfortunately there would be absolutely no use from the network if we couldn't even save it. Therefore network derives from class JSONEncodable. By calling a jsonEncode() method, we'll get an nlohmann::json object, which can be easily saved to file.

std::fstream file(filePath, std::ios::out);
file << network.jsonEncode();
file.close();

Since it can be saved, there should also be a possibility to deserialize such json file and create a network from it. Just use an overloaded constructor.

using JSON = nlohmann::json;
std::ifstream ifs("test.json");
JSON json = json::parse(ifs);

Network network(json);

it will already have a ready state, therefore it is unnecessary to call either network.ready(); nor network.initRandom();.


Depends on the nlohmann/json library. https://github.com/nlohmann/json