Projekt: Künstliches neuronales Netz beim Lernen zuschauen

Projekt: Künstliches neuronales Netz beim Lernen zuschauen

Die ursprüngliche Zielsetzung war, ein ganz einfaches künstliches neuronales Netz auf einem Raspberry Pi Pico mit MicroPython zu trainieren und anzuwenden. Es ging dabei weniger um eine ersthafte Anwendung, sondern eher um eine Demonstration, um einen Eindruck zu bekommen, wie ein neuronales Netz funktioniert.
Das besondere dabei sollte sein, dem künstlichen neuronalen Netz beim Lernen zuzuschauen. Das heißt, es dabei zu beobachten, wie es mit der Zeit immer besser wird.

Für Demonstrationszwecke soll ein Gerät gebaut werden, das an einen HDMI-Bildschirm, Fernseher oder Beamer angeschlossen werden kann. Damit soll in einer Vorlesung „Grundlagen der IT“ die Funktionsweise eines künstlichen neuronalen Netzes zum Thema „Künstliche Intelligenz“ anschaulich gezeigt werden können.
Normalerweise würde man das Training auf einem Notebook laufen lassen. Aber, es sollte ein eigenständiges Gerät sein, um es als „leichtes Gepäck“ mitnehmen zu können. Und beispielsweise auf Veranstaltungen, Messen, Vorträgen sofort zur Demonstration einsetzen zu können ohne einen großen Computer bedienen zu müssen.

Was wird trainiert?

A B Q
0 0 0
0 1 1
1 0 1
1 1 0

Es geht in diesem Beispiel darum, dass ein minimales künstliches neuronales Netz lernt, wie die logische Funktion XOR funktioniert. Das XOR ist im Prinzip die Funktion des binären Vergleichens. Klar ist, dass in jedem Prozessor die XOR-Funktion enthalten ist. Dafür braucht man eigentlich keine künstliche Intelligenz. Hier geht es jedoch darum, herauszufinden, wie groß der Aufwand ist, um einer künstlichen Intelligenz das XOR beizubringen. Und gleichzeitig brauchen wir ein KI-Modell, dem wir beim Lernen zusehen können.

Wenn man ein KI-Modell trainieren will, dann braucht man neben dem Modell auch Trainingsdaten. Für ein XOR gibt es insgesamt 4 Trainingsdatensätze, die aus je zwei binären Eingangswerten und einem binären Ausgangswert bestehen. Der Vorteil dabei ist, dass die Trainingsdatensätze auf 4 begrenzt sind. Das heißt, das Lernen erfolgt relativ schnell. Ein weiterer Vorteil ist, dass die Trainingsdatensätze gleich auch als Testdatensätze verwendet werden können. Da die zu erwartenden Ausgangswerte bekannt sind, lässt sich maschinell prüfen, ob das Modell funktioniert. Es bedarf keinerlei Eingriffe durch einen Bediener. Es handelt sich dabei um eine Art des unüberwachten Lernens.

Anleitung zum Aufbau

In der folgenden Anleitung werden die verwendeten Bauteile beschrieben. Es wird erklärt, wie CircuitPython als Bare-Metal-Version auf dem Raspberry Pi zu installiert ist. Ein weiterer Schritt umfasst den Programmcode zur Einstellung der Display-Auflösung und der Programmcode für das künstliche neuronale Netz und das Training.
Abschließend wird die Datenausgabe auf dem Bildschirm erläutert. Dabei wird beschrieben, wie die Ergebnisse des neuronalen Netzes aufbereitet und visuell ausgegeben werden, sodass sie für den Betrachter verständlicher sind.

  • Aufbau und Bauteile
  • Bare Metal CircuitPython auf dem Raspberry Pi installieren
  • Programmcode: Display-Auflösung einstellen
  • Bibliotheken für die Textausgabe
  • Programmcode: Das künstliche neuronale Netz
  • Erläuterungen zur Datenausgabe

Aufbau und Bauteile

Raspberry Pi mit Reset-Taster

Raspberry Pi Zero: Der Programmcode für das künstliche neuronale Netz wurde ursprüngliche für einen Raspberry Pi Pico (Mikrocontroller-Board) geschrieben. In diesem Projekt wurde jedoch der Raspberry Pi Zero gewählt, der als Einplatinen-Computer über eine HDMI-Schnittstelle verfügt, die zwingend notwendig ist, um das Gerät an einem Bildschirm, Fernseher oder Beamer anschließen zu können.

Bare Metal CircuitPython: Anstatt ein herkömmliches Betriebssystem auf dem Raspberry Pi Zero laufen zu lassen, viel die Wahl auf die Bare-Metal-Version von CircuitPython. Dabei ging es hauptsächlich darum, die Vorteile der direkten Unterstützung eines HDMI-Bildschirms zu nutzen. Außerdem sollte der vorhandene Programmcode, der in MicroPython geschrieben war, ohne Änderung verwendet werden können. Da auf Mikrocontroller-spezifische Funktionen verzichtet wurde, ist die einzige Änderung am Programmcode die Funktionen für die Darstellung auf dem HDMI-Bildschirm. Die Programmierung erfolgt mit der Thonny Python IDE und funktioniert vom Ablauf her wie bei einem herkömmlichen Mikrocontroller-Board.

Speicherkarte: Auf der Speicherkarte wird das Image für Bare Metal CircuitPython geschrieben. Im Prinzip ist die Speicherkapazität egal. Die Bare-Metal-Version ist nur wenige Megabyte groß. Der Programmcode und die Bibliotheken nur wenige Kilobyte.

HDMI-Adapter: Weil der Raspberry Pi Zero nur einen Mini-HDMI-Anschluss hat, bedarf es eines Adapters auf den normalen HDMI-Anschluss.

Stromversorgung: Die Stromversorgung erfolgt mit einem herkömmlichen USB-Netzteil. Da der Raspberry Pi Zero nur wenig Strom verbraucht, ist dafür fast jedes USB-Netzteil geeignet.

Taster: Es ist ein Taster vorgesehen, der mit den Reset-Pins auf dem Raspberry Pi Zero verbunden ist. Mit dem Taster kann man einen Neustart auslösen, um das Training erneut zu beginnen. Mehr Steuerungsmöglichkeiten sind nicht vorgesehen. Bedarfsweise kann man einen beleuchteten Taster verwenden oder eine separate LED, mit der man einen Betriebszustand anzeigen kann.

Gehäuse (optional): Um den Raspberry Pi mit dem Taster betriebssicher unterzubringen, ist ein schwarzes ABS-Gehäuse mit den Außenmaßen 10x10x10 cm vorgesehen. Während sich der Raspberry Pi innen befindet, ist der Taster auf der Oberseite befestigt und seine Kontakte nach innen geführt. Der Taster ist beleuchtet. Außerdem muss der HDMI-Anschluss und ein USB-Anschluss herausgeführt werden.

Bare Metal CircuitPython auf dem Raspberry Pi installieren

Die Installation von CircuitPython auf dem Raspberry Pi Zero funktioniert wie bei jedem anderen Betriebssystem auch. Zuerst muss man ein Image herunterladen und das auf eine Speicherkarte schreiben. Anschließend nimmt den Raspberry Pi Zero in Betrieb, in dem man ihn über USB mit einem Host-Computer verbindet.

Programmcode: Display-Auflösung einstellen

Um einen HDMI-Bildschirm nutzen zu können muss man den CircuitPython-Framebuffer mit einer passenden Auflösung initialisiert. Dieser Programmcode sollte in der Datei boot.py gespeichert werden, der immer beim Booten ausgeführt wird.

Kopiere die folgenden Zeilen in die Datei boot.py.

import displayio
import framebufferio
import videocore
displayio.release_displays()
fb = videocore.Framebuffer(1920 // 2, 1080 // 2)
display = framebufferio.FramebufferDisplay(fb)

Diese Zeilen erzeugen bei einem Neustart (von der Stromversorgung trennen und wieder verbinden) einen Framebuffer mit einer Auflösung von 960 x 540 Pixeln. Einw größere Auflösung würde zu einer verzögerten Darstellung auf dem HDMI-Bildschirm führen.

Bibliotheken für die Textausgabe

Damit eine einfache Text-Darstellung auf dem Display funktioniert braucht man das Modul „adafruit_display_text“ aus dem „Adafruit CircuitPython Bundle“.

Programmcode: Das künstliche neuronale Netz

Lade folgende Datei herunter und kopiere sie in das Laufwerk „CIRCUITPY“:

Download

Wenn man für den Programmcode den Dateinamen „code.py“ wählt, dann wird die Datei beim Start des Raspberry Pi Zero automatisch ausgeführt.

Grundlagen zur Funktionsweise von künstlichen neuronalen Netzen

Die Implementierung eines künstlichen neuronalen Netzes im Programmcode berücksichtigt Feedforward, Backpropagation und Training über viele Epochen. Wenn du diese KI-spezifischen Fachbegriffe noch nicht kennst, dann empfiehlt es sich, dass du dich vorab ein wenig informierst. In der folgenden Erläuterung zur Datenausgabe wird nicht jeder Fachbegriff erläutert.

Erläuterungen zur Datenausgabe

Projekt: Künstliches neuronales Netz beim Lernen zuschauen

Wenn man den Raspberry Pi Zero mit dem Netzteil verbindet, dann startet sofort das KI-Training. Vorher muss der HDMI-Bildschirm verbunden werden, damit die CircuitPython-Firmware den Bildschirm erkennt und die Bildausgabe startet. Ein Hot-Plugging ist nicht vorgesehen.

Ziel der Darstellung

Die Bildausgabe ist so gestaltet, dass man dem künstlichen neuronalen Netz beim Lernen zusehen kann. Dabei ist das KI-Modell bewusst klein gehalten und die Trainingsdaten stark reduziert, damit das Training schon nach wenigen Sekunden beendet ist.

Um den Lernprozess nachvollziehbar zu machen, wird nach jeder 100. Epoche das Training für 1,5 Sekunden pausiert. Die Verzögerung ist deshalb notwendig, damit man die Veränderungen in der Darstellung leichter beobachten kann.

Aufbau des KI-Modells und Lerngegenstand

Das neuronale Netz besteht aus:

2 Eingabeneuronen
1 Ausgabeneuron
1 Hidden-Layer mit 2 Neuronen

Mit diesem minimalistischen Modell soll ein künstliches neuronales Netz die Funktionsweise der logischen XOR-Funktion lernen.

Trainingsdauer und Abbruchkriterien

Zu Demonstrationszwecken wird das Training spätestens nach 4200 Epochen beendet. Die maximale Trainingsdauer beträgt etwa 30 Sekunden.

Ein Training wird vorzeitig beendet, wenn der Gesamtfehler so gering ist, dass ein weiteres Training keine Verbesserung der Funktion bringen würde.

Falls das Modell bis zur maximalen Epochenzahl kein XOR-Verhalten zeigt, wird das Training ebenfalls beendet, da eine zeitnahe Verbesserung unwahrscheinlich ist.

Zufällige Startwerte und ihre Auswirkungen

Jedes Training verläuft unterschiedlich, da die Startwerte der Gewichte für die Eingaben und Ausgaben der Neuronen im Hidden-Layer zufällig gewählt werden.
Dadurch sind die Trainingsläufe nicht direkt vergleichbar, weil Verlauf und Endergebnis jedes Mal unterschiedlich sind. Dabei kann man aber untersuchen, welchen Einfluss optimale und suboptimale Startwerte haben können.

  • Optimale Startwerte ermöglichen ein schnelles Lernen und erfolgreiches Training.
  • Suboptimale Startwerte haben ein langsames Lernen zur Folge und führen zum Abbruch bei der hier maximalen Epochenzahl von 4200.

Ablauf einer Epoche

  • Eine Epoche umfasst einen vollständigen Durchlauf aller Trainingsdaten mit 4 Datensätzen.
  • Nach jeder Epoche erfolgt die Backpropagation. Dabei wird der Fehler des Modells berechnet und anschließend die Gewichte angepasst.

Die Backpropagation stellt den eigentlichen Lernprozess dar.
In der Visualisierung ist sichtbar, wie sich die Gewichte für die Eingaben und Ausgaben der Neuronen im Hidden-Layer verändern.

Beobachtung des Lernprozesses

Es gibt 3 Bereiche, die man beobachten kann. Dabei sollte man nicht versuchen alle 3 Bereiche gleichzeitig im Auge zu behalten, sondern separat voneinander und zum Vergleichen mehrere Trainingsläufe hintereinander beobachten.

(1) Entwicklung des Gesamtfehlers über die Epochen: Bei der Entwicklung des Gesamtfehlers kann man beobachten, dass der Fehler im Verlauf des Trainings sinkt. Ein kurzfristiger Anstieg zu Beginn ist normal. Aber, ein zu langsamer Fehlerabfall deutet auf ungünstige Startwerte hin.

(2) Die Veränderung der Gewichte: Die Backpropagation stellt den eigentlichen Lernprozess dar. Dabei werden die Gewichte für die Eingaben und Ausgaben der Neuronen im Hidden-Layer verändern.

(3) Test des Modells (XOR-Funktion): Beim Test des Modells werden alle XOR-Eingabekombinationen geprüft und das Rechenergebnis angezeigt. Erfolgreiches Lernen erkennt man daran, dass die Ausgaben irgendwann den erwarteten XOR-Ergebnissen entsprechen.

Übersicht: Künstliche Intelligenz

Weitere Projekte:

Elektronik-Sets für das Hardware-nahe Programmieren

Elektronik-Fibel

Elektronik einfach und leicht verständlich

Die Elektronik-Fibel ist ein Buch über die Grundlagen der Elektronik, Bauelemente, Schaltungstechnik und Digitaltechnik.

Das will ich haben!

Programmieren mit dem Raspberry Pi Pico
Online-Meeting

Programmieren mit dem Raspberry Pi Pico

Besuchen Sie unser fast monatlich stattfindendes Online-Meeting PicoTalk und lernen Sie uns kennen. Die Teilnahme ist kostenfrei.

Termine und Newsletter-Anmeldung

Frag Elektronik-Kompendium.de