KI-Spracherkennung mit TensorFlow Lite für Mikrocontroller und SparkFun Edge

1. Einführung

Umfang

In diesem Codelab lernen wir, wie wir TensorFlow Lite For Microcontrollers verwenden, um ein Deep-Learning-Modell auf dem SparkFun Edge Development Board auszuführen. Wir verwenden das integrierte Spracherkennungsmodell des Boards, das ein faltendes neuronales Netzwerk nutzt, um die Wörter „Ja“ und „Nein“ zu erkennen, die über die beiden Mikrofone des Boards gesprochen werden.

bf256d403a1821af.gif

Machine Learning auf Mikrocontrollern

Mit maschinellem Lernen lassen sich intelligente Tools wie Google Assistant entwickeln, die den Alltag der Nutzer erleichtern. Oft erfordern diese Funktionen jedoch viel Rechenleistung oder Ressourcen, z. B. einen leistungsstarken Cloud-Server oder einen Desktop-Computer. Es ist jedoch jetzt möglich, ML-Inferenz auf winziger Hardware mit geringem Stromverbrauch wie Mikrocontrollern auszuführen.

Mikrocontroller sind sehr verbreitet, günstig, benötigen sehr wenig Energie und sind sehr zuverlässig. Sie sind in allen Arten von Haushaltsgeräten enthalten, z. B. in Geräten, Autos und Spielzeug. Tatsächlich werden jedes Jahr etwa 30 Milliarden Geräte mit Mikrocontrollern hergestellt.

1360b61fbfa33657.jpeg

Durch den Einsatz von Machine Learning auf winzigen Mikrocontrollern können wir die Intelligenz von Milliarden von Geräten, die wir in unserem Leben verwenden, steigern, ohne auf teure Hardware oder zuverlässige Internetverbindungen angewiesen zu sein. Stellen Sie sich intelligente Geräte vor, die sich an Ihren Alltag anpassen, intelligente Industriesensoren, die zwischen Problemen und normalem Betrieb unterscheiden können, und magische Spielzeuge, die Kindern auf unterhaltsame Weise helfen, zu lernen.

TensorFlow Lite For Microcontrollers (Software)

358ffdb9eb758b90.png

TensorFlow ist das Open-Source-Framework von Google für maschinelles Lernen zum Trainieren und Ausführen von Modellen. TensorFlow Lite ist ein Software-Framework, eine optimierte Version von TensorFlow, die für die Ausführung von TensorFlow-Modellen auf kleinen, relativ leistungsschwachen Geräten wie Mobiltelefonen entwickelt wurde.

TensorFlow Lite For Microcontrollers ist ein Software-Framework, eine optimierte Version von TensorFlow, die darauf ausgelegt ist, TensorFlow-Modelle auf kleiner, stromsparender Hardware wie Mikrocontrollern auszuführen. Es hält sich an die in diesen eingebetteten Umgebungen erforderlichen Einschränkungen, d. h., es hat eine geringe Binärgröße, erfordert keine Unterstützung durch das Betriebssystem, keine Standard-C- oder C++-Bibliotheken oder dynamische Speicherzuweisung usw.

SparkFun Edge (Hardware)

SparkFun Edge ist eine auf einem Mikrocontroller basierende Plattform – ein winziger Computer auf einer einzigen Leiterplatte. Es verfügt über einen Prozessor, Arbeitsspeicher und E/A-Hardware, mit denen digitale Signale an andere Geräte gesendet und von anderen Geräten empfangen werden können. Es hat vier softwaregesteuerte LEDs in den Google-Farben.

aa4493835a2338c6.png

Im Gegensatz zu einem Computer wird auf einem Mikrocontroller kein Betriebssystem ausgeführt. Stattdessen werden die von Ihnen geschriebenen Programme direkt auf der Hardware ausgeführt. Sie schreiben Ihren Code auf einem Computer und laden ihn über ein Gerät namens Programmer auf den Mikrocontroller herunter.

Mikrocontroller sind keine leistungsstarken Computer. Sie haben kleine Prozessoren und wenig Arbeitsspeicher. Da sie jedoch so einfach wie möglich konzipiert sind, kann ein Mikrocontroller sehr wenig Energie verbrauchen. Je nachdem, was Ihr Programm macht, kann der SparkFun Edge wochenlang mit einer einzigen Knopfzelle betrieben werden.

Lerninhalte

  • Beispielprogramm für SparkFun Edge auf Ihrem Computer kompilieren
  • Programm auf dem Gerät bereitstellen
  • Änderungen am Programm vornehmen und es noch einmal bereitstellen

Voraussetzungen

Sie benötigen folgende Hardware:

Sie benötigen folgende Software:

  • Git (prüfen Sie, ob es installiert ist, indem Sie git in der Befehlszeile ausführen)
  • Python 3 (prüfen Sie, ob es installiert ist, indem Sie python3 oder python --version in der Befehlszeile ausführen)
  • Pip für Python 3 ( hilfreiche StackOverflow-Antwort)
  • Version 4.2.1 oder höher (prüfen Sie, ob sie installiert ist, indem Sie make --version in der Befehlszeile ausführen)
  • SparkFun Serial Basic-Treiber

2. Hardware einrichten

Der SparkFun Edge-Mikrocontroller wird mit einer vorinstallierten Binärdatei geliefert, mit der das Sprachmodell ausgeführt werden kann. Bevor wir das mit unserer eigenen Version überschreiben, führen wir das Modell erst einmal aus.

So können Sie Ihr Board mit Inhalten füllen:

  1. Setzen Sie eine Knopfzelle in den Akkuanschluss auf der Rückseite des Boards ein (mit der „+“-Seite des Akkus nach oben). Wenn das Board bereits mit einer eingesetzten Batterie geliefert wurde, ziehen Sie den Kunststoffstreifen heraus und drücken Sie die Batterie hinein, um sicherzustellen, dass sie vollständig eingesetzt ist.

25a6cc6b208e8a4e.png

  1. Wenn Sie keine Knopfzelle haben, können Sie das SparkFun USB‑C Serial Basic-Programmiergerät verwenden, um das Board mit Strom zu versorgen. So befestigen Sie das Gerät an Ihrem Board:
  • Suchen Sie den 6-poligen Header an der Seite des SparkFun Edge.
  • Stecke den SparkFun USB‑C Serial Basic in diese Pins und achte darauf, dass die Pins mit der Aufschrift „BLK“ und „GRN“ auf beiden Geräten richtig ausgerichtet sind.
  • Verbinden Sie das SparkFun USB‑C Serial Basic über ein USB‑C-Kabel mit Ihrem Computer.

b140822f0019f92a.png

Sobald Sie das Board mit Strom versorgt haben, indem Sie die Batterie einsetzen oder den USB-Programmierer anschließen, wird es aktiviert und beginnt, mit seinen Mikrofonen zuzuhören. Das blaue Licht sollte anfangen zu blinken.

Das ML-Modell auf dem Board ist darauf trainiert, die Wörter „Ja“ und „Nein“ zu erkennen und das Vorhandensein und Fehlen von Sprache zu erkennen. Die Ergebnisse werden durch farbige LEDs angezeigt. In der folgenden Tabelle wird die Bedeutung der einzelnen LED-Farben beschrieben:

Erkennungsergebnis

LED-Farbe

"Ja"

Gelb

"Nein"

Rot

Unbekannte Sprache

Grün

Kein gesprochener Text erkannt

Keine LEDs leuchten

Probieren Sie es aus!

Halten Sie das Board vor Ihren Mund und sagen Sie mehrmals „Ja“. Die gelbe LED blinkt. Wenn nichts passiert, wenn Sie „Ja“ sagen, können Sie Folgendes versuchen:

  • Halte das Board etwa 25 cm von deinem Mund entfernt.
  • Übermäßige Hintergrundgeräusche vermeiden
  • Wiederholen Sie „Ja“ mehrmals kurz hintereinander (sagen Sie z. B. „Ja, ja, ja“).

3. Software einrichten

Wir laden das Sprachmodell jetzt herunter, installieren es und führen es auf dem Mikrocontroller aus. Dazu laden wir zuerst den Quellcode für dieses Programm und die Abhängigkeiten herunter, die wir zum Erstellen benötigen. Das Programm ist in C++ geschrieben und muss in eine Binärdatei kompiliert werden, bevor es auf das Board heruntergeladen werden kann. Ein Binärprogramm ist eine Datei, die das Programm in einer Form enthält, die direkt von der SparkFun Edge-Hardware ausgeführt werden kann.

Die folgende Anleitung wurde für Linux oder macOS geschrieben.

TensorFlow-Repository herunterladen

Der Code ist im TensorFlow-Repository auf GitHub unter folgendem Pfad verfügbar:

https://github.com/tensorflow/tensorflow/tree/master/tensorflow/lite/micro

Öffnen Sie ein Terminal auf Ihrem Computer, wechseln Sie in ein Verzeichnis, in dem Sie normalerweise Codierungsprojekte speichern, laden Sie das TensorFlow-Repository herunter und wechseln Sie in das erstellte Verzeichnis, wie unten gezeigt:

cd ~  # change into your home (or any other) directory
git clone --depth 1 https://github.com/tensorflow/tensorflow.git
cd tensorflow

Python-Abhängigkeiten herunterladen

Wir verwenden Python 3, um die Binärdatei vorzubereiten und auf das Gerät zu flashen. Die Python-Skripts hängen von der Verfügbarkeit bestimmter Bibliotheken ab. Führen Sie den folgenden Befehl aus, um diese Abhängigkeiten zu installieren:

pip3 install pycrypto pyserial --user

4. Binärdatei erstellen und vorbereiten

Wir erstellen das Binärprogramm und führen Befehle aus, um es für das Herunterladen auf das Gerät vorzubereiten.

Binärdatei erstellen

Führen Sie den folgenden Befehl aus, um alle erforderlichen Abhängigkeiten herunterzuladen und das Binärprogramm zu erstellen:

make -f tensorflow/lite/micro/tools/make/Makefile TARGET=sparkfun_edge micro_speech_bin

Wenn der Build erfolgreich ist, sollte die letzte Zeile der Ausgabe so aussehen:

arm-none-eabi-objcopy tensorflow/lite/micro/tools/make/gen/sparkfun_edge_cortex-m4/bin/micro_speech tensorflow/lite/micro/tools/make/gen/sparkfun_edge_cortex-m4/bin/micro_speech.bin -O binary

Führen Sie den folgenden Befehl aus, um zu bestätigen, dass die Binärdatei erfolgreich erstellt wurde:

test -f \
tensorflow/lite/micro/tools/make/gen/sparkfun_edge_cortex-m4/bin/micro_speech.bin && \
 echo "Binary was successfully created" || echo "Binary is missing"

Auf der Konsole sollte Binary was successfully created angezeigt werden. Wenn Sie Binary is missing sehen, ist ein Problem beim Build-Prozess aufgetreten, das behoben werden muss.

Binärdatei vorbereiten

Das Binärprogramm muss mit kryptografischen Schlüsseln signiert werden, damit es auf dem Gerät bereitgestellt werden kann. Wir führen jetzt einige Befehle aus, mit denen unser Binärprogramm signiert wird, damit es auf den SparkFun Edge heruntergeladen werden kann.

Geben Sie den folgenden Befehl ein, um einige Dummy-Verschlüsselungsschlüssel einzurichten, die wir für die Entwicklung verwenden können:

cp tensorflow/lite/micro/tools/make/downloads/AmbiqSuite-Rel2.2.0/tools/apollo3_scripts/keys_info0.py tensorflow/lite/micro/tools/make/downloads/AmbiqSuite-Rel2.2.0/tools/apollo3_scripts/keys_info.py

Führen Sie nun den folgenden Befehl aus, um ein signiertes Binärprogramm zu erstellen:

python3 tensorflow/lite/micro/tools/make/downloads/AmbiqSuite-Rel2.2.0/tools/apollo3_scripts/create_cust_image_blob.py \
--bin tensorflow/lite/micro/tools/make/gen/sparkfun_edge_cortex-m4/bin/micro_speech.bin \
--load-address 0xC000 \
--magic-num 0xCB \
-o main_nonsecure_ota \
--version 0x0

Dadurch wird die Datei main_nonsecure_ota.bin erstellt. Wir führen jetzt einen weiteren Befehl aus, um eine endgültige Version der Datei zu erstellen, mit der wir unser Gerät mit dem Bootloader-Skript flashen können, das wir im nächsten Schritt verwenden:

python3 tensorflow/lite/micro/tools/make/downloads/AmbiqSuite-Rel2.2.0/tools/apollo3_scripts/create_cust_wireupdate_blob.py \
--load-address 0x20000 \
--bin main_nonsecure_ota.bin \
-i 6 \
-o main_nonsecure_wire \
--options 0x1

Jetzt sollte sich eine Datei namens main_nonsecure_wire.bin in dem Verzeichnis befinden, in dem Sie die Befehle ausgeführt haben. Das ist die Datei, die wir auf das Gerät flashen.

5. Vorbereitung zum Flashen der Binärdatei

Was ist Flashing?

Das SparkFun Edge speichert das Programm, das es gerade ausführt, in seinem 512 Kilobyte großen Flash-Speicher. Wenn wir möchten, dass das Board ein neues Programm ausführt, müssen wir es an das Board senden. Es wird dann im Flash-Speicher gespeichert und überschreibt alle zuvor gespeicherten Programme.

Dieser Vorgang wird als „Flashen“ bezeichnet. Wir verwenden ihn, um unser Programm an das Board zu senden.

Programmiergerät an das Board anschließen

Um neue Programme auf die Platine herunterzuladen, verwenden wir den seriellen Programmierer SparkFun USB‑C Serial Basic. Dieses Gerät ermöglicht die Kommunikation zwischen Ihrem Computer und dem Mikrocontroller über USB.

So befestigen Sie das Gerät an Ihrem Board:

  1. Suchen Sie den 6-poligen Header an der Seite des SparkFun Edge.
  2. Stecke den SparkFun USB‑C Serial Basic in diese Pins und achte darauf, dass die Pins mit der Aufschrift „BLK“ und „GRN“ auf beiden Geräten richtig ausgerichtet sind.

b140822f0019f92a.png

Programmiergerät an den Computer anschließen

Wir verbinden das Board über USB mit Ihrem Computer. Damit wir das Board programmieren können, müssen wir wissen, welchen Namen Ihr Computer dem Gerät gibt. Am besten listen Sie alle Geräte des Computers vor und nach dem Anschließen auf und sehen nach, welches Gerät neu ist.

Bevor Sie das Gerät über USB anschließen, führen Sie den folgenden Befehl aus:

If you are using Linux: ls /dev/tty*
If you are using MacOS: ls /dev/cu*

Daraufhin sollte eine Liste der angeschlossenen Geräte ausgegeben werden, die in etwa so aussieht:

/dev/cu.Bluetooth-Incoming-Port
/dev/cu.MALS
/dev/cu.SOC

Schließen Sie den Programmer jetzt an den USB-Anschluss Ihres Computers an. Geben Sie den folgenden Befehl noch einmal ein:

If you are using Linux: ls /dev/tty*
If you are using MacOS: ls /dev/cu*

In der Ausgabe sollte ein zusätzliches Element wie im folgenden Beispiel angezeigt werden. Ihr neuer Artikel hat möglicherweise einen anderen Namen. Dieser neue Eintrag ist der Name des Geräts.

/dev/cu.Bluetooth-Incoming-Port
/dev/cu.MALS
/dev/cu.SOC
/dev/cu.wchusbserial-1450

Zuerst erstellen wir eine Umgebungsvariable, um den Gerätenamen zu identifizieren:

export DEVICENAME=put your device name here

Als Nächstes erstellen wir eine Umgebungsvariable, um die Baudrate anzugeben. Das ist die Geschwindigkeit, mit der Daten an das Gerät gesendet werden:

export BAUD_RATE=921600

6. Binärdatei flashen

Skript zum Flashen des Boards ausführen

Um das Board zu flashen, müssen wir es in einen speziellen „Bootloader“-Zustand versetzen, der es auf den Empfang der neuen Binärdatei vorbereitet. Anschließend führen wir ein Skript aus, um die Binärdatei an das Board zu senden.

Sehen wir uns die folgenden Schaltflächen auf dem Board an:

64c620570b9d2f83.png

Führen Sie die folgenden Schritte aus, um das Board zurückzusetzen und zu flashen:

  1. Achten Sie darauf, dass das Board mit dem Programmiergerät und das gesamte Setup über USB mit Ihrem Computer verbunden ist.
  2. Starten Sie, indem Sie die mit 14 gekennzeichnete Taste auf dem Board gedrückt halten. Halten Sie die Taste gedrückt, bis Sie Schritt 6 erreichen.
  3. Halten Sie die mit 14 gekennzeichnete Taste weiterhin gedrückt und klicken Sie auf die mit RST gekennzeichnete Taste, um das Board in den Bootloader-Status zurückzusetzen.
  4. Halten Sie die mit 14 gekennzeichnete Taste weiterhin gedrückt, fügen Sie den folgenden Befehl in das Terminal ein und drücken Sie die Eingabetaste, um ihn auszuführen. Sie können diesen Befehl auch schon vor dem Gedrückthalten der Taste in das Terminal einfügen, drücken Sie die Eingabetaste aber erst, wenn Sie diesen Schritt erreicht haben.
python3 tensorflow/lite/micro/tools/make/downloads/AmbiqSuite-Rel2.2.0/tools/apollo3_scripts/uart_wired_update.py -b ${BAUD_RATE} ${DEVICENAME} -r 1 -f main_nonsecure_wire.bin -i 6
  1. Halten Sie die mit 14 gekennzeichnete Taste weiterhin gedrückt. Auf dem Bildschirm sollte nun Folgendes angezeigt werden:
Connecting with Corvette over serial port /dev/cu.usbserial-1440...
Sending Hello.
Received response for Hello
Received Status
length =  0x58
version =  0x3
Max Storage =  0x4ffa0
Status =  0x2
State =  0x7
AMInfo =
0x1
0xff2da3ff
0x55fff
0x1
0x49f40003
0xffffffff
[...lots more 0xffffffff...]
Sending OTA Descriptor =  0xfe000
Sending Update Command.
number of updates needed =  1
Sending block of size  0x158b0  from  0x0  to  0x158b0
Sending Data Packet of length  8180
Sending Data Packet of length  8180
[...lots more Sending Data Packet of length  8180...]
  1. Lassen Sie die Taste mit der Markierung 14 auf der Platine los, nachdem Sie Sending Data Packet of length 8180 gesehen haben (es ist aber in Ordnung, wenn Sie sie weiter gedrückt halten). Das Programm gibt weiterhin Zeilen im Terminal aus. Das Ergebnis sollte in etwa so aussehen:
[...lots more Sending Data Packet of length  8180...]
Sending Data Packet of length  8180
Sending Data Packet of length  6440
Sending Reset Command.
Done.

Wenn Sie Done sehen, bedeutet das, dass das Blinken erfolgreich war. Wenn die Programmausgabe mit einem Fehler endet, prüfen Sie, ob Sending Reset Command ausgegeben wurde. Wenn ja, war das Flashen trotz des Fehlers wahrscheinlich erfolgreich.

Auf einem Linux-Computer kann es zu einem NoResponse Error kommen. Das liegt daran, dass der serielle Treiber ch34x zusammen mit dem vorhandenen seriellen Treiber installiert wurde. Das Problem kann so behoben werden:

Schritt 1: Installieren Sie die richtige Version der ch34x-Bibliothek neu. Achten Sie darauf, dass das Gerät während der Installation vom Computer getrennt ist.

git clone https://github.com/juliagoda/CH341SER.git
cd CH341SER/
make
sudo insmod ch34x.ko
sudo rmmod ch341

Schritt 2: Schließen Sie das USB-Kabel des Boards an und führen Sie Folgendes aus:

dmesg | grep "ch34x"

Eine Meldung wie diese sollte angezeigt werden:

[ 1299.444724]  ch34x_attach+0x1af/0x280 [ch34x]
[ 1299.445386] usb 2-13.1: ch34x converter now attached to ttyUSB0

Wenn der verwendete Treiber nicht „ch34x“ ist (z. B. ch341), versuchen Sie, den anderen Treiber zu deaktivieren, indem Sie Folgendes ausführen:

rmmod <non-ch34x driver name>

Trennen Sie das Gerät und schließen Sie es wieder an. Achten Sie darauf, dass der verwendete Treiber „ch34x“ ist.

7. Demo

Programm ausprobieren

Sobald das Board geflasht wurde, drücken Sie die Schaltfläche mit der Markierung

RST, um das Board neu zu starten und das Programm zu starten. Wenn die blaue LED blinkt, war das Flashen erfolgreich. Wenn nicht, scrolle nach unten zum Abschnitt Was ist, wenn es nicht funktioniert hat?.

bf256d403a1821af.gif

Das ML-Modell auf dem Board ist darauf trainiert, die Wörter „Ja“ und „Nein“ zu erkennen und das Vorhandensein und Fehlen von Sprache zu erkennen. Die Ergebnisse werden durch farbige LEDs angezeigt. In der folgenden Tabelle wird die Bedeutung der einzelnen LED-Farben beschrieben:

Erkennungsergebnis

LED-Farbe

"Ja"

Gelb

"Nein"

Rot

Unbekannte Sprache

Grün

Kein gesprochener Text erkannt

Keine LEDs leuchten

Probieren Sie es aus!

Halten Sie das Board vor Ihren Mund und sagen Sie mehrmals „Ja“. Die gelbe LED blinkt. Wenn nichts passiert, wenn Sie „Ja“ sagen, können Sie Folgendes versuchen:

  • Halte das Board etwa 25 cm von deinem Mund entfernt.
  • Übermäßige Hintergrundgeräusche vermeiden
  • Wiederholen Sie „Ja“ mehrmals kurz hintereinander (sagen Sie z. B. „Ja, ja, ja“).

Was kann ich tun, wenn es nicht funktioniert hat?

Hier sind einige mögliche Probleme und wie Sie sie beheben können:

Problem: Nach dem Flashen leuchtet keine der LEDs.

Lösung:Drücken Sie die Taste RST oder trennen Sie die Verbindung zwischen dem Board und dem Programmiergerät und stellen Sie sie dann wieder her. Wenn keiner dieser Schritte funktioniert, flashe das Board noch einmal.

Problem: Die blaue LED leuchtet, aber sehr schwach.

Lösung:Tauschen Sie die Batterie aus, da der Ladestand niedrig ist. Alternativ kann das Board auch über den Computer mit dem Programmiergerät und dem Kabel mit Strom versorgt werden.

8. Debugging-Ausgabe lesen (optional)

Sehen Sie sich diesen Abschnitt an, wenn Probleme auftreten und Sie Ihren Code im Detail debuggen müssen. Um zu verstehen, was in einem Mikrocontroller passiert, wenn Ihr Code ausgeführt wird, können Sie über die serielle Verbindung des Boards Debugging-Informationen ausgeben. Sie verwenden Ihren Computer, um eine Verbindung zum Board herzustellen und die Daten anzuzeigen, die das Board sendet.

Serielle Verbindung öffnen

Standardmäßig werden in unserem SparkFun Edge-Beispielcode alle gesprochenen Befehle zusammen mit ihrer Konfidenz protokolliert. Führen Sie den folgenden Befehl aus, um die Ausgabe des Boards zu sehen:

screen ${DEVICENAME} 115200

Anfangs wird möglicherweise eine Ausgabe wie die folgende angezeigt. Das passiert aber nur, wenn das Board nach dem Verbinden zurückgesetzt wird. Andernfalls werden möglicherweise Debugging-Informationen angezeigt.

Apollo3 Burst Mode is Available

                               Apollo3 operating in Burst Mode (96MHz)

Versuchen Sie, einige Befehle mit „Ja“ oder „Nein“ zu geben. Das Board sollte für jeden Befehl Debugging-Informationen ausgeben:

 Heard yes (202) @65536ms

Im obigen Log bezieht sich yes auf den Befehl. Die Zahl 202 bezieht sich auf die Wahrscheinlichkeit, dass der Befehl gehört wurde (mit 200 als Mindestwert). 65536ms gibt an, wie viel Zeit seit dem letzten Zurücksetzen des Mikrocontrollers vergangen ist.

Wenn Sie die Debug-Ausgabe nicht mehr sehen möchten, drücken Sie Ctrl+A, gefolgt von der Taste K und dann der Taste Y.

Debug-Logs schreiben

Den Code, mit dem diese Informationen protokolliert werden, finden Sie in der Datei „command_responder.cc“, mit der Sie gerade gearbeitet haben:

tensorflow/lite/micro/examples/micro_speech/sparkfun_edge/command_responder.cc

Zum Protokollieren von Daten können Sie die Methode error_reporter->Report() aufrufen. Es werden die Standard-printf-Tokens für die String-Interpolation unterstützt, mit denen Sie wichtige Informationen in Ihre Logs aufnehmen können:

error_reporter->Report("Heard %s (%d) @%dms", found_command, score, current_time);

Diese Methode ist hilfreich, wenn Sie im nächsten Abschnitt eigene Änderungen am Code vornehmen.

9. Code erweitern (optional)

Nachdem Sie nun wissen, wie Sie Ihren SparkFun Edge bauen und flashen, können Sie mit dem Code experimentieren und ihn auf Ihrem Gerät bereitstellen, um die Ergebnisse zu sehen.

Code lesen

Ein guter Ausgangspunkt für das Lesen des Codes ist die folgende Datei: command_responder.cc.

tensorflow/lite/micro/examples/micro_speech/sparkfun_edge/command_responder.cc

Sie können die Datei auf GitHub ansehen.

Die Methode in dieser Datei, RespondToCommand, wird aufgerufen, wenn ein Sprachbefehl erkannt wird. Der vorhandene Code schaltet je nach Antwort („yes“, „no“ oder unbekannter Befehl) eine andere LED ein. Das folgende Snippet zeigt, wie das funktioniert:

if (found_command[0] == 'y') {
  am_hal_gpio_output_set(AM_BSP_GPIO_LED_YELLOW);
}
if (found_command[0] == 'n') {
  am_hal_gpio_output_set(AM_BSP_GPIO_LED_RED);
}
if (found_command[0] == 'u') {
  am_hal_gpio_output_set(AM_BSP_GPIO_LED_GREEN);
}

Das Argument found_command enthält den Namen des erkannten Befehls. Durch die Überprüfung des ersten Zeichens wird in dieser Gruppe von if-Anweisungen festgelegt, welche LED leuchten soll.

Die Methode „RespondToCommand“ wird mit mehreren Argumenten aufgerufen:

void RespondToCommand(tflite::ErrorReporter* error_reporter,
    int32_t current_time, const char* found_command,
    uint8_t score, bool is_new_command) {
  • Mit error_reporter werden Debugging-Informationen protokolliert (dazu später mehr).
  • current_time steht für den Zeitpunkt, zu dem der Befehl erkannt wurde.
  • found_command gibt an, welcher Befehl erkannt wurde.
  • score gibt an, wie sicher wir sind, dass wir einen Befehl erkannt haben.
  • is_new_command gibt an, ob der Befehl zum ersten Mal gehört wird.

score ist eine Ganzzahl zwischen 0 und 255, die die Wahrscheinlichkeit angibt, dass ein Befehl erkannt wurde. Im Beispielcode wird ein Befehl nur als gültig betrachtet, wenn der Wert größer als 200 ist. Unsere Tests haben ergeben, dass die meisten gültigen Befehle im Bereich von 200 bis 210 liegen.

Code ändern

Das SparkFun Edge-Board hat vier LEDs. Derzeit blinkt die blaue LED, um anzuzeigen, dass eine Erkennung stattfindet. Das können Sie in der Datei command_responder.cc sehen:

static int count = 0;

// Toggle the blue LED every time an inference is performed.
++count;
if (count & 1) {
  am_hal_gpio_output_set(AM_BSP_GPIO_LED_BLUE);
} else {
  am_hal_gpio_output_clear(AM_BSP_GPIO_LED_BLUE);
}

Da wir vier LEDs haben, wollen wir das Programm so ändern, dass sie als visuelle Anzeige für die score eines bestimmten Befehls verwendet werden. Bei einer niedrigen Punktzahl leuchtet nur eine LED, bei einer hohen Punktzahl mehrere.

Damit wir wissen, dass das Programm ausgeführt wird, lassen wir die rote LED anstelle der blauen LED kontinuierlich blinken. Die angrenzenden blauen, grünen und gelben LEDs zeigen die Stärke unseres letzten score an. Der Einfachheit halber leuchten wir die LEDs nur auf, wenn das Wort „Ja“ gesprochen wird. Wenn ein anderes Wort erkannt wird, leuchten die LEDs nicht mehr.

Ersetzen Sie dazu den gesamten Code in der Datei command_responder.cc durch das folgende Snippet:

#include "tensorflow/lite/micro/examples/micro_speech/command_responder.h"

#include "am_bsp.h"

// This implementation will light up the LEDs on the board in response to different commands.
void RespondToCommand(tflite::ErrorReporter* error_reporter,
                      int32_t current_time, const char* found_command,
                      uint8_t score, bool is_new_command) {
  static bool is_initialized = false;
  if (!is_initialized) {
    // Setup LEDs as outputs
    am_hal_gpio_pinconfig(AM_BSP_GPIO_LED_RED, g_AM_HAL_GPIO_OUTPUT_12);
    am_hal_gpio_pinconfig(AM_BSP_GPIO_LED_BLUE, g_AM_HAL_GPIO_OUTPUT_12);
    am_hal_gpio_pinconfig(AM_BSP_GPIO_LED_GREEN, g_AM_HAL_GPIO_OUTPUT_12);
    am_hal_gpio_pinconfig(AM_BSP_GPIO_LED_YELLOW, g_AM_HAL_GPIO_OUTPUT_12);
    // Ensure all pins are cleared
    am_hal_gpio_output_clear(AM_BSP_GPIO_LED_RED);
    am_hal_gpio_output_clear(AM_BSP_GPIO_LED_BLUE);
    am_hal_gpio_output_clear(AM_BSP_GPIO_LED_GREEN);
    am_hal_gpio_output_clear(AM_BSP_GPIO_LED_YELLOW);
    is_initialized = true;
  }
  static int count = 0;

   // Toggle the red LED every time an inference is performed.
   ++count;
   if (count & 1) {
     am_hal_gpio_output_set(AM_BSP_GPIO_LED_RED);
   } else {
     am_hal_gpio_output_clear(AM_BSP_GPIO_LED_RED);
   }

  if (is_new_command) {
    // Clear the last three LEDs
    am_hal_gpio_output_clear(AM_BSP_GPIO_LED_BLUE);
    am_hal_gpio_output_clear(AM_BSP_GPIO_LED_GREEN);
    am_hal_gpio_output_clear(AM_BSP_GPIO_LED_YELLOW);
    error_reporter->Report("Heard %s (%d) @%dms", found_command, score,
                           current_time);
    // Only indicate a 'yes'
    if (found_command[0] == 'y') {
      // Always light the blue LED
      am_hal_gpio_output_set(AM_BSP_GPIO_LED_BLUE);
      // Light the other LEDs depending on score
      if (score >= 205) {
        am_hal_gpio_output_set(AM_BSP_GPIO_LED_GREEN);
      }
      if(score >= 210) {
        am_hal_gpio_output_set(AM_BSP_GPIO_LED_YELLOW);
      }
    }
  }
}

Wenn ein neuer Befehl erkannt wird, ist is_new_command „true“. Wir löschen die blauen, grünen und gelben LEDs und lassen sie dann je nach den Werten von found_command und score wieder aufleuchten.

Neu erstellen und flashen

Nachdem Sie Codeänderungen vorgenommen haben, testen Sie sie, indem Sie alle Schritte unter Binärdatei erstellen und vorbereiten ausführen.

10. Nächste Schritte

Herzlichen Glückwunsch! Sie haben Ihren ersten Spracherkennungsalgorithmus auf einem Mikrocontroller erstellt.

Wir hoffen, dass Ihnen diese kurze Einführung in die Entwicklung mit TensorFlow Lite für Mikrocontroller gefallen hat. Die Idee des Deep Learning auf Mikrocontrollern ist neu und spannend. Wir empfehlen Ihnen, sie auszuprobieren.

Referenzdokumente

26699b18f2b199f.png

Viele Grüße und viel Spaß beim Bauen!