Lancement de Keras en C ++

Il n'y a pas si longtemps, j'ai été confronté à la tâche de production consistant à lancer un Kesas réseau de neurones Kesas formé à l'aide de code C++ natif. Curieusement, la solution n'était pas du tout triviale. En conséquence, il y avait une bibliothèque privée, offrant une telle opportunité. À propos de comment c'est - des réseaux de neurones sur des croix propres et sera le court article d'aujourd'hui.


Pour ceux qui ne peuvent pas attendre - voici le dépôt github, avec une description détaillée de l'utilisation. Eh bien, je demande à tout le monde sous le chat ...


Énoncé du problème.


Dans le processus, j'avais besoin d'exécuter un modèle formé dans une application C++ (Unreal Engune 4) . Mais voici la malchance: aujourd'hui, il n'y a pratiquement aucun moyen d'exécuter le modèle Keras en C ++.


L'option d'appel Python de C++ ne me semblait pas bonne. Une autre option était de convertir le modèle Keras en un modèle TensorFlow , puis de créer TensoFflow pour les croix et d'appeler l'API TF à partir du code C ++.


Ce processus de métamorphose est bien décrit dans cet article . Mais des difficultés surgissent également avec cela. Tout d'abord , TensorFlow passe par Bzzel . Et la lunette elle-même est une chose fantaisiste et a refusé de se réunir sous UE4 . Deuxièmement , TF lui-même est une chose assez grande et encombrante , mais je voulais quelque chose de plus léger et productif. Je peux seulement dire que sur les espaces ouverts de github, un projet à moitié fonctionnel a été trouvé, avec les fonctionnalités dont j'avais besoin. Mais, il ne prend pas en charge les versions actuelles de Python et Keras . Et les tentatives pour le refaire ont échoué: l' application C ++ s'est bloquée avec une erreur Core Dump . Il était habituel d'écrire ma propre implémentation ...


Nous écrivons notre bibliothèque!


Tourner la pierre plus fort, lancer une bouteille pivasa l'énergie, je me suis assis au code. Le code TensorFlow, les tentatives de réhabilitation du code trouvé sur le code , quelques connaissances sur les algorithmes et les structures de données (merci à ITMO pour ses cours) et la bonne musique à mes oreilles m'ont beaucoup aidé dans l'implémentation de cette bibliothèque. D'une manière ou d'une autre, la bibliothèque a été écrite en une nuit.


Et donc rencontrez: Keras2cpp!


La première partie de la bibliothèque est le module Python pour enregistrer le modèle entraîné dans son propre format binaire .


Il n'y a rien de compliqué dans cette opération. Nous lisons simplement le modèle Keras et écrivons petit à petit dans un fichier: d'abord , puis la , puis au format float .


Passons maintenant à l'implémentation la plus délicieuse - C ++.


L'utilisateur dispose de 2 entités tensor et model .


Tenseur - redistribue les données avec lesquelles le réseau de neurones fonctionne et est une implémentation informatique du tenseur. Dimension maximale actuellement prise en charge en 4 dimensions. La dimension de chaque dimension est stockée dans le std::vector<int> dims_; et le poids de chaque élément tensoriel est dans std::vector<int> data_; . Parmi les méthodes disponibles, void Print() et Tensor Select(int row) peuvent être distingués. Le reste des opérations que vous pouvez voir dans le code source. Après avoir écrit les mathématiques pour les tenseurs, j'ai commencé à implémenter des modèles.


Modèle - est un ensemble de couches dans chacune desquelles des opérations sur les tenseurs et une matrice de poids sont prescrites. 2 fonctions sont disponibles pour l'utilisateur virtual bool LoadModel(const std::string& filename); et virtual bool Apply(Tensor* in, Tensor* out); .


Voici un exemple de code complet.


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; } 

C'est tout ce que je pense. Profitez de son utilisation, et j'irai vers mon C # et Python bien-aimés pour écrire plus loin les réseaux de neurones.


PS


J'ai aimé écrire cette bibliothèque. Lorsque vous écrivez tout vous-même à partir de zéro, vous comprenez mieux, mais comment cela fonctionne ... Nous prévoyons d'ajouter la prise en charge d'autres architectures et GPU ...


référentiel github
Source

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


All Articles