Im ersten Teil der Artikelserie haben wir uns mit der Abgrenzung zwischen klassischen, linearen Programmablauf in einem Mikrocontroller und den Vorzügen faltungsneuronaler Netze (CNN) beschäftigt. Wir wissen jetzt, was genau CNNs sind und aus welchen Bestandteilen und Funktionen sie zusammengesetzt werden können. Am Ende der Exkursion haben wir kurz das Cifar-Netzwerk diskutiert, mit dessen Hilfe es möglich ist, Objekte wie zum Beispiel Katzen, Häuser oder Fahrräder in Bildern zu klassifizieren oder einfache Stimmmustererkennungen durchzuführen.
Der Trainingsvorgang neuronaler Netzwerke
Das im ersten Teil des Artikels besprochene Cifar-Netzwerk besteht aus unterschiedlichen Lagen von Neuronen. Zur Verdeutlichung ist dieses Netzwerk nochmals in Abbildung 1 dargestellt. Die Bilddaten von 32 x 32 Bildpunkten werden dem Netzwerk präsentiert und durchlaufen die Netzwerkschichten. Im ersten Teil, dem Faltungsteil, des Netzwerks werden in einem CNN schrittweise die für die zu unterscheidenden Objekte einzigartigen Merkmale und Strukturen untersucht und detektiert. Hierzu kommen Filtermatrizen zum Einsatz. Nachdem ein neuronales Netzwerk wie das Cifar von einem Designer modelliert wurde, sind diese Filtermatrizen zunächst noch unbestimmt und das Netzwerk ist in diesem Stadium noch nicht in der Lage Muster und Objekte zu erkennen.
Damit das möglich wird, ist es notwendig alle Parameter beziehungsweise Elemente der Matrizen zu bestimmen, sodass die Genauigkeit, mit der Objekte erkannt werden, maximal beziehungsweise die Fehlerfunktion minimal wird. Dieser Vorgang wird als Training eines neuronalen Netzwerks bezeichnet. Für gängige Anwendungen, wie sie im ersten Teil beschrieben wurden, werden die Netzwerke während der Entwicklung und Erprobung einmalig trainiert. Anschließend sind sie einsatzfähig und die Parameter müssen nicht mehr geändert werden. Erst dann, wenn ein bereits bestehendes System völlig neue Objekte klassifizieren soll, wird ein erneutes Training notwendig.
Damit ein Netzwerk trainiert werden kann, bedarf es Trainingsdaten. Diese ähneln jenen Daten, die später analysiert werden sollen. In unserem Fall eines Cifar-10-Netzwerks sind das also Bilder der zehn Objektklassen Flugzeug, PKW, Vogel, Katze, Hirsch, Frosch, Pferd, Schiff und LKW. Allerdings – und das ist während der gesamten Entwicklung einer KI-Applikation der komplizierteste Teil – ist es notwendig diese Bilder vorher zu benamen. Der Trainingsprozess, auf den wir etwas später noch genauer eingehen werden – arbeitet sehr einfach beschrieben nach dem Prinzip der Fehlerrückführung: Dem Netzwerk werden viele Bilder hintereinander gezeigt und gleichzeitig ein Zielwert, in unserem Fall die zugehörige Objektklasse, übermittelt. Bei jedem Zeigen eines Bildes werden die Filtermatrizen derart optimiert, dass Soll- und Istwert der Objektklasse übereinstimmt. Wenn dieser Prozess abgeschlossen ist, dann erkennt das Netzwerk Objekte auch in Bildern, die es während des Trainings noch niemals gesehen hat.
Überanpassung
Bei der Modellierung von neuronalen Netzwerken stellt sich oft die Frage wie hoch die Komplexität sein soll – wie viele Neuronen-Layer verwendet oder wie groß die Filtermatrizen gestaltet werden sollten. In diesem Zusammenhang ist es wichtig, die Über- und Unteranpassung eines Netzwerks zu diskutieren. Überanpassung ist das Ergebnis eines übermäßig komplexen Modells mit zu vielen Parametern. Es ist möglich festzustellen, ob ein Vorhersagemodell die Trainingsdaten zu schlecht oder zu gut anpasst, indem wir den Fehler der Trainingsdaten und den der Testdaten miteinander vergleichen.
Ist der Fehler während des Trainings sehr gering und steigt über die Maßen an, wenn dem Netzwerk vorher noch niemals gezeigte Testdaten präsentiert wird, so ist dies ein starkes Indiz dafür, dass das Netzwerk die Trainingsdaten „auswendig“ gelernt hat, anstatt die Mustererkennung zu generalisieren. Dies geschieht hauptsächlich dann, wenn das Netzwerk einen zu umfangreichen Speicher für Parameter oder zu viele Faltungs-Layer aufweist. In diesem Fall ist das Netzwerk kleiner zu gestalten.
Fehlerfunktion und Trainingsalgorithmen
Das Lernen besteht aus zwei Schritten. Im ersten Schritt wird dem Netz ein Bild gezeigt, welches durch das Netz der Neuronen wandert und einen Ausgabevektor erzeugt. Der höchste Wert des Ausgangsvektors repräsentiert die erkannte Objektklasse, in unserem Fall zum Beispiel „Hund“, was im Trainingsfall noch nicht notwendigerweise korrekt sein muss. Dieser Schritt wird als Vorwärtskopplung bezeichnet.
Die am Ausgang entstandene Differenz zwischen Soll- und Istwert wird als Fehler und die zugehörige Funktion als Fehlerfunktion bezeichnet. In die Fehlerfunktion gehen alle Elemente und Parameter des Netzes ein. Zielsetzung des Lernvorgangs eines neuronalen Netzwerks ist es, diese Parameter so zu bestimmen, dass die Fehlerfunktion minimiert wird. Diese Minimierung wird dadurch erreicht, dass die am Ausgang entstandene Abweichung (Fehler = Sollwert minus Istwert) rückwärts durch alle Bestandteile des Netzes bis an den Anfang geführt wird. Dieser Teil des Lernvorgang wird als Fehlerrückführung bezeichnet.
Somit ergibt sich während des Trainingsvorgangs eine Schleife, die schrittweise die Parameter der Filtermatrizen bestimmt. Dieser Vorgang aus Vorwärtskopplung und Fehlerrückführung wird solange wiederholt, bis der Fehlerwert unter einen vorher festgelegten Wert sinkt.
Optimierungsalgorithmus, Gradient und Gradientenverfahren
In Abbildung 3 ist zur Veranschaulichung unseres Trainings eine Fehlerfunktion bestehend aus nur zwei Parametern x und y dargestellt. Die z-Achse entspricht dem Fehler. Die Funktion selbst spielt hier keine Rolle und dient lediglich der Veranschaulichung. Schaut man sich den 3D-Funktionsplot genauer an, so stellt man fest, dass die Funktion ein globales, zusätzlich aber noch ein lokales Minimum besitzt.
Es gibt eine Vielzahl an numerischen Optimierungsalgorithmen, die für die Bestimmung der Gewichte und Biasse eingesetzt werden können. Der einfachste unter allen ist das Gradientenverfahren, welches im Folgenden beschrieben wird.
Das Gradientenverfahren basiert auf der Idee mittels des Gradienten schrittweise einen Weg von einem beliebigen Startpunk der Fehlerfunktion aus ins globale Minimum zu suchen. Der Gradient als mathematischer Operator beschreibt den Verlauf von physikalischen Größen. Er liefert in jedem Punkt unserer Fehlerfunktion einen Vektor – auch Gradientenvektor genannt –, der in die Richtung der größten Änderung des Funktionswertes weist. Der Betrag des Vektors entspricht dabei dem Maß des Änderung. In der Funktion in Abbildung 3 würde der Gradientenvektor in einem Punkt irgendwo unten rechts (roter Pfeil) in Richtung des Minimums zeigen. Der Betrag wäre auf Grund der sehr flachen Ebene sehr klein. Anders sieht es nahe der „Bergspitze“ im hinteren Bereich aus. Hier zeigt der Vektor (grüner Pfeil) steil nach unten und ist hat einen sehr großen Betrag, da das Relief sehr steil ist.
Beim Gradientenverfahren wird nun iterativ – ausgehend von einem beliebigen Startpunkt – derjenige Pfad gesucht, der mit dem stärksten Gefälle ins Tal führt. Das bedeutet, dass der Optimierungsalgorithmus im Startpunkt den Gradient berechnet und einen kleinen Schritt in die Richtung des stärksten Gefälles wandert. In diesem Zwischenpunkt wird der Gradient erneut berechnet und der Weg ins Tal fortgesetzt. So entsteht ausgehend vom Startpunkt ein Pfad ins Tal. Hierbei ergibt sich das Problem, das der Startpunk vorher nicht festgelegt ist, sondern frei gewählt werden muss.
In unserer zweidimensionalen Landkarte wird der aufmerksame Leser den Startpunkt selbstverständlich irgendwo auf der linken Seite des Funktionsplots legen. Damit ist sichergestellt, dass das Ende des (zum Beispiel blauen) Pfades auch im globalem Minimum endet. Die anderen beiden Pfade (gelb und orange) sind entweder sehr viel länger oder enden in einem lokalem Minimum. Da der Optimierungsalgorithmus nicht nur zwei Parameter optimieren muss, sondern hunderttausende, wird schnell klar, dass die Wahl des Startpunktes nur durch Zufall korrekt sein wird. In der Praxis ist dieser Ansatz augenscheinlich wenig hilfreich, da je nach Wahl des Startpunktes der Pfad sehr lang werden kann, was eine lange Trainingszeit bedeutet, oder der Zielpunkt liegt nicht im globalem Minimum, was dazu führen wird, dass die Genauigkeit, mit der das Netzwerk später arbeitet, herabgesetzt ist.
Abgesehen vom Gradientenverfahren wurden deshalb in den letzten Jahren noch eine ganze Reihe anderer Optimierungsalgorithmen entwickelt, die die oben beschriebenen beiden Probleme zu umgehen versuchen: Stochastisches Gradientenverfahren, Momentum, Adagrad, RMSprop und Adam – nur um einige zu nennen. Welcher Algorithmus in der Praxis zum Einsatz kommt, legt der Entwickler eines Netzwerks fest, da jeder Algorithmus spezifische Vor- und Nachteile mit sich bringt.
Trainingsdaten
Wie oben besprochen, führen wir dem Netzwerk während des Trainings mit den richtigen Objektklassen markierte Bilder zu – also zum Beispiel Auto, LKW und so weiter.... . Für unser Beispiel verwenden wir einen bereits vorhandenen Datensatz. In der Realität werden sich AI-Anwender vermutlich eher nicht mit dem Erkennen von Katzen, Hunden und Autos beschäftigen. Wenn also eine komplett neue Applikation – also zum Beispiel das Erkennen ob während des Herstellungsprozesses von Schrauben diese eine ausreichende Qualität haben – entwickelt werden soll, dann muss das Netzwerk auch mit Trainingsdaten von guten beziehungsweise schlechten Schrauben angelernt werden.
Das Erstellen eines solchen Datensatzes kann extrem aufwendig und zeitraubend sein und ist im Entwicklungsprozess einer KI-Applikation nicht selten der kostspieligste Schritt. Ist ein solcher Datensatz zusammengestellt, wird der Datensatz in Trainings- und Testdaten geteilt. Die Trainingsdaten werden für das oben beschriebene Training verwendet. Die Testdaten kommen am Schluss der Entwicklung zum Einsatz, um die korrekte Funktion des trainierten Netzwerks zu überprüfen.
Das fertige Netzwerk
Im ersten Teil wurde ein neuronales Netzwerk beschrieben und das Design mit all seinen Funktionen genauer beleuchtet. Nachdem nun auch alle zur Funktion notwendigen Gewichte und Biase bestimmt worden sind, ist davon auszugehen, dass das Netzwerk korrekt arbeiten kann. Um das zu überprüfen werden wir uns schlussendlich im dritten und letzten Teil damit beschäftigen, wie wir unser geschaffenes neuronales Netz zur Erkennung einer Katze in Hardware umsetzen. Hierfür werden wir die von ADI entwickelte MAX78000-MCU mit Hardwarebeschleuniger für CNNs verwenden.
Teil 1 der Artikel-Serie: Was ist maschinelles Lernen
Teil 3 der Artikel-Serie: Neuronales Netzwerk in Hardware umsetzen