Make 4/2023
S. 82
Make
Projekt

KI für die Modelleisenbahn, Teil 2

Ein Raspberry Pi überwacht mit einer Kamera Gleise und meldet, wenn Loks auf falschen Schienen fahren oder überfällig sind. In diesem Teil zeigen wir, wie man das Neuronale Netz mit Google Colab modelliert, mit den in Teil 1 bearbeiteten Bildern trainiert und exportiert.

von Detlef Heinze

In diesem Teil trainieren wir unser Neuronales Netz. Dazu setzen wir auf die Online-Entwicklungsumgebung Google Colab. Colab ist eine kostenlos nutzbare Alternative zu einer lokal auf dem PC laufenden Jupyter-Umgebung. In unserer „KI auf dem ESP32“-Artikelstrecke haben wir die Bedienung von Jupyter Notebooks in Artikeln und ergänzenden Videos erklärt (siehe Links in der Kurzinfo).

Das Training basiert auf der ModelMaker-API von Google. Die API erwartet, dass die Trainingsbilder in drei Untermengen aufgeteilt werden: Dies sind die Trainings-, die Validierungs- und die Testdaten. Wir verwenden eine Aufteilung von 80%-10%-10%. Darüber hinaus erwartet das API eine spezielle CSV-Datei als Input.

Im Ordner auf dem PC mit den Trainingsdaten liegt das Python3-Programm VIAjson2ModelMaker.py, also unter 20_Example_Training/20_Data. Man startet es in der Konsole mit python3 VIAjson2ModelMaker.py. Sofern auf dem PC kein Python verfügbar ist und Sie es nicht nachinstallieren wollen, kopieren Sie am besten das ganze Verzeichnis auf einen USB-Stick, stecken ihn an den Pi und wechseln in einer Shell auf das Verzeichnis auf dem Stick. Das Skript greift auf die Datei VIA_SMRC_json.json im gleichen Ordner und alle Bilder zu und erstellt in ein paar Sekunden die Datei training.csv für das Training. Die Aufteilung der Bilder bestimmt der Zufallsgenerator.

Je nach Ausgangslage können Sie nun auf dem PC oder dem Pi weiterarbeiten. Die restliche Arbeit übernimmt nun nämlich Google.

Training

Das Training erfolgt in der Cloud mit Google Colab. Dort kann man auf per GPU beschleunigten Servern neuronale Netze bis zu einem begrenzten Umfang kostenlos trainieren. Sie benötigen keine lokale Installation. Voraussetzung ist nur ein Google Account. Für das Training verwenden wir ein Jupyter-Notebook, das unter 20_Example_Training/30_Training liegt.

Den Link zum Starten des Juypter-Notebooks finden Sie im Repo-Verzeichnis bzw. im Ordner 20_Example_Training/30_Training.
Den Link zum Starten des Juypter-Notebooks finden Sie im Repo-Verzeichnis bzw. im Ordner 20_Example_Training/30_Training.

Das Jupyter-Notebook benutzt sogenanntes Transfer-Learning. Dabei wird ein bereits trainiertes Modell auf Loks und Waggons umtrainiert. Das spart erheblich Zeit. Die Trainingszeiten liegen mit den GPUs in der Cloud mit unserem Beispiel bei nur ca. 10-12 Minuten. Als Ergebnis liefert das Jupyter-Notebook mit einem Durchlauf ein fertiges quantifiziertes TensorFlow Lite Model, das auf dem Coral-USB-Accelerator-Stick lauffähig ist.

Damit das Training in der Google Cloud stattfinden kann, müssen die Trainingsdaten in Ihr Google Drive hochgeladen werden. Dazu melden Sie sich auf dem PC oder Pi mit Ihrem Google-Account auf google.de an und wechseln in Ihr Google Drive.

In Google Drive müssen alle Trainingsdaten und -skripte im Ordner TrainData liegen.
In Google Drive müssen alle Trainingsdaten und -skripte im Ordner TrainData liegen.

Dort legen Sie einen neuen Ordner TrainData direkt unter dem Wurzelverzeichnis an. Wechseln Sie in den Ordner und laden Sie alle Trainingsbilder sowie die Datei training.csv und train.py in den neuen Ordner hoch. Der Ordner darf keine Unterordner haben.

Colab

Nun können wir mit dem Training beginnen. Öffnen Sie einen Browser mit dem Link zum GitHub-Repository (siehe Artikel-Links). Navigieren Sie dort zum Ordner 30_Your_Training/30_Training und klicken Sie im Text unten den Link „Open Colab notebook...“ an.

Das Jupyter Notebook öffnet sich und Sie können sich mit Ihrem Google-Account anmelden. Es enthält den Verlauf eines vorherigen Trainings zum Ansehen. Stellen Sie im Menü unter Laufzeit (Runtime) den Laufzeittyp GPU ein. Das Jupyter Notebook hat drei Hauptabschnitte:

  • Step 1: „Create runtime environment for Python 3.9 and ModelMaker“ (Dauer etwa 5 Minuten). Der Benutzer muss auf Nachfrage zweimal mit „y“ (yes) antworten. Die zwei Orte sind gekennzeichnet.
  • Step 2: „Training of the model“. Hier ruft das Jupyter Notebook die Datei train.py auf. Diese Datei muss im TrainData-Verzeichnis auf dem Google-Drive liegen wie die Datei training.csv.
  • Step 3: „Compile tflite-model for the Edge TPU“

Nun können Sie jede Codezelle vom Anfang bis zum Ende der Reihenfolge nach einzeln starten (empfohlen). Dazu müssen Sie am Anfang jeder Zelle auf den Play-Button klicken. In unseren Durchläufen kam es hin und wieder mal zu einer Fehlermeldung, wenn das Skript in das Verzeichnis des Google Drives wechselt: „Not found“. Dieser Fehler trat meist dann auf, wenn das Jupyter Notebook wegen längerer fehlender Interaktion mit dem Nutzer (mal eben Kaffee holen und dann mit Kollegen in Plauderei versinken) die aktive Verbindung unterbrach. Abhilfe brachte es nur, das komplette Notebook neu zu starten.

Zum Start der einzelnen Zellen muss man links den Play-Button anklicken. Sobald die Zelle durchgelaufen ist, erscheint ein grüner Haken links neben dem Button.
Zum Start der einzelnen Zellen muss man links den Play-Button anklicken. Sobald die Zelle durchgelaufen ist, erscheint ein grüner Haken links neben dem Button.

Modell übernehmen und testen

Das Training ist in unserem Beispiel sehr erfolgreich, wenn im Abschnitt „Evaluate the TF-Lite-Model“ der Wert für AP (Average Precision) größer als 0.7 ist. Falls der Wert deutlich kleiner ist, sollten Sie das Training wiederholen.

Bei der Installation und Konfiguration der Laufzeitumgebung fragt das Notebook mehrfach, ob es weitermachen soll. Das bestätigt man mit einem Klick rechts neben dem Dialog. Es öffnet sich ein Eingabefeld, in das man „y“ tippt und mit Enter bestätigt.
Bei der Installation und Konfiguration der Laufzeitumgebung fragt das Notebook mehrfach, ob es weitermachen soll. Das bestätigt man mit einem Klick rechts neben dem Dialog. Es öffnet sich ein Eingabefeld, in das man „y“ tippt und mit Enter bestätigt.

Das Ergebnis des Trainings ist ein Modell, das in der Datei smrc_model_edgetpu.tflite auf den PC oder Pi heruntergeladen wird. Zusätzlich lädt der Browser die Datei railwayLabels.txt mit den Klassennamen herunter. Diese beiden Dateien kopieren Sie in das Applikationsverzeichnis auf dem Raspberry Pi, wo das Python-Programm SMRC_Main.py liegt. Nun können Sie die Anwendung SMRC_Main.py auf dem Raspberry Pi starten und das neue Modell mit der Eisenbahn testen, dazu gleich mehr.

Work in progress: Tensorflow trainiert das Modell.
Work in progress: Tensorflow trainiert das Modell.

Nicht immer ist das Ergebnis eines Trainings im Einsatz befriedigend. Modelle können False-positives hervorbringen. Dies sind erkannte Objekte, die mit einer falschen Klasse identifiziert werden. So kann es z.B. sein, dass ein Waggon als Lok erkannt wird, weil er in Größe und Farbe ähnlich ist.

Liegt der Objekt-Score (die Prozentzahl am erkannten Objekt) von False-positives regelmäßig mindestens 15% unter dem von richtig erkannten Objekten, können wir sie herausfiltern. In der Datei SMRC_Contr.py können Sie in der Funktion __init__() den Wert minObjectScore 0.6 (60%) erhöhen. Ist dieser Wert aber zu hoch, werden auch die richtig erkannten Objekte herausge-filtert.

Ein gelungenes Training zeichnet sich durch einen AP größer als 0.7 aus.
Ein gelungenes Training zeichnet sich durch einen AP größer als 0.7 aus.

Eine zweite Möglichkeit, das Problem zu beheben besteht darin, das Training mit anderen Parametern zu wiederholen. Im Abschnitt „Create and train the model“ in unserem Trainingsprogramm können Sie den Wert für epochs z.B. zwischen 30 und 80 variieren. Der Wert gibt an, wie oft Trainingsschritte wiederholt werden. Mehr Trainingsschritte passen das Modell besser an die Trainingsdaten an. Ähnliche Objekte werden dann nicht mehr so gut erkannt. Ist der Wert aber zu hoch, kann der Objekt-Score von richtig erkannten Objekten sinken, da sie nie exakt gleich wie die Trainingsdaten aussehen. Diesen Effekt nennt man Overfitting.

Nach einem vollständigen Durchlauf des Notebooks lädt der Browser zwei Modell-Dateien herunter.
Nach einem vollständigen Durchlauf des Notebooks lädt der Browser zwei Modell-Dateien herunter.

Hilft der letzte Ansatz nicht, kann man eine weitere Klasse für ein False-positive-Objekt zum Training hinzufügen. Dann müssen Sie wieder alle fünf Schritte des KI-Trainings von vorn beginnen. Die einfachste, aber nicht so schöne Lösung ist es, den betroffen Waggon oder die Lok von der Anlage zu nehmen.

Eine dritte Möglichkeit besteht darin, die Anzahl der Trainingsdaten für alle Objekte gleichmäßig zu erhöhen. Statt wie in unserem Beispiel 240 Bilder pro Objekt, könnten z.B. 360 oder 480 Bilder eine Verbesserung bringen. Die Erstellung und Anwendung von KI-Modellen hat auch immer etwas vom „Trial and Error“. Experimentieren Sie mit dem Projekt und haben Sie Spaß; so lernt nicht nur das KI-Model etwas, sondern auch Sie.

Anwendung

Alle für die Anwendung wichtigen Dateien liegen im Verzeichnis 10_SMRC_Application. Die Hauptanwendung startet man mit python3 SMRC_Main.py. Sie ist konfigurierbar, um Bereiche und Regeln an die eigene Anlage anzupassen. Die Konfiguration von Bereichen (Gleise) erfolgt in der Datei detectionRegions.json. Sie enthält eine Liste von definierten Bereichen. Jeder Bereich hat einen Namen, gefolgt von einer Rechteck-Definition mit linker oberer und rechter unterer Ecke. Ein Bereich muss auf das Kamerabild mit der Auflösung von 320 × 320 Punkten passen. Hier das Beispiel für Gleis 1:

{ "name": "Gleis 1",
"x1": 2,
"y1": 208,
"x2": 318,
"y2": 216
}

Die Anwendung im Betrieb: Das Neuronale Netz hat zwei Loks und eine Regelverletzung erkannt.
Die Anwendung im Betrieb: Das Neuronale Netz hat zwei Loks und eine Regelverletzung erkannt.

Enthält die Datei mehrere Bereiche (Gleise), so definiert die Reihenfolge eine Priorität. Schneidet eine Lokomotive zwei Bereiche gleichzeitig, so wird sie dem Bereich zugeordnet, der zuerst in der Datei konfiguriert ist.

Nun zu der Konfiguration der Regeln in der Datei notAllowedRules.json (siehe Listing Seite 81). Es zeigt fünf Beispielregeln. Darunter sind auch die drei oben erwähnten Regeln. Jede Regel nimmt Bezug auf einen der konfigurierten Bereiche (Gleise), auf einen der drei Lokzustände sowie auf eine Lokomotive, die das Modell für die Objekterkennung erkennen kann.

Die Anwendung zeigt nicht nur in der grafischen Oberfläche Informationen an, im Terminalgibt es alle Ereignisse zusätzlich aus.
Die Anwendung zeigt nicht nur in der grafischen Oberfläche Informationen an, im Terminalgibt es alle Ereignisse zusätzlich aus.

Weiterhin muss man bei der Konfiguration einer Regel angeben, ob die Regelverletzung für einen Zeitraum in Sekunden geduldet werden soll. Soll es keinen Duldungszeitraum geben, so gibt man bei "allowedFor": 0 an.

Zusätzlich zu den Regeln kann man in der Datei den Schalter "mailNotification" mit "off" oder "on"belegen. Ist er eingeschaltet, sendet das Programm die jeweilige Regelverletzung an ein E-Mail-Postfach. Bevor Sie die Mail-Benachrichtigung einschalten, müssen Sie in der Python-Datei MailSender.py die Verbindungen zu einem absendenden und einem empfangenden Postfach angeben.

Es sei jedoch darauf hingewiesen, dass Mail-Provider erkennen können, wenn Mails von Programmen in zu schneller Folge oder in zu großer Anzahl generiert werden. Sie wollen damit Spam-Nachrichten verhindern. Achten Sie auf Meldungen auf dem LXTerminal, ob Nachrichten abgesendet wurden. Und nun: „Gute Fahrt“. —dab