How I Keras on C ++ started

Not long ago, I was faced with a production task — to launch a trained model of a neural network Kesason a native C++code. Oddly enough, the decision was not at all trivial. As a result, there appeared its own library, which gives such an opportunity. How is it - neural networks on clean crosses and there will be a small article today.


Those who can not wait - here is the repository on github, with a detailed description of the use. Well, and all the rest I ask under the cat ...


Formulation of the problem.


In the process, I needed to run a trained model on the C++application (Unreal Engune 4) . But bad luck: today there is almost no way to run the Keras model in C ++.


The option to call Pythonfrom C++did not seem good to me. Another option was to convert the Keras model to the TensorFlow model and then build the TensoFflow under the crosses and call the API TF from C ++ code.


This process of metamorphosis is well described in this article . But with this also difficulties arise. First , TensorFlow is going through Bzzel. And the bezel itself is capricious and refused to assemble under UE4 . Secondly , he himself is TFquite a big and cumbersome thing, but I wanted something more light and productive. I can only say that a half-working project was found in github , with the functionality I needed. But, he did not support current versions Pythonand Keras. And the attempts to remake it were not crowned with success: the C ++ application failed with an errorCore Dump . It was decided to write their own implementation ...


We write our library!


Turning the rock heavier, throwing a bottle pivasaenergy, I sat behind the code. In many ways, the TensorFlow code, attempts to rehabilitate the гитcode found , some knowledge about algorithms and data structures (thanks to ITMO for its courses) and good ear music helped me in the implementation of this library . Anyway, the library was written overnight.


And so meet: Keras2cpp!


The first part of the library is the Python module for saving the trained model in its own binary format.


There is nothing difficult in this operation. We simply read the model Kerasand write bitwise to the file: first тип слоя, then размерность, then матрицу весовin the format float.


We now turn to the most delicious - C ++ implementation.


The user has 2 entities tensorand model.


Tensor - transfers the data with which the neural network works and is a computer implementation of the tensor. Currently, the maximum dimension in 4 dimensions is supported . The dimension of each dimension is stored in the field std::vector<int> dims_;and the weight of each element of the tensor is in std::vector<int> data_;. From the available methods can be identified void Print()and Tensor Select(int row). The rest of the operations you can see in the source code. After the math for tensors was written, I started to implement the models.


Model - is a set of layers in each of which operations on tensors and weights matrix are registered. For the user, there are 2 functions virtual bool LoadModel(const std::string& filename);and virtual bool Apply(Tensor* in, Tensor* out);.


Here is a complete code example.


python_model.py:


import numpy as np
from keras import Sequential
from keras.layers import Dense
#create random data
test_x = np.random.rand(10, 10).astype('f')
test_y = np.random.rand(10).astype('f')
model = Sequential([
    Dense(1, input_dim=10)
])
model.compile(loss='mse', optimizer='adam')
#train model by 1 iteration
model.fit(test_x, test_y, epochs=1, verbose=False)
#predict
data = np.array([[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]])
prediction = model.predict(data)
print(prediction)
#save modelfrom keras2cpp import export_model
export_model(model, 'example.model')

cpp_mpdel.cc:


#include"keras_model.h"intmain(){
    // Initialize model.
    KerasModel model;
    model.LoadModel("example.model");
    // Create a 1D Tensor on length 10 for input data.Tensor in(10);
    in.data_ = {{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}};
    // Run prediction.
    Tensor out;
    model.Apply(&in, &out);
    out.Print();
    return0;
}

On this I think everything. Enjoyable use, and I will go to my favorite C # and Python to write neural networks further.


PS


I liked writing this library. When you write everything yourself from scratch, you understand more, but how it works ... Plans to add support for other architectures and GPUs ...


github repository
Source


Also popular now: