Neuronales Netz: Lernen
Es ist wiedermal ein bissl Zeit für Theorie.
Ich habs in Neuronale Netze: Hintergrund bereits kurz angerissen, aber da es jetzt zur konkreten Implementierung geht werd ich es doch nochmal detailierter angehen.
Also: wie lernt ein Neuronales Netz?
Etwas präziser gehts um den sogenannten Backpropagation Lernalgorithmus. Ich erspar euch die mathematischen Details und beschränk mich auf verständliches Kauderwelsch ;)
Der backprop-algo ist ein häufig verwendeter Algorithmus zum trainieren von feed-forward Netzen. Hierfür eine kurze Wiederholung der Funktionsweise eines feedforward Netzes:
Es besteht aus mehreren Schichten von Neuronen. Für eine Inputliste, wird für jedes Neuron der ersten Schicht der resultierende Output berechnet, aus diesen Outputs ergibt sich eine neue Inputliste, diese wird nun auf die 2. Schicht angewandt und so weiter bis zur letzten Schicht. Die Outputs der letzten Schicht sind dann die Outputs des Neuronalen Netzes. Es wird also der Input von vorne nach hinten "durch propagiert".
Wenn man das Netz jetzt trainieren will, nimmt man eine Inputliste wo man die gewünschte Output liste kennt und propagiert die Inputliste durch das Netz. Nun hat man den tatsächlichen Output und den gewünschten Output.
Die Differenz dieser beiden wird als Error bezeichnet. Auf der letzten Schicht kann man nun sehr einfach an der Behebung dieses Erros arbeiten: Da man sowohl die inputs dieser Schicht als auch die Aktivierungsfunktionen kennt, muss man lediglich die Gewichte so anpassen, das der Fehler "verschwindet".
Aber man hat ja mehrere Schichten und will nicht sofort auswendig lernen. Also bewegt man die Gewichte nur einen kleinen Schritt (die sogenannte Lernrate) in die entsprechende Richtung und "propagiert" den Fehler weiter zur vorigen Schicht. Man "propagiert" den Fehler also zurück zum Anfang, deswegen Back-Propagation.
Bei der Outputschicht ist die Bestimmung des Fehlers ja noch recht einfach. Bei den tieferen Schichten wirds dann schon schwieriger.
- Zunächst berechnet man wie beschrieben für die Outputneuronen, in welche Richtung sich der gesamte Input des Neurons, wie stark bewegen müsste damit der Output passt. Das ist für jedes Neuron auf dem Layer eine Zahl, wir nennen es Delta.
- Dann schiebt man die Gewichte für jedes Neuron einen kleinen Schritt in diese Richtung. Die größe dieses Schrittes hängt ab von der vorgegebenen Lernrate und dem Inputwert. Ist der Inputwert für dieses Gewicht negativ gewesen, muss man natürlich in die andere Richtung gehen, war der Wert klein, geht man einen kleinen Schritt, war er groß, einen großen Schritt.
- Für ein Neuron auf der nächsten Schicht, multipliziert man die Deltas der verbundenen Neuronen auf der nächsten Schicht, multipliziert sie mit den Gewichten und verwendet diesen Wert als "Error" für dieses Neuron. Mit diesem Error berechnet man das Delta für dieses Neuron und so weiter...
Im Inneren des Netzes kann man also nicht direkt den Fehler und damit die notwendige Änderungen bestimmen, sondern muss aufgrund der "durchgereichten" Fehler der späteren Schichten Rückschlüsse auf den Fehler dieser Schicht ziehen.
In der Praxis funktioniert das normal recht gut.
Die Lernrate
Im Backprop wird an sich der Outputfehler so durchgereicht als würde nur eine Schicht verändert werden. Es darf also auf keinen Fall jede Schicht einen vollen Schritt in diese Richtung gehen. Dadurch würde man übers Ziel hinausschießen und einen großen Schritt zu weit gehen. Bei der nächsten Iteration geht man dann einen noch größeren Schritt zurück etc.
Die Lernrate sollte also einerseits klein sein und zur Anzahl der Schichten passen. Je mehr Schichten desto geringer sollte die Lernrate sein. Ich hab in ersten Test gute Ergebnisse mit 1% Lernrate gemacht.
Man kann das ganze natürlich verbessern indem man die Lernrate variabel gestaltet je nach derzeitigem Error (bei großem Fehler, hohe Lernrate..) oder mit Momentum (die Gewichtsveränderung ist ein Mittelwert zwischen letzter Iteration und neuem Wert).
Initiale Gewichte
Es hilft bei der Lerngeschwindigkeit (und teils überhaupt beim Lernen), wenn die Gewichte zu Beginn nicht alle gleich sind, sondern Zufallswerte sind. Dadurch "merkt" das Netz leichter die Unterschiede bei den Inputs...
Zufällige Änderungen
Ich weiß jetzt nicht ob das irgendwo wissenschaftlich untersucht ist, aber ich werde beim Lernen auch noch leichte Zufällige "Verzerrungen" einbauen. Das hilft (hoffentlich) einerseits gegen zu schlimmes auswendig lernen, andererseits bekommt der Lernalgo eine nichtdeterministische Komponente was ihm die Möglichkeit gibt aus lokalen Mini auszubrechen und ggf. bessere Minima zu finden.
soda, ich hoff das war noch halbwegs verständlich ;)
0 Comments
Recommended Comments
There are no comments to display.