Wie erstelle ich meine eigenen neuronalen Netze und binde diese in eine Flutter-Applikation ein?
Zur Verwendung künstlicher neuronaler Netze (KNN) können verschiedene Vorgehensweisen in Betracht gezogen werden. Man kann diese beispielsweise „von Hand“ mittels Python selbst erstellen, bereits erstellte und trainierte Netze verwenden oder auch Hilfetools benutzen. In diesem Blogbeitrag wird der Einfachheit halber die Teachable Machine (https://teachablemachine.withgoogle.com) von Google verwendet, um das einzubindende KNN bereitzustellen und diese künstlich erstellten neuronalen Netze mithilfe von TensorFlow in Flutter einzubinden.
Was ist die Teachable Machine?
„Teachable Machine ist ein webbasiertes Tool, mit dem sich Modelle für maschinelles Lernen schnell und einfach erstellen lassen und das für alle zugänglich ist.“ (siehe https://teachablemachine.withgoogle.com). Unser Netz soll Hunde- und Katzenbilder unterscheiden beziehungsweise klassifizieren können. Dahingehend erstellen wir unser Netz mithilfe der Teachable Machine wie folgt:
Wir haben die Möglichkeit, bei der Teachable Machine ein Bild-, Audio oder Posenprojekt zu erstellen. Wir entscheiden uns hier für ein Bildprojekt. Anschließend erscheint der folgende Screen:
Dort legen wir nun unsere Bildbeispiele für die Klassen „Hund“ und „Katze“ ab, um das Netz anschließend auf Grundlage dieser importierten Beispiele zu trainieren – hierfür genügt ein einen Klick auf „Modell trainieren“, um das Training zu starten.
Nachdem das Modell erfolgreich trainiert wurde, kann es konvertiert und exportiert werden. Zur Einbindung des gerade erstellten KNNs verwenden wir ein TensorFlow Lite Modell und legen als Konvertierungs-Typ des Modells „Gleitkomma“ fest.
Im letzten Schritt kann dann das Modell heruntergeladen werden. Daraus resultiert eine zip-Datei, welche zum einen das trainierte Modell als .tflite-Datei enthält und zum anderen eine labels.txt-Datei, welche die Klassennamen beinhaltet. Diese beiden Dateien können nun in das Flutter-Projekt eingebunden werden.
Setup TensorFlow
Im Flutter-Projekt werden folgende Bibliotheken benötigt:
Verständlicherweise wird die tflite-Bibliothek verwendet, um das trainierte KNN zu laden und auf dem Smartphone inferenzieren zu können. Als weitere Bibliothek wird hier auf die image_picker-Bibliothek gesetzt, damit wir lokal gespeicherte Bilder von dem Gerät laden können, um diese dann zu klassifizieren.
Zudem müssen noch die beiden heruntergeladenen Dateien von der Teachable Machine eingebunden werden. Dafür wird auf gleicher Hierarchieebene wie der lib-Ordner aus dem Flutter-Projekt ein assets-Ordner erstellt, welcher die beiden Dateien beinhaltet:
Um diese dann auch nutzen zu können, muss Folgendes in der pubspec.yaml festgelegt werden:
Flutter-Implementierung mit TensorFlow
Vorab: In diesem Blogbeitrag geht es einzig und allein um die Einbindung von künstlich erstellten neuronalen Netzen mithilfe von TensorFlow in eine Flutter-Applikation. In dem Codebeispiel werden keine Architekturpattern nach Best Practices, clean code oder Ähnliches berücksichtigt. Die gerade aufgezählten Prinzipien hinsichtlich clean code und Architekturmuster können im folgenden Beitrag nachgelesen werden: https://www.adesso-mobile.de/flutter/business-logic-components/
Zunächst verwenden wir drei global definierte Variablen. Zum einen benötigen wir eine ImagePicker-Instanz, welche zum Laden eines lokal gespeicherten Bildes benötigt wird. Dieses wird anschließend dem KNN
vorgelegt, welches dann schließlich klassifiziert werden soll. Das lokal geladene Bild befindet sich dann in der Variable _chosenImage. Die dritte Variable beinhaltet die Klassifikationen, die vom neuronalen Netz inferiert wurden. Bei der Inferenzbildung wird eine Liste als Rückgabetyp ausgegeben, da man den Klassifikator auch so konfigurieren kann, dass er mehrere Klassifikationen zu einem Bild ausgibt. In diesem Beispiel wird aber lediglich eine Klassifikation zu einem Eingabebild ausgegeben (siehe Attribut numResults).
Da wir ein StatefulWidget verwenden, können wir die initState-Methode zum Laden des neuronalen Netzes nutzen:
Das Laden des künstlich erstellten neuronalen Netzes aus den assets erfolgt durch folgenden Code-Abschnitt:
Der nächste Schritt wäre das Rendern der UI. Dies geschieht folgendermaßen:
Der Übersichtlichkeit halber wurden die einzelnen Teil-Widgets in separate Methoden ausgelagert. Zunächst das Widget, welches die Klassifikation, die mittels TensorFlow ermittelt wird, anzeigen soll:
Solange kein Bild aus dem lokalen Speicher geladen wurde, wird ein zirkulärer Ladeindikator angezeigt. Wurde ein Bild erfolgreich geladen, wird dieses anstelle des Ladeindikators angezeigt und hinsichtlich der Klassifikationen das Label des ersten Eintrags angezeigt.
Zum Laden des Bildes wird ein Button verwendet. Dieser ruft bei einem Klick die Methode _pickImage auf:
Die Methode _pickImage öffnet die Galerie, sodass der Nutzer ein lokales Bild aus dieser laden kann. Wurde ein Bild ausgewählt und aus der Galerie geladen, wird anschließend die Methode _predict zur Vorhersage der Klassifikation aufgerufen:
Die Methode _predict ruft dann die Methode runModelOnImage aus der TensorFlow-Bibliothek auf, um eine Vorhersage auf dem ausgewählten Bild zu treffen. Dort können einige Einstellungsparameter festgelegt werden.
- path: Der Pfad zum lokalen Bild
- threshold: Die Vorhersage muss mindestens diesen Konfidenzscore haben, damit die Klassifikation wahrgenommen wird
- numResults: Die Anzahl der Resultate, die in den Klassifikationen auftreten kann/soll
- imageMean: Dient der Normalisierung und bildet den mittleren Pixelwert des Bilddatensatzes ab
- imageStd: Dient der Normalisierung und bildet die Standardabweichung ab
Nachdem das Modell eine Klassifizierung prädiziert hat, wird diese der global definierten Variable zugewiesen und schlussendlich auf der UI angezeigt. Die App sieht dann wie folgt aus:
Fazit
Der Blogbeitrag sollte zum einen auf die Teachable Machine von Google aufmerksam machen, durch die es möglich ist, relativ einfach eigene künstliche neuronale Netze zu erstellen. Darüber hinaus können diese dann noch in ein gängiges Format exportiert werden, um diese zum Beispiel in eine App einbinden zu können. Zum anderen hat der Beitrag aufgezeigt, wie die Einbindung solcher KNNs in eine Flutter-Applikation aussehen kann. Man konnte anhand des relativ überschaubaren Aufwands an Code feststellen, dass das Einbinden dieser simpel und zuverlässig funktioniert.