📜 ⬆️ ⬇️

How I Keras on C ++ started

Not long ago, I was faced with a production task — to launch the trained Kesas neural network Kesas in 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 in a C++ application (Unreal Engune 4) . But bad luck: today there is almost no way to run the Keras model in C ++.


The option of calling Python from 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 , the TF itself is quite a big and cumbersome thing, but I wanted something lighter and more productive. I can only say that in the github open spaces a semi-working project was found, with the functionality I needed. But, he did not support current versions of Python and Keras . And the attempts to remake it were not crowned with success: The C ++ application failed with the Core Dump error . It was decided to write their own implementation ...


We write our library!


Turning the rock heavier, throwing a bottle pivasa energy, I sat behind the code. In many ways, the TensorFlow code, attempts to rehabilitate the code found on гит , some knowledge about algorithms and data structures (thanks to ITMO for its courses) and good ear music helped me in implementing 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 Keras model and write bitwise to the file: first тип слоя , then the размерность , then матрицу весов in the float format.


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


Two tensor and model entities are available to the user.


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 std::vector<int> dims_; and the weight of each tensor element is in std::vector<int> data_; . From the available methods you can select 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. Two functions are available for the user. 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 model from keras2cpp import export_model export_model(model, 'example.model') 

cpp_mpdel.cc:


 #include "keras_model.h" int main() { // 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(); return 0; } 

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
A source



Source: https://habr.com/ru/post/438398/