So verwenden Sie TensorFlow Mobile in Android-Apps

Mit TensorFlow, einem der beliebtesten maschinellen Lernframeworks, das heute verfügbar ist, können Sie auf einfache Weise tiefe Modelle erstellen und trainieren, die auch als Deep-Forward-Forward-Neuronale Netzwerke bezeichnet werden, und die eine Vielzahl komplexer Probleme lösen, wie z. B. Bildklassifizierung oder Objekt Erkennung und Verständnis der natürlichen Sprache. TensorFlow Mobile ist eine Bibliothek, mit der Sie diese Modelle in Ihren mobilen Apps nutzen können.

In diesem Tutorial zeige ich Ihnen, wie Sie TensorFlow Mobile in Android Studio-Projekten verwenden.

Voraussetzungen

Um diesem Tutorial folgen zu können, benötigen Sie:

  • Android Studio 3.0 oder höher
  • TensorFlow 1.5.0 oder höher
  • ein Android-Gerät mit API Level 21 oder höher
  • und ein grundlegendes Verständnis des TensorFlow-Frameworks

1. Ein Modell erstellen

Bevor wir TensorFlow Mobile einsetzen können, benötigen wir ein trainiertes TensorFlow-Modell. Lass uns jetzt einen erstellen.

Unser Modell wird sehr einfach sein. Es verhält sich wie ein XOR-Gatter, nimmt zwei Eingänge an, von denen beide entweder Null oder Eins sein können, und erzeugt einen Ausgang, der Null ist, wenn beide Eingänge identisch sind, andernfalls einer. Da es ein tiefes Modell sein wird, wird es außerdem zwei verborgene Schichten haben, eine mit vier Neuronen und eine mit drei Neuronen. Sie können die Anzahl der verborgenen Ebenen und die Anzahl der darin enthaltenen Neuronen ändern.

Um dieses Tutorial kurz zu halten, verwenden wir nicht die TensorFlow-APIs auf niedriger Ebene direkt, sondern TFLearn, ein beliebtes Wrapper-Framework für TensorFlow, das intuitivere und prägnantere APIs bietet. Wenn Sie es noch nicht haben, verwenden Sie den folgenden Befehl, um es in Ihrer virtuellen TensorFlow-Umgebung zu installieren:

pip install tflearn

Erstellen Sie zum Erstellen des Modells ein Python-Skript mit dem Namen create_model.py, vorzugsweise in einem leeren Verzeichnis und öffnen Sie es mit Ihrem bevorzugten Texteditor.

In der Datei müssen wir zunächst die TFLearn-APIs importieren.

tflearn importieren

Als Nächstes müssen wir die Trainingsdaten erstellen. Für unser einfaches Modell gibt es nur vier mögliche Ein- und Ausgänge, die dem Inhalt der Wahrheitstabelle des XOR-Gatters ähneln.

X = [[0, 0], [0, 1], [1, 0], [1, 1]] Y = [[0], # Gewünschter Ausgang für die Eingänge 0, 0 [1], # Gewünschter Ausgang für Eingänge 0, 1 [1], # Gewünschter Ausgang für die Eingänge 1, 0 [0] # Gewünschter Ausgang für die Eingänge 1, 1]

In der Regel ist es eine gute Idee, Zufallswerte zu verwenden, die aus einer gleichmäßigen Verteilung ausgewählt wurden, während allen Neuronen in den verborgenen Schichten Anfangsgewichte zugewiesen werden. Um die Werte zu erzeugen, verwenden Sie die Uniform() Methode.

Gewichte = tflearn.initializations.uniform (minval = -1, maxval = 1)

An diesem Punkt können wir die Schichten unseres neuronalen Netzwerks erstellen. Um die Eingabeebene zu erstellen, müssen Sie die Eingabedaten() Methode, mit der wir die Anzahl der Eingänge angeben können, die das Netzwerk akzeptieren kann. Sobald die Eingabeebene fertig ist, können Sie das aufrufen vollständig_verbunden () mehrmals, um dem Netzwerk weitere Schichten hinzuzufügen.

# Eingabeebene net = tflearn.input_data (shape = [Keine, 2], name = 'mein_input') # Versteckte Ebenen net = tflearn.fully_connected (net, 4, Aktivierung = 'sigmoid', Gewichte_init = Gewichte) net = tflearn. vollständig verbunden (netto, 3, Aktivierung = 'sigmoid', Gewichte_init = Gewichte) # Ausgabeschicht net = tflearn.fully_connected (net, 1, Aktivierung = 'sigmoid', Gewichte_init = Gewichte, name = 'mein_output')

Beachten Sie, dass wir im obigen Code den Eingabe- und Ausgabeebenen sinnvolle Namen gegeben haben. Dies ist wichtig, da wir sie während der Verwendung des Netzwerks von unserer Android-App benötigen. Beachten Sie auch, dass die ausgeblendeten und Ausgabe-Layer die Sigmoid Aktivierungsfunktion. Sie können mit anderen Aktivierungsfunktionen, z. B. SoftmaxTanh, und relu.

Als letzte Schicht unseres Netzwerks müssen wir eine Regressionsebene mithilfe von erstellen Regression () function, die einige Hyper-Parameter als Argumente erwartet, z. B. die Lernrate des Netzwerks und die Optimierer- und Verlustfunktionen, die es verwenden sollte. Der folgende Code zeigt Ihnen, wie Sie den stochastischen Gradientenabstieg, kurz SGD, als Optimierungsfunktion und den Mittelwert als Verlustfunktion verwenden:

net = tflearn.regression (net, learning_rate = 2, optimizer = 'sgd', Verlust = 'mean_square')

Um dem TFLearn-Framework mitzuteilen, dass unser Netzwerkmodell tatsächlich ein Modell für ein tiefes neuronales Netzwerk ist, müssen wir das nennen DNN () Funktion.

model = tflearn.DNN (net)

Das Modell ist jetzt fertig. Jetzt müssen wir nur noch mit den zuvor erstellten Trainingsdaten trainieren. Rufen Sie also an passen() Methode des Modells und geben Sie zusammen mit den Trainingsdaten die Anzahl der auszuführenden Trainingsepochen an. Da die Trainingsdaten sehr klein sind, benötigt unser Modell Tausende von Epochen, um eine angemessene Genauigkeit zu erreichen.

model.fit (X, Y, 5000)

Sobald das Training abgeschlossen ist, können wir die anrufen vorhersagen() Methode des Modells, um zu überprüfen, ob es die gewünschten Ausgaben erzeugt. Der folgende Code zeigt, wie Sie die Ausgänge auf alle gültigen Eingänge prüfen:

print ("1 XOR 0 =% f"% model.predict ([[1,0]]). item (0)) print ("1 XOR 1 =% f"% model.predict ([[1,1]) ]). item (0)) print ("0 XOR 1 =% f"% model.predict ([[0,1]]). item (0)) print ("0 XOR 0 =% f"% model. vorhersagen ([[0,0]]). Punkt (0))

Wenn Sie das Python-Skript jetzt ausführen, sollten Sie folgende Ausgabe sehen:

Beachten Sie, dass die Ausgänge niemals exakt 0 oder 1 sind. Stattdessen handelt es sich um Fließkommazahlen, die entweder nahe bei Null oder nahe bei Eins liegen. Daher sollten Sie bei der Verwendung der Ausgaben Pythons verwenden runden() Funktion.

Wenn wir das Modell nicht explizit nach dem Training speichern, werden wir es verlieren, sobald das Skript beendet ist. Glücklicherweise mit TFLearn ein einfacher Aufruf an sparen() Methode speichert das Modell. Um das gespeicherte Modell jedoch mit TensorFlow Mobile verwenden zu können, müssen Sie vor dem Speichern sicherstellen, dass alle im Zusammenhang mit dem Training vorhandenen Vorgänge entfernt werden tf.GraphKeys.TRAIN_OPS Sammlung, damit verbunden. Der folgende Code zeigt, wie das geht:

# Entfernen Sie die Zugoperationen mit net.graph.as_default (): del tf.get_collection_ref (tf.GraphKeys.TRAIN_OPS) [:] # Speichern Sie das Modell model.save ('xor.tflearn').

Wenn Sie das Skript erneut ausführen, werden Sie feststellen, dass es eine Checkpoint-Datei, eine Metadatendatei, eine Indexdatei und eine Datendatei generiert, die alle zusammen unser geschultes Modell schnell neu erstellen können.

2. Einfrieren des Modells

Zusätzlich zum Speichern des Modells müssen Sie es einfrieren, bevor Sie es mit TensorFlow Mobile verwenden können. Das Einfrieren eines Modells beinhaltet, wie Sie vielleicht erraten haben, das Konvertieren aller Variablen in Konstanten. Darüber hinaus muss ein eingefrorenes Modell eine einzelne Binärdatei sein, die dem Serialisierungsformat von Google Protocol Buffers entspricht.

Erstellen Sie ein neues Python-Skript mit dem Namen freeze_model.py und öffnen Sie es mit einem Texteditor. Wir werden den gesamten Code schreiben, um unser Modell in dieser Datei einzufrieren.

Da TFLearn keine Funktionen zum Einfrieren von Modellen bietet, müssen wir jetzt die TensorFlow-APIs direkt verwenden. Importieren Sie sie, indem Sie der Datei die folgende Zeile hinzufügen:

Tensorflow als tf importieren

Im gesamten Skript verwenden wir eine einzige TensorFlow-Sitzung. Verwenden Sie zum Erstellen der Sitzung den Konstruktor von Session Klasse.

mit tf.Session () als Sitzung: # Restlicher Code geht hier

An diesem Punkt müssen wir ein erstellen Sparer Objekt durch Aufrufen der import_meta_graph () Funktion und Übergabe des Namens der Metadatendatei des Modells. Zusätzlich zur Rückgabe eines Sparer Objekt, das import_meta_graph () Die Funktion fügt außerdem automatisch die Diagrammdefinition des Modells zur Diagrammdefinition der Sitzung hinzu.

Sobald der Saver erstellt wurde, können wir alle Variablen initialisieren, die in der Diagrammdefinition enthalten sind, indem Sie das Symbol aufrufen wiederherstellen() Diese Methode erwartet den Pfad des Verzeichnisses, das die neueste Prüfpunktdatei des Modells enthält.

my_saver = tf.train.import_meta_graph ('xor.tflearn.meta') my_saver.restore (session, tf.train.latest_checkpoint ('.'))

An dieser Stelle können wir das anrufen convert_variables_to_constants () Funktion zum Erstellen einer Definition für ein eingefrorenes Diagramm, in der alle Variablen des Modells durch Konstanten ersetzt werden. Als Eingabe erwartet die Funktion die aktuelle Sitzung, die Diagrammdefinition der aktuellen Sitzung und eine Liste mit den Namen der Ausgabe-Layer des Modells.

frozen_graph = tf.graph_util.convert_variables_to_constants (session, session.graph_def, ['mein_output / Sigmoid'])

Anrufen der SerializeToString () Die Methode der Definition des eingefrorenen Graphen liefert eine binäre Protobuf-Darstellung des Modells. Wenn Sie die grundlegenden E / A-Funktionen von Python verwenden, sollten Sie sie als Datei mit dem Namen speichern frozen_model.pb.

mit open ('frozen_model.pb', 'wb') als f: f.write (frozen_graph.SerializeToString ())

Sie können das Skript jetzt ausführen, um das eingefrorene Modell zu generieren.

Wir haben jetzt alles, was wir brauchen, um TensorFlow Mobile zu nutzen.

3. Android Studio Project-Setup

Die TensorFlow Mobile-Bibliothek ist in JCenter verfügbar, sodass wir sie direkt als Erweiterung hinzufügen können Implementierung Abhängigkeit in der App Modul build.gradle Datei.

Implementierung 'org.tensorflow: tensorflow-android: 1.7.0'

Um das eingefrorene Modell zum Projekt hinzuzufügen, platzieren Sie das frozen_model.pb Datei im Projekt Vermögenswerte Mappe.

4. Initialisieren der TensorFlow-Schnittstelle

TensorFlow Mobile bietet eine einfache Schnittstelle, mit der Sie mit unserem eingefrorenen Modell interagieren können. Verwenden Sie zum Erstellen der Schnittstelle den Konstruktor von TensorFlowInferenceInterface Klasse, die ein erwartet Vermögensverwalter Instanz und der Dateiname des eingefrorenen Modells.

thread val tfInterface = TensorFlowInferenceInterface (assets, "frozen_model.pb") // Mehr Code hier

Im obigen Code können Sie sehen, dass wir einen neuen Thread starten. Dies ist zwar nicht immer notwendig, wird jedoch empfohlen, um sicherzustellen, dass die Benutzeroberfläche der App weiterhin reagiert.

Um sicher zu sein, dass TensorFlow Mobile es geschafft hat, die Datei unseres Modells korrekt zu lesen, versuchen wir jetzt, die Namen aller Vorgänge auszudrucken, die im Diagramm des Modells vorhanden sind. Um einen Verweis auf die Grafik zu erhalten, können wir die verwenden Graph() Methode der Schnittstelle, und um alle Operationen zu erhalten, die Operationen () Methode des Graphen. Der folgende Code zeigt Ihnen wie:

val graph = tfInterface.graph () graph.operations (). forEach println (it.name ())

Wenn Sie die App jetzt ausführen, sollten Sie in der Lage sein, über ein Dutzend in Android Studio gedruckte Operationsnamen zu sehen Logcat Fenster. Wenn unter all diesen Namen keine Fehler beim Einfrieren des Modells aufgetreten sind, können Sie die Namen der Eingabe- und Ausgabe-Layer finden: my_input / X und my_output / Sigmoid.

5. Verwenden des Modells

Um Vorhersagen mit dem Modell treffen zu können, müssen wir Daten in die Eingabeebene einfügen und Daten von der Ausgabeebene abrufen. Um Daten in die Eingabeebene einzufügen, verwenden Sie die Futter() Methode der Schnittstelle, die den Namen der Ebene, ein Array mit den Eingaben und die Abmessungen des Arrays erwartet. Der folgende Code zeigt Ihnen, wie Sie die Nummern senden 0 und 1 zur Eingabeebene:

tfInterface.feed ("my_input / X", floatArrayOf (0f, 1f), 1, 2)

Nach dem Laden von Daten in die Eingabeebene müssen wir eine Inferenzoperation mit der Lauf() Methode, die den Namen der Ausgabeebene erwartet. Sobald der Vorgang abgeschlossen ist, enthält die Ausgabeebene die Vorhersage des Modells. Um die Vorhersage in ein Kotlin-Array zu laden, können wir das verwenden holen() Methode. Der folgende Code zeigt, wie das geht:

tfInterface.run (arrayOf ("my_output / Sigmoid")) val output = floatArrayOf (-1f) tfInterface.fetch ("my_output / Sigmoid", Ausgabe)

Wie Sie die Vorhersage verwenden, liegt natürlich bei Ihnen. Für den Moment schlage ich vor, dass Sie es einfach ausdrucken.

println ("Ausgabe ist $ Ausgabe [0]")

Sie können die App jetzt ausführen, um zu sehen, ob die Vorhersage des Modells korrekt ist.

Sie können die von Ihnen eingegebenen Zahlen der Eingabeebene jederzeit ändern, um sicherzustellen, dass die Vorhersagen des Modells immer korrekt sind.

Fazit

Sie wissen jetzt, wie Sie ein einfaches TensorFlow-Modell erstellen und es mit TensorFlow Mobile in Android-Apps verwenden. Sie müssen sich jedoch nicht immer auf Ihre eigenen Modelle beschränken. Mit den Fertigkeiten, die Sie heute gelernt haben, sollten Sie keine Probleme mit größeren Modellen wie MobileNet und Inception haben, die im TensorFlow-Modellzoo verfügbar sind. Beachten Sie jedoch, dass solche Modelle zu größeren APKs führen, was zu Problemen für Benutzer mit Low-End-Geräten führen kann.

Weitere Informationen zu TensorFlow Mobile finden Sie in der offiziellen Dokumentation.