Als Anwendung eines neuronalen Netzes ist im Folgenden die Erkennung von handgeschriebenen Ziffern beschrieben. Das Programm ist in der Programmiersprache Python als jupyter-Notebook implementiert.
Eine Standardanwendung für ein neuronales Netz ist die Erkennung von handgeschriebenen Ziffern. Die Datei mnist_train.csv enthält die Daten von 60.000 gescannten handgeschriebenen Ziffern. Mit diesen Daten wird das neuronale Netz zunächst trainiert. Anschließend wird das neuronale Netz mit weiteren 10.000 handgeschriebenen Ziffern, die sich in der Datei mnist_test.csv befinden, getestet.
Jede der beiden CSV-Dateien enhält eine Tabelle. Jede Zeile der Tabelle besteht aus 785 Zahlenwerten, dabei gibt der erste Wert die Ziffer an, die dargestellt ist, und die restlichen 784 Zahlenwerte stellen Graustufen eines 28×28-Pixel-Bildes dar, das die handgeschriebene Ziffer zeigt. Als Beispiel ist in Bild 1 eine handgeschriebene Ziffer 6 zu sehen.
Bild 1: Handgeschriebene Ziffer 6 als 28×28-Pixel-Bild
Die Daten entstammen der öffentlich zugänglichen MNIST-Datensammlung (http://yann.lecun.com/exdb/mnist/).
Die Trainingsdaten, die sich in der CSV-Datei mnist_train.csv befinden, werden zunächst mit folgender Funktion eingelesen.
Das Array datalist besteht aus 60.000 Strings, die jeweils Zeilen von durch Kommas getrennten Werten darstellen. Mit einer Funktion prepareInput werden die Daten für die weitere Verwendung aufbereitet.
Jede der durch Kommas unterteilten Zeilen wird im ersten Schritt in ein Array umgewandelt. Die Array-Einträge sind aber noch Strings, daher werden diese als nächstes in Zahlen umgewandelt. Dann wird die erste Zahl abgetrennt, diese entspricht dem Wert der dargestellten Ziffer, und in der Variablen d gespeichert. Die restlichen Zahlen werden um 128 vermindert, sodass sie in den Bereich {-128., ..., +127} fallen. Das Ergebnis ist der spätere Eingabevektor x, auf den in der Eingabeschicht ja die Funktion σ angewandt wird. So wird erreicht, dass der Wertebereich von σ ausgeschöpft wird.
Der Zielvektor y wird folgendermaßen gebildet. Zunächst wird Vektor mit zehn gleichen Werten von 0.1 erzeugt. In diesem Vektor wird an Indexposition d der Wert in 0.9 geändert. Das neuronale Netz soll später so trainiert werden, dass bei Eingabe einer handgeschriebenen Ziffer d das Neuron an Indexposition d der Ausgabeschicht einen hohen Wert liefert und alle anderen Neuronen der Ausgabeschicht einen niedrigen Wert. Die Ausgabewerte des neuronalen Netzes liegen stets zwischen 0 und 1, da sie als Fiúnktionswerte der Funktion σ zustande kommen.
Eingabevektor und zugehöriger Zielvektor werden miteinander verkettet, und alle so aufbereiteten Zeilen werden zum Schluss zu einer zweidimensionalen Liste r zusammengefügt.
In entsprechender Weise werden auch die Testdaten aus der Datei mnist_test.csv eingelesen und aufbereitet.
Es folgt das fertige Programm. Es beginnt mit den Definitionen der Funktionen readInput und prepareInput. Dann kommt die Definition der Funktion sigma. Die Definitionen der eigentlichen Funktionen des neuronalen Netzes, nämlich propagate, backpropagate, train und test schließen sich an.
Im Hauptprogramm wird zunächst das neuronale Netz definiert, indem pro Schicht die Anzahl der Neuronen angegeben wird. Hier etwa wird ein neuronales Netz mit drei Schichten definiert, wobei die Eingabeschicht 28 · 28 = 784 Neuronen umfasst, die innere Schicht 100 Neuronen und die Ausgabeschicht 10 Neuronen. Alternativ, hier im Programmtext auskommentiert, wird ein neuronales Netz mit vier Schichten definiert.
Überraschenderweise hat die Initialisierung der Gewichtungsmatrizen erheblichen Einfluss auf die Erkennungsrate des neuronalen Netzes. Hier ist eine Initialisierung gewählt, die normalverteilte Zufallswerte enthält.
Für die im Verlauf der Berechnung erforderlichen Vektoren werden zunächst Platzhalter erzeugt, sodass später per Indizierung darauf zugegriffen werden kann (zum Beispiel muss e[0] vorhanden sein, wenn ihm ein Wert zugewiesen wird).
Es folgt dann das Programmstück zum Trainieren und Testen des neuronalen Netzes. Die 60.000 Trainingsdatensätze werden mehrfach in sogenannten Epochen in das Netz eingegeben, um es zu trainieren. Im Anschluss daran wird mit den 10.000 Testdatensätzen jeweils die erzielte Erkennungsrate bestimmt.
Der Programmtext steht in Form eines jupyter-Notebooks unter MultilayerNeuralNetwork-HandwrittenNumbers.ipynb zum Herunterladen zur Verfügung. Zusätzlich erforderlich sind die Dateien mnist_train.csv und mnist_test.csv.
Probieren Sie das Programm mit unterschiedlichen neuronalen Netzen mit unterschiedlicher Anzahl von Schichten und Anzahl von Neuronen in den inneren Schichten aus. Die Anzahl der Neuronen in der Eingabeschicht liegt fest, sie beträgt 28 · 28 = 784 entsprechend der Anzahl der Pixel der Eingabebilder. Die Anzahl der Neuronen der Ausgabeschicht liegt ebenfalls fest, sie beträgt 10 entsprechend der Anzahl der zu erkennenden unterschiedlichen Ziffern 0, ..., 9.
Das hier angegebene neuronale Netz erzielt nach der sechsten Trainingsepoche eine Erkennungsrate von über 97 %. Tatsächlich wäre eine Erkennungsrate von 100 % auch gar nicht unbedingt sinnvoll, da manche Ziffer so unsauber geschrieben ist, dass eine Zuordnung zu einem "richtigen" Wert rein willkürlich wäre.
Weiter mit: [up]