Hintergrund
Backpropagation ist eine gängige Methode zum Trainieren eines neuronalen Netzwerks. Es gibt keinen Mangel an Abhandlungen im Internet, die zu erklären versuchen, wie Backpropagation funktioniert, aber nur wenige, die ein Beispiel mit tatsächlichen Zahlen enthalten. Dieser Beitrag ist mein Versuch, die Funktionsweise anhand eines konkreten Beispiels zu erklären, mit dem die Leute ihre eigenen Berechnungen vergleichen können, um sicherzustellen, dass sie Backpropagation richtig verstehen.
Backpropagation in Python
Sie können mit einem Python-Skript herumspielen, das ich geschrieben habe und das den Backpropagation-Algorithmus in diesem Github Repo implementiert.
Visualisierung der Backpropagation
Für eine interaktive Visualisierung, die zeigt, wie ein neuronales Netzwerk lernt, schauen Sie sich meine Visualisierung des neuronalen Netzwerks an.
Zusätzliche Ressourcen
Wenn Sie dieses Tutorial nützlich finden und weiter über neuronale Netzwerke, maschinelles Lernen und Deep Learning lernen wollen, empfehle ich Ihnen das neue Buch von Adrian Rosebrock, Deep Learning for Computer Vision with Python. Ich habe das Buch wirklich genossen und werde bald eine vollständige Rezension veröffentlichen.
Übersicht
Für dieses Tutorial werden wir ein neuronales Netzwerk mit zwei Eingängen, zwei versteckten Neuronen und zwei Ausgangsneuronen verwenden. Zusätzlich werden die versteckten Neuronen und die Ausgangsneuronen einen Bias enthalten.
Hier ist die Grundstruktur:
Um ein paar Zahlen zum Arbeiten zu haben, sind hier die anfänglichen Gewichte, die Verzerrungen und die Trainingsinputs/-outputs:
Das Ziel der Backpropagation ist es, die Gewichte zu optimieren, damit das neuronale Netz lernen kann, wie es beliebige Eingaben korrekt auf Ausgaben abbildet.
Für den Rest dieses Tutorials werden wir mit einem einzigen Trainingsset arbeiten: Bei Eingaben von 0,05 und 0,10 soll das neuronale Netz 0,01 und 0,99 ausgeben.
Der Vorwärtsdurchlauf
Zu Beginn sehen wir uns an, was das neuronale Netz bei den obigen Gewichten und Verzerrungen und den Eingaben von 0,05 und 0,10 derzeit vorhersagt. Dazu werden wir diese Eingaben vorwärts durch das Netz leiten.
Wir ermitteln die gesamte Netzeingabe für jedes Neuron der versteckten Schicht, zerquetschen die gesamte Netzeingabe mithilfe einer Aktivierungsfunktion (hier verwenden wir die logistische Funktion) und wiederholen den Vorgang dann mit den Neuronen der Ausgabeschicht.
Hier sehen Sie, wie wir die Gesamtnetzeingabe für berechnen:
Wir zerlegen es dann mit der logistischen Funktion, um die Ausgabe von zu erhalten:
Wenn man den gleichen Prozess für durchführt, erhält man:
Wir wiederholen diesen Vorgang für die Neuronen der Ausgabeschicht und verwenden die Ausgaben der Neuronen der versteckten Schicht als Eingaben.
Hier ist die Ausgabe für :
Und wenn wir den gleichen Prozess für durchführen, erhalten wir:
Berechnen des Gesamtfehlers
Wir können nun den Fehler für jedes Ausgangsneuron mit Hilfe der quadratischen Fehlerfunktion berechnen und diese addieren, um den Gesamtfehler zu erhalten:
Zum Beispiel ist die Zielausgabe für 0.01, aber die Ausgabe des neuronalen Netzwerks 0,75136507, daher ist sein Fehler:
Wenn wir diesen Vorgang für wiederholen (und uns daran erinnern, dass das Ziel 0.99) erhalten wir:
Der Gesamtfehler für das neuronale Netz ist die Summe dieser Fehler:
Der Rückwärtsdurchlauf
Unser Ziel bei der Backpropagation ist es, jedes der Gewichte im Netzwerk so zu aktualisieren, dass sie die tatsächliche Ausgabe näher an die Zielausgabe heranführen, wodurch der Fehler für jedes Ausgangsneuron und das Netzwerk als Ganzes minimiert wird.
Output Layer
Betrachten Sie . Wir wollen wissen, wie stark sich eine Änderung von auf den Gesamtfehler auswirkt, also .
Durch Anwendung der Kettenregel wissen wir, dass:
Visuell gesehen, machen wir Folgendes:
Wir müssen jeden Teil in dieser Gleichung herausfinden.
Erstens, wie stark ändert sich der Gesamtfehler in Bezug auf die Ausgabe?
Nächste Frage: Wie stark ändert sich der Ausgang von in Bezug auf seinen gesamten Nettoeingang?
Die partielle Ableitung der logistischen Funktion ist der Output multipliziert mit 1 minus dem Output:
Schließlich, wie stark ändert sich der gesamte Netto-Input von in Bezug auf ?
Alles zusammenfassen:
Sie werden diese Berechnung oft in Form der Delta-Regel kombiniert sehen:
Alternativ, haben wir und , was als geschrieben werden kann, auch bekannt als (der griechische Buchstabe delta), auch bekannt als das Knoten-Delta. Wir können dies verwenden, um die obige Berechnung umzuschreiben:
Daraus folgt:
Einige Quellen extrahieren das negative Vorzeichen aus , so dass es geschrieben werden würde als:
Um den Fehler zu verringern, subtrahieren wir dann diesen Wert von der aktuellen Gewichtung (optional multipliziert mit einer Lernrate, eta, die wir auf 0 setzen werden.5):
Wir können diesen Vorgang wiederholen, um die neuen Gewichte , und zu erhalten:
Wir führen die eigentlichen Aktualisierungen im neuronalen Netz durch, nachdem wir die neuen Gewichte haben, die in die Neuronen der versteckten Schicht führen (d. h., wir verwenden die ursprünglichen Gewichte, nicht die aktualisierten Gewichte, wenn wir unten mit dem Backpropagation-Algorithmus fortfahren).
Hintere Schicht
Als Nächstes setzen wir den Rückwärtsdurchlauf fort, indem wir neue Werte für berechnen, , und .
Im Großen und Ganzen müssen wir folgendes herausfinden:
Visuell:
Wir werden ein ähnliches Verfahren wie für die Ausgabeschicht verwenden, aber etwas anders, um der Tatsache Rechnung zu tragen, dass die Ausgabe jedes Neurons der versteckten Schicht zur Ausgabe (und damit zum Fehler) mehrerer Ausgangsneuronen beiträgt. Wir wissen, dass sowohl als auch beeinflusst. muss das seine Wirkung auf die beiden Ausgangsneuronen berücksichtigen:
Beginnend mit :
Wir können mit den Werten berechnen, die wir zuvor berechnet haben:
Und ist gleich :
Einstecken:
Wenn wir den gleichen Prozess für verfolgen, erhalten wir:
Daher:
Nun, da wir haben, müssen wir herausfinden und dann für jedes Gewicht:
Wir berechnen die partielle Ableitung des gesamten Netzeingangs für nach genauso wie für das Ausgangsneuron:
Zusammengefasst:
Sie könnten dies auch geschrieben sehen als:
Wir können nun aktualisieren:
Wiederhole dies für und
Zuletzt haben wir alle unsere Gewichte aktualisiert! Als wir ursprünglich die 0,05- und 0,1-Eingänge weiterleiteten, betrug der Fehler des Netzwerks 0,298371109. Nach dieser ersten Runde der Backpropagation ist der Gesamtfehler jetzt auf 0,291027924 gesunken. Das mag nicht viel erscheinen, aber nachdem dieser Prozess beispielsweise 10.000 Mal wiederholt wurde, sinkt der Fehler auf 0,0000351085. An diesem Punkt, wenn wir 0,05 und 0,1 vorwärts einspeisen, erzeugen die beiden Ausgänge Neuronen 0,015912196 (gegenüber dem 0,01-Ziel) und 0,984065734 (gegenüber dem 0,99-Ziel).
Wenn Sie es bis hierher geschafft haben und irgendwelche Fehler in den obigen Ausführungen gefunden haben oder Ihnen eine Möglichkeit einfällt, es für zukünftige Leser klarer zu machen, zögern Sie nicht, mir eine Nachricht zu schicken. Danke!