Ein Deep Neural Network auf einem Cortex-M7-Mikrocontroller von ST ausführen

Mit dem Erweiterungspaket STM32Cube.AI ermöglicht STMicroelectronics ein Neuronales Netz auf einen Mikrocontroller auszuführen. In dem folgenden Beispiel LED-Monitoring wird ein DNN (Deep Neuronal Network) mit Keras/Tensorflow erstellt, dann mittels STM32Cube.AI in das C-Projekt importiert und anschließend auf dem Testboard  Nucleo-F767ZI ausgeführt.

Das Beispiel veranschaulicht die Machbarkeit und Vorgehensweise.

Quellcode: https://github.com/embmike/State-Monitoring-With-AI

Aufgabe

Mittels der Schalttabelle

Schalttabelle

werden User-LED1 Grün auf Pin PB0 und User-LED3 Rot auf Pin PB14 auf dem Board Nucleo-F767ZI angesteuert.

Nucleo-F767Z

Werkzeuge

  • Keras: Open Deep-Learning -Bibliothek für Python
  • Tensorflow: Open Source Bibliothek zum Training und Entwicklung von Modellen des maschinellen Lernens (Machine Learning)
  • Spyder IDE: Scientific Python Development Environment
  • STM32CubeIDE: Die Software-Entwicklungsumgebung von ST für Mikrocontroller und Mikroprozessoren wie STM32F767
  • Nucleo-F767ZI: Entwicklungsboard von ST
  • Hercules SETUP utility: Serial Port Terminal

Auflauf

  1. Entwicklung des DNN in der Spyder IDE mit den Bibliotheken Keras/Tensorflow
  2. Training und Validierung des DNN
  3. DNN als h5-Datei speichern
  4. C-Projekt in der STM32CubeIDE anlegen
  5. DNN-h5-Datei importieren und validieren
  6. Die DNN-C-Funktion implementieren
  7. DNN-C-Funktion ausführen und prüfen

Entwicklung des DNN in der Spyder IDE mit den Bibliotheken Keras/Tensorflow

Mittels led_monitoring = Sequential() wird ein DNN angelegt. Es besteht aus :

  • einer vollständig verbundenen Eingangsschicht mit 48 Neuronen und jeweils mit einer Rectifier-Aktivierungsfunktion (ReLU) 
  • einer vollständig verbundenen Ausgangsschicht mit 3 Neuronen und mit einer Softmax-Aktivierungsfunktion

Deep Neural Network: led_monitoring

Deep Neural Network

Training und Validierung des DNN

Da das DNN ein einfaches Schaltwerk mit wenigen aber vollständigen Anwendungsfällen ist, ist eine Aufteilung zwischen Trainings- und Testset nicht notwendig.

Bereits nach 38 Trainingsepochen wird eine Modellgenauigkeit von 100% erzielt.

Modellgenauigkeit des DNN

Ausgabeschicht mit den 3 Wahrscheinlichkeiten der Klassifikationen  je Eingangsvektor der Schalttabelle.

Modellgenauigkeit

DNN als h5-Datei speichern

C-Projekt in der STM32CubeIDE anlegen

STM32CubeIDE starten und File > New > STM32 Project auswählen. Im Board Selector das Board Nucleo-F767ZI auswählen und Next klicken.

Board Selector

LED_Monitoring als Projektname angeben und Finish klicken.

DNN-h5-Datei importieren, validieren und Quellcode generieren

Datei LED_Monitoring.ioc öffnen. Auf das Tab Additional Software klicken. Im Fenster Additional Software Components selection die Checkbox Artificial Intelligence auswählen. Unter Packs Core und Application Templates auswählen. Anschließend auf Ok klicken.

STM32CubeMX.AI

Im Tab Categories, unter Additional Software den Menüpunkt STMicroelectronics X-CUBE-AI anklicken.  In Fenster Artificial Intelligence X-CUBE-AI und Artificial Intelligence Application auswählen. Im Fenster Configuration auf Add network klicken. Im Bereich Model inputs als Name led_monitoring_network eintragen. Darunter links Keras und rechts Saved model auswählen. Darunter bei Model: nach dem Netzwerk led_monitoring.h5 browsen. Das Netzwerk ist nun importiert.

Keras model

Nun muss überprüft werden, ob die Speicher für das Netzwerk ausreichen oder es komprimiert werden muss. Nun auf Analyze klicken. Passt das Netzwerk in die Speicher erscheint bei Analyze ein grüner Haken.

Grüner Haken

Nun auf Save all oben in der Menüleiste klicken. STM32CubeMX generiert den Initialcode.

Die DNN-C-Funktion implementieren

Die Datei main.c im Order LED_Monitoring > Core > Src öffnen. Die DNN-Funktion MX_X_CUBE_AI_Process() wird zyklisch in der while der main() aufgerufen.

main.c

Die DNN-Funktion MX_X_CUBE_AI_Process() befindet sich in der Quellcode-Datei LED_Monitoring > X-CUBE-AI > App > app_x-cube-ai.c. Mit jedem der 4 Use cases wird das DNN mit der Funktion aiRun(in_data, out_dataaufgerufen.

Der Parameter in_data ist der jeweilige Eingabe-Vektor, wie 

((ai_float *)in_data)[0] = (ai_float) 0.0f;

((ai_float *)in_data)[1] = (ai_float) 0.0f;

Der Parameter out_data beinhaltet die 3 Werte (p(0), p(1), p(2)) der Ausgangsschicht. Die 3 Werte geben die jeweilige Wahrscheinlichkeit der Klassifikation wieder. Der größte Wahrscheinlichkeit ist Klassifikation zum Eingangsvektor.

Mit jedem Use case werden die User-LEDs entsprechend angesteuert sowie Debugausgaben mittels prinf > Uart3 > Serial Port Terminal ausgegeben.

Die DNN-C-Funktion ausführen und prüfen

Das Bord wird mit der Software programmiert. Der schwarze Reset-Taster auf dem Board betätigt. Anschließend im Serial Port Terminal im Tab Serial die Verbindung zum Board mittels einem Klick auf dem Open Button hergestellt.

LED monitoring terminal

Im Ergebnis wird die Schalttabelle als DNN auf dem Mikrocontroller korrekt ausgeführt.