ESP-DL: hardwarebeschleunigtes maschinelles Lernen für ESP32

Neben Optimierungen im Bereich der Entwicklungswerkzeuge hat Espressif eine neue API angekündigt, die die Erledigung von Machine-Learning-Aufgaben unter Nutzung der in neueren ESP32-Kernen enthaltenen ML-Hardwareressourcen beschleunigt.

von Tam HANNA

Worum geht es hier?

Die einst als reine „Funk-Knechte“ für andere Mikrocontroller gestartete ESP-Familie bekommt im Laufe der letzten Monate fortgeschrittene Funktionen eingeschrieben, die in vielen Applikationen den Host-Mikrocontroller arbeitslos machen.

Mit dem noch nur in Samplemengen verfügbaren ESP32-S3 stellte Espressif eine an Kendryte K210 und Maxim MAX78000 erinnernde Hardware-Beschleunigerengine zur Verfügung, die in ML-Aufgaben anfallende Tasks stark beschleunigt.
Spezifischerweise verspricht Espressif für ein – natürlich handoptimiertes – Modell auf einem S3 folgende Ergebnisse:

1MNIST::forward: 6103 μs
2Prediction Result: 9

Führt man dasselbe Modell hingegen auf einem normalen ESP 32 aus, so fällt die Performance wesentlich bescheidener aus:

1MNIST::forward: 37294 μs
2Prediction Result: 9

Wie bei vielen anderen ML-Beschleunigen gilt, dass die „Krux“ in der Software begraben liegt – eine Aufgabe, der Espressif mit der DL-Bibliothek Abhilfe verschaffen möchte.

Wie funktioniert es für den Embedded-Entwickler.

Die Erzeugung von ML-Modellen ist eine Aufgabe, die man sich als Embedded-Entwickler tunlichst vom Leib halten sollte. Wir wollen für unsere Experimente deshalb das unter https://github.com/espressif/esp-dl/tree/master/examples/cat_face_detect bereitstehende Codebeispiel verwenden, das Katzen zu erkennen sucht.
Am interessantesten ist die Arbeitsschleife, die nach folgendem Schema aufgebaut ist:

1#include <stdio.h>
2#include “image.hpp”
3#include “cat_face_detect_mn03.hpp”
4#include “dl_tool.hpp”

Neben der Datei “cat_face_detect_mn03.hpp”, die das eigentliche Modell bereitstellt, enthält die Datei “image.hpp” das zu verarbeitende Bild. Die von Espressif bereitgestellten Beispiele arbeiten ausschließlich mit in Form von C-Arrays vorliegenden Bilddaten, die das unter https://github.com/espressif/esp-dl/tree/master/tools/convert_tool befindliche Werkzeug auf der Workstation erzeugt.

Der nächste Akt der Arbeitsschleife ist das Laden der eigentlichen Modell-Logik:

1extern “C” void app_main(void)
2{
3 dl::tool::Latency latency;
4 // detector
5 CatFaceDetectMN03 cat_face_detect(0.4F, 0.3F, 10, 0.3F);
6
7 // inference
8 latency.start();
9 std::list<dl::detect::result_t> &results = cat_face_detect.infer((uint8_t *)IMAGE_ELEMENT, {IMAGE_HEIGHT, IMAGE_WIDTH, IMAGE_CHANNEL});
10 latency.end();
11 latency.print(“Inference latency”);
12
13 int i = 0;
14 for (std::list<dl::detect::result_t>::iterator prediction = results.begin(); prediction != results.end(); prediction++, i++)
15 {
16 printf(“[%d] score: %f, box: [%d, %d, %d, %d]n, i, prediction->score, prediction->box[0], prediction->box[1], prediction->box[2], prediction->box[3]);
17 }
18}

Der Rest des Codes ist dann gewöhnliches Betreiben eines Hardware-Beschleunigers. Informationen wandern im ersten Schritt in die dafür bereitgestellten Register, aus denen wir die Ergebnisse danach wieder abernten.
Ausgabewert des Programms sind dabei Koordinatenwerte, die – siehe auch die Abbildung – für vom ML-Modell als relevant erkannte Teile des Bildes markieren. Für ihre Visualisierung steht am Desktop ebenfalls ein Werkzeug zur Verfügung, das sie nach folgendem Schema aufrufen:

1python display_image.py i ../cat_face_detect/image.jpg b “(122, 2, 256, 117)”

(Bildquelle: https://github.com/espressif/esp-dl/blob/master/examples/cat_face_detect/result.png)

Erzeugung hauseigener Modelle.

Obwohl Espressif im unter https://github.com/espressif/esp-dl/tree/master/include/model_zoo bereitstehenden und apart als Model Zoo bezeichneten Repository eine Gruppe schlüsselfertige Modelle für ESP32-Entwickler bereitstellt, wünscht man sich in der Praxis die Verwendung „hauseigener“ Modelle.
Informationen dazu, wie man ein vorliegendes Modell für den ESP32 einsatzbereit macht, finden sich in der unter https://github.com/espressif/esp-dl/tree/master/tutorial bereitstehenden fünfstufigen Anleitung.
Offensichtlich ist schon hier, dass zur Nutzung Handarbeit erforderlich ist. Die einzelnen „Layers“ eines Modells muss der Entwickler beispielsweise von Hand in der von Espressif bereitgestellten Modell-Basisklasse anlegen:

1class MNIST : public Model<int16_t>
2{
3private:
4 Conv2D<int16_t> l1; // a layer named l1
5 DepthwiseConv2D<int16_t> l2_depth; // a layer named l2_depth
6 Conv2D<int16_t> l2_compress; // a layer named l2_compress

Analoges gilt auch für die Initialisierung, deren Generierung – zumindest zum Zeitpunkt der Drucklegung – ebenfalls Handarbeit voraussetzt:

1class MNIST : public Model<int16_t>
2{
3 // ellipsis member variables
4
5 MNIST() : l1(Conv2D<int16_t>(2, get_l1_filter(), get_l1_bias(), get_l1_activation(), PADDING_VALID, 2, 2, “l1”)),
6 l2_depth(DepthwiseConv2D<int16_t>(1, get_l2_depth_filter(), NULL, get_l2_depth_activation(), PADDING_SAME, 2, 2, “l2_depth”)),
7 l2_compress(Conv2D<int16_t>(3, get_l2_compress_filter(), get_l2_compress_bias(), NULL, PADDING_SAME, 1, 1, “l2_compress”)),

Lohnt es sich?

Wer auf einem ESP32 ML-Aufgaben mit hoher Performance ausführen möchte, ist gut beraten, dem unter https://github.com/espressif/esp-dl/ bereitstehenden GitHub-Repository Aufmerksamkeit zu geben. Auch wenn die Lernkurve des ML-Frameworks mit Sicherheit steil ist, dürfte das manuelle Entwickeln von einer hardwarebeschleunigten Engines für den ESP32 noch viel arbeitsamer sein.

Zuerst erschienen bei Mikrocontroller.net News

Quelle: Read More