Wie ich Keras in C ++ ausgeführt habe

Vor nicht allzu langer Zeit war ich mit einer Produktionsaufgabe konfrontiert: einem trainierten neuronalen Netzwerkmodell Kesasmit einem nativen C++Code. Seltsamerweise war die Entscheidung überhaupt nicht trivial. Als Ergebnis erschien eine private Bibliothek, die eine solche Gelegenheit bot. Wie das ist - neuronale Netze auf reinen Kreuzen und es wird den heutigen kleinen Artikel geben.


Diejenigen, die nicht warten können - hier ist das Repository auf Github mit einer detaillierten Beschreibung der Verwendung. Nun, und alles andere frage ich unter der Katze ...


Problem stellen.


Dabei musste ich ein trainiertes Modell für die C++Anwendung ausführen (Unreal Engune 4) . Aber Pech: Heute gibt es fast keine Möglichkeit, das Keras-Modell in C ++ auszuführen.


Option mit einem Aufruf Pythonvon C++nicht scheint mir gut. Eine andere Option bestand darin, das Keras-Modell in das TensorFlow- Modell zu konvertieren und dann den TensoFflow unter den Kreuzen zu erstellen und die API TF vom C ++ - Code aus aufzurufen.


Dieser Prozess der Metamorphose wird in diesem Artikel ausführlich beschrieben . Damit ergeben sich aber auch Schwierigkeiten. Zunächst geht TensorFlow durch Bzzel. Und die Lünette selbst ist launisch und weigert sich, unter UE4 zu montieren . Zweitens das TFziemlich große und umständliche Ding selbst, aber ich wollte etwas Leichteres und Produktiveres. Ich kann nur sagen, dass auf github ein halbarbeitendes Projekt gefunden wurde , mit der Funktionalität, die ich brauchte. Aktuelle Versionen Pythonund unterstützte er jedoch nicht Keras. Und Versuche, es neu zu machen, waren nicht mit Erfolg gekrönt: Mit ++ fiel die Anwendung mit einem Fehler ausCore Dump . Es wurde beschlossen, eine eigene Implementierung zu schreiben ...


Wir schreiben unsere Bibliothek!


Den Stein schwerer werden, eine Flasche werfen PivasaEnergie, ich saß hinter dem Code. Der TensorFlow-Code, der Versuch, den gefundenen Code zu rehabilitieren гит, einige Kenntnisse über Algorithmen und Datenstrukturen (dank ITMO für seine Kurse) und gute Musik in meinen Ohren haben mir bei der Implementierung dieser Bibliothek geholfen . So oder so wurde die Bibliothek über Nacht geschrieben.


Und so triff dich: Keras2cpp!


Der erste Teil der Bibliothek ist das Python- Modul zum Speichern des trainierten Modells in einem eigenen Binärformat .


Bei dieser Operation ist nichts schwierig. Wir lesen einfach das Modell Kerasund schreiben bitweise in die Datei: zuerst тип слоя, dann размерностьdann матрицу весовim Format float.


Wir wenden uns jetzt der leckersten - C ++ - Implementierung zu.


Der Benutzer hat 2 Entitäten tensorund model.


Tensor - überträgt die Daten, mit denen das neuronale Netzwerk arbeitet, und ist eine Computerimplementierung des Tensors. Derzeit wird die maximale Abmessung in 4 Dimensionen unterstützt . Die Dimension jeder Dimension wird in dem Feld gespeichert std::vector<int> dims_;und das Gewicht jedes Elements des Tensors ist in std::vector<int> data_;. Aus den verfügbaren Methoden lassen sich void Print()und identifizieren Tensor Select(int row). Die restlichen Vorgänge können im Quellcode angezeigt werden. Nachdem die Mathematik für Tensoren geschrieben war, begann ich mit der Implementierung der Modelle.


Modell - ist eine Gruppe von Schichten, in denen Vorgänge an Spannern und Gewichtungsmatrix registriert werden. Für den Benutzer stehen 2 Funktionen virtual bool LoadModel(const std::string& filename);und zur Verfügung virtual bool Apply(Tensor* in, Tensor* out);.


Hier ist ein vollständiges Codebeispiel.


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

Daran denke ich alles. Angenehmer Gebrauch, und ich werde zu meinem Lieblings-C # und Python gehen, um neuronale Netzwerke weiter zu schreiben.


PS


Ich habe es genossen, diese Bibliothek zu schreiben. Wenn Sie alles selbst schreiben, verstehen Sie mehr, aber wie es funktioniert ... Planen Sie die Unterstützung für andere Architekturen und GPUs ...


github-Repository-
Quelle


Jetzt auch beliebt: