Mein erstes neurales Netzwerk in Python

Das Themengebiet „Künstliche Intelligenz“ (KI) war für mich ein total unbekanntes Gebiet, aber die Neugier lässt einen nicht ruhen. Und dann kam noch das Stichwort „Neuronales Netz“ hinzu…

Das Suchen im Internet erbrachte viel (für mich recht unverständliche) Theorie, aber auch einen Hinweis auf das Buch „Neuronale Netze selbst programmieren“ von Tariq Rashid. Das Buch baut sich um ein schönes und verständliches Beispiel auf. Handgeschriebene Ziffern sollen „trainiert“ und anschließend richtig erkannt werden. Die Ziffern liegen als S/W-Bilder im Format 28*28 Pixel mit Grauwerten vor. Und es gibt eine öffentlich zugängliche Datenbank mit 60.000 dieser Bilder zum Trainieren und 10.000 Bilder zum Testen.

Der Hinweis auf Python und auf den Raspberry gaben dann den Ausschlag: Das probiere ich aus!

Die Theorie war einfach: Neuronen sind kleine programmierbare Rechner, die ihre analogen Eingangssignale mit einfachen Regeln wie Eingangsgewichtung, Summierung, Ausgabe-Begrenzung (z.Bsp. mit der Sigmoid-Funktion) in ein analoges Ausgangssignal übertragen. Die Gewichtungsregeln werden in Matrizen gespeichert. Dann kann man die Neuronen recht bequem mit den Mitteln der Matrizenmultiplikation zum Arbeiten bringen.

Die Anzahl der analogen Eingangssignale ist meist vorgegeben, die Anzahl der Ausgangssignale ergibt sich meist aus der erhofften Antwort. Die optimale Anzahl der Neuronen in der verdeckten (hidden) Mittelschicht probiert man aus. Jedes Neuron der mittleren Schicht ist mit jedem Eingangssignal verbunden, die Gewichtung der Signale ist der Schlüssel zu einem guten Gesamtergebnis. Es gibt sicherlich ausgefeiltere Algorithmen zur Signalbearbeitung, aber der im Buch vorgestellte Algorithmus ist leicht umsetzbar und zeigt auch Wirkung.

Die Gewichtungs-Matrizen der „Mittelschicht“ und der Ausgabeschicht füllt man zu Beginn mit Zufallswerten, am besten Werte zwischen Null und Eins. Die Testdaten erzeugen dann über die Zwischenschicht Signale auf den Ausgängen, diese vergleicht man mit den bekannten Werten der Lerndaten und verändert je nach Fehler rückwirkend (Backpropagation) die Gewichtungsmatrix der Ausgabeschicht und die Gewichtungsmatrix der (unbekannten) Mittelschicht.

Das Python-Programm fand sich in GITHUB und konnte recht einfach in meinen Raspberry und dessen Python 3 übertragen werden. Der im Buch vorgeschlagene Algorithmus arbeitet. Das Programm liegt bei mir im Sourcecode (weniger als 200 Zeilen) auf dem Raspberry und auch auf dem Windows-PC und ich kann an einigen Stellschrauben drehen. Mehr wollte ich eigentlich nicht.

Interessant: Die eingesetzten Parameter sagen eigentlich nichts über das Problem aus und dennoch gibt es eine Erkennungsrate von über 97% bei Ausnutzung des vollen Datensatzes. Allerdings ist dann mein Raspberry fast 2 Stunden beschäftigt.

Dann habe ich das Beispiel umgeändert auf 3*3 kleine unterschiedlich graue Quadrate, in denen das Programm Muster erkennen soll. Der Algorithmus für das neuronale Netz aus dem Beispiel “Ziffernerkennung” wurde nicht abgeändert, nur an den vorhandenen Parametern wurde gedreht.

Jetzt kann ich auch den Input gezielt verändern. Natürlich verrate ich dem Lernalgorithmus nicht das von mir „berechnete“ Muster. Meine Kontrolle ist einfach: Steigt die Erkennungsrate deutlich über die zufällige Erkennungsrate (die ohne Lernen), so hat sich ein Lerneffekt eingestellt und das neuronale Lernen hat funktioniert. Eine ypische Frage: Wo ist das hellste Plättchen? Aber diese genaue Frage kennt ja das Programm nicht. Es hatte nur viele, viele Beispiele zum Trainieren.

 

Eine gute Darstellung dieser Techniken findet man unter „Künstliches neuronales Netz“ in Wikipedia. YouTube bietet Lernvideos zu den Stichworten „neural networks“ an.

Buch „Neuronale Netze selbst programmieren“ von Tariq Rashid, O’Reilly, 2017

Python-Code (mit Daten): https://github.com/makeyourownneuralnetwork/

Testdaten: https://www.kaggle.com