Stellen Sie sich vor, Sie sind Ingenieur und wurden gebeten, einen Computer von Grund auf neu zu entwickeln. Sobald Sie im BĂŒro sitzen, haben Sie Probleme, logische Schaltkreise zu entwerfen, die UND- ODER ODER-Ventile zu verteilen usw. - und plötzlich kommt Ihr Chef herein und teilt Ihnen die schlechten Nachrichten mit. Der Client hat gerade beschlossen, dem Projekt eine unerwartete Anforderung hinzuzufĂŒgen: Das Schema des gesamten Computers sollte nicht mehr als zwei Ebenen haben:

Sie sind erstaunt und sagen dem Chef: "Ja, der Kunde ist verrĂŒckt!"
Der Chef antwortet: âDas denke ich auch. Aber der Kunde muss bekommen, was er will. "
TatsĂ€chlich ist der Klient im engeren Sinne nicht völlig verrĂŒckt. Angenommen, Sie dĂŒrfen ein spezielles Logikgatter verwenden, mit dem Sie eine beliebige Anzahl von EingĂ€ngen ĂŒber UND verbinden können. Und Sie dĂŒrfen das NAND-Gatter mit einer beliebigen Anzahl von EingĂ€ngen verwenden, d. H. Einem Gatter, das viele Eingaben durch UND addiert und dann das Ergebnis umkehrt. Es stellt sich heraus, dass Sie mit solchen Spezialventilen jede Funktion mit nur einer zweischichtigen Schaltung berechnen können.
Nur weil etwas getan werden kann, heiĂt das noch lange nicht, dass es sich lohnt, es zu tun. In der Praxis beginnen wir bei der Lösung von Problemen im Zusammenhang mit dem Entwurf von Logikschaltungen (und fast allen algorithmischen Problemen) normalerweise mit der Lösung von Unteraufgaben und stellen dann schrittweise eine vollstĂ€ndige Lösung zusammen. Mit anderen Worten, wir bauen eine Lösung auf vielen Abstraktionsebenen auf.
Angenommen, wir entwerfen eine Logikschaltung zum Multiplizieren von zwei Zahlen. Es ist wahrscheinlich, dass wir es aus Teilschaltungen erstellen möchten, die Operationen wie das HinzufĂŒgen von zwei Zahlen implementieren. Additionsunterschaltungen bestehen wiederum aus Unterschaltungen, die zwei Bits hinzufĂŒgen. Grob gesagt wird unser Schema so aussehen:

Das heiĂt, die letzte Schaltung enthĂ€lt mindestens drei Schichten von Schaltungselementen. In der Tat wird es wahrscheinlich mehr als drei Ebenen haben, wenn wir die Unteraufgaben in kleinere als die von mir beschriebenen aufteilen. Aber du hast das Prinzip verstanden.
Daher erleichtern tiefe Schemata den Entwurfsprozess. Sie helfen aber nicht nur beim Design. Es gibt mathematische Beweise dafĂŒr, dass zur Berechnung einiger Funktionen in sehr flachen Schaltkreisen eine exponentiell gröĂere Anzahl von Elementen verwendet werden muss als in tiefen. Zum Beispiel gibt es eine
berĂŒhmte Reihe wissenschaftlicher Arbeiten der 1980er Jahre, in denen gezeigt wurde, dass die Berechnung der ParitĂ€t eines Satzes von Bits eine exponentiell gröĂere Anzahl von Gates mit einer flachen Schaltung erfordert. Wenn Sie jedoch tiefe Schemata verwenden, ist es einfacher, die ParitĂ€t mit einem kleinen Schema zu berechnen: Sie berechnen einfach die ParitĂ€t der Bitpaare und verwenden dann das Ergebnis, um die ParitĂ€t der Bitpaare usw. zu berechnen, um schnell die allgemeine ParitĂ€t zu erreichen. Daher können tiefe Schemata viel leistungsfĂ€higer sein als flache.
Bisher hat dieses Buch einen Ansatz fĂŒr neuronale Netze (NS) verwendet, Ă€hnlich den Anforderungen eines verrĂŒckten Kunden. Fast alle Netzwerke, mit denen wir gearbeitet haben, hatten eine einzige verborgene Schicht von Neuronen (plus die Eingabe- und Ausgabeschichten):

Diese einfachen Netzwerke haben sich als sehr nĂŒtzlich erwiesen: In frĂŒheren Kapiteln haben wir solche Netzwerke verwendet, um handgeschriebene Zahlen mit einer Genauigkeit von mehr als 98% zu klassifizieren! Es ist jedoch intuitiv klar, dass Netzwerke mit vielen verborgenen Schichten viel leistungsfĂ€higer sind:

Solche Netzwerke können Zwischenschichten verwenden, um viele Abstraktionsebenen zu erstellen, wie dies bei unseren Booleschen Schemata der Fall ist. Beispielsweise können bei der Mustererkennung Neuronen der ersten Schicht lernen, Gesichter zu erkennen, Neuronen der zweiten Schicht - komplexere Formen, beispielsweise Dreiecke oder Rechtecke, die aus Gesichtern erzeugt werden. Dann kann die dritte Schicht noch komplexere Formen erkennen. Usw. Es ist wahrscheinlich, dass diese vielen Abstraktionsebenen tiefen Netzwerken einen ĂŒberzeugenden Vorteil bei der Lösung von Problemen beim Erkennen komplexer Muster verschaffen. DarĂŒber hinaus gibt es, wie im Fall von Schaltungen, theoretische
Ergebnisse, die bestÀtigen, dass tiefe Netzwerke von Natur aus mehr FÀhigkeiten haben als flache.
Wie trainieren wir diese tiefen neuronalen Netze (GNSs)? In diesem Kapitel werden wir versuchen, STS mit unserem Arbeitstier unter den Trainingsalgorithmen zu trainieren - stochastischer Gradienten-RĂŒckwĂ€rtsausbreitungsabstieg. Wir werden jedoch auf ein Problem stoĂen - unser STS wird nicht viel besser funktionieren (wenn ĂŒberhaupt ĂŒbertroffen) als flache.
Dieser Fehler erscheint angesichts der obigen Diskussion seltsam. Aber anstatt das STS aufzugeben, werden wir uns eingehender mit dem Problem befassen und versuchen zu verstehen, warum das STS schwer zu trainieren ist. Wenn wir uns das Problem genauer ansehen, werden wir feststellen, dass verschiedene Ebenen im STS mit sehr unterschiedlichen Geschwindigkeiten lernen. Insbesondere wenn die letzten Schichten des Netzwerks gut trainiert sind, bleiben die ersten oft wĂ€hrend des Trainings stecken und lernen fast nichts. Und es ist nicht nur Pech. Wir werden grundlegende GrĂŒnde fĂŒr die Verlangsamung des Lernens finden, die mit der Verwendung von gradientenbasierten Lerntechniken zusammenhĂ€ngen.
Wenn wir uns tiefer mit diesem Problem befassen, stellen wir fest, dass auch das gegenteilige PhĂ€nomen auftreten kann: Die frĂŒhen Schichten können gut lernen und die spĂ€teren bleiben stecken. TatsĂ€chlich werden wir die interne InstabilitĂ€t entdecken, die mit dem Gradientenabstiegstraining in tiefen mehrschichtigen NS verbunden ist. Und aufgrund dieser InstabilitĂ€t bleiben die frĂŒhen oder spĂ€ten Schichten oft im Training stecken.
Das klingt alles ziemlich unangenehm. In diese Schwierigkeiten geraten, können wir beginnen, Ideen darĂŒber zu entwickeln, was fĂŒr ein effektives Training von STS getan werden muss. Daher werden diese Studien eine gute Vorbereitung fĂŒr das nĂ€chste Kapitel sein, in dem wir tiefes Lernen nutzen werden, um die Probleme der Bilderkennung anzugehen.
Fading Gradientenproblem
Was geht also schief, wenn wir versuchen, ein tiefes Netzwerk zu trainieren?
Um diese Frage zu beantworten, kehren wir zu dem Netzwerk zurĂŒck, das nur eine verborgene Schicht enthĂ€lt. Wie ĂŒblich werden wir das MNIST-Ziffernklassifizierungsproblem als Sandbox zum Lernen und Experimentieren verwenden.
Wenn Sie alle diese Schritte auf Ihrem Computer wiederholen möchten, mĂŒssen Sie Python 2.7 installiert haben, die Numpy-Bibliothek und eine Kopie des Codes, der aus dem Repository entnommen werden kann:
git clone https://github.com/mnielsen/neural-networks-and-deep-learning.git
Sie können auf Git verzichten, indem Sie einfach
die Daten und den Code herunterladen . Wechseln Sie in das Unterverzeichnis src und laden Sie aus der Python-Shell die MNIST-Daten:
>>> import mnist_loader >>> training_data, validation_data, test_data = \ ... mnist_loader.load_data_wrapper()
Konfigurieren Sie das Netzwerk:
>>> import network2 >>> net = network2.Network([784, 30, 10])
Ein solches Netzwerk hat 784 Neuronen in der Eingangsschicht, was 28 Ă 28 = 784 Pixel des Eingabebildes entspricht. Wir verwenden 30 versteckte Neuronen und 10 Wochenenden, was zehn möglichen Klassifizierungsoptionen fĂŒr die Zahlen MNIST ('0', '1', '2', ..., '9') entspricht.
Versuchen wir, unser Netzwerk fĂŒr 30 ganze Epochen zu trainieren, indem wir Mini-Pakete mit jeweils 10 Trainingsbeispielen verwenden, wobei die Lerngeschwindigkeit η = 0,1 und der Regularisierungsparameter λ = 5,0 sind. WĂ€hrend des Trainings werden wir die Genauigkeit der Klassifizierung durch validation_data verfolgen:
>>> net.SGD(training_data, 30, 10, 0.1, lmbda=5.0, ... evaluation_data=validation_data, monitor_evaluation_accuracy=True)
Wir erhalten eine Klassifizierungsgenauigkeit von 96,48% (oder so - die Zahlen variieren bei verschiedenen Starts), vergleichbar mit unseren frĂŒheren Ergebnissen mit Ă€hnlichen Einstellungen.
FĂŒgen wir eine weitere versteckte Ebene hinzu, die ebenfalls 30 Neuronen enthĂ€lt, und versuchen, das Netzwerk mit denselben Hyperparametern zu trainieren:
>>> net = network2.Network([784, 30, 30, 10]) >>> net.SGD(training_data, 30, 10, 0.1, lmbda=5.0, ... evaluation_data=validation_data, monitor_evaluation_accuracy=True)
Die Klassifizierungsgenauigkeit verbessert sich auf 96,90%. Es ist inspirierend - eine leichte Erhöhung der Tiefe hilft. FĂŒgen wir eine weitere versteckte Schicht von 30 Neuronen hinzu:
>>> net = network2.Network([784, 30, 30, 30, 10]) >>> net.SGD(training_data, 30, 10, 0.1, lmbda=5.0, ... evaluation_data=validation_data, monitor_evaluation_accuracy=True)
Es hat nicht geholfen. Das Ergebnis fiel sogar auf 96,57%, ein Wert nahe dem ursprĂŒnglichen flachen Netzwerk. Und wenn wir eine weitere versteckte Ebene hinzufĂŒgen:
>>> net = network2.Network([784, 30, 30, 30, 30, 10]) >>> net.SGD(training_data, 30, 10, 0.1, lmbda=5.0, ... evaluation_data=validation_data, monitor_evaluation_accuracy=True)
Dann sinkt die Klassifizierungsgenauigkeit wieder auf 96,53%. Statistisch gesehen ist dieser RĂŒckgang wahrscheinlich unbedeutend, aber es ist nichts Gutes daran.
Dieses Verhalten scheint seltsam. Es scheint intuitiv, dass zusĂ€tzliche verborgene Schichten dem Netzwerk helfen sollten, komplexere Klassifizierungsfunktionen zu erlernen und die Aufgabe besser zu bewĂ€ltigen. NatĂŒrlich sollte sich das Ergebnis nicht verschlechtern, da im schlimmsten Fall zusĂ€tzliche Schichten einfach nichts bewirken. Dies ist jedoch nicht der Fall.
Also, was ist los? Nehmen wir an, dass zusĂ€tzliche versteckte Ebenen im Prinzip helfen können und dass das Problem darin besteht, dass unser Trainingsalgorithmus nicht die richtigen Werte fĂŒr Gewichte und Offsets findet. Wir möchten verstehen, was mit unserem Algorithmus nicht stimmt und wie wir ihn verbessern können.
Um zu verstehen, was schief gelaufen ist, visualisieren wir den Lernprozess im Netzwerk. Unten habe ich einen Teil des Netzwerks aufgebaut [784,30,30,10], in dem es zwei versteckte Schichten gibt, von denen jede 30 versteckte Neuronen hat. In dem Diagramm hat jedes Neuron einen Balken, der die Ănderungsrate beim Lernen des Netzwerks angibt. Ein groĂer Balken bedeutet, dass sich die Gewichte und Verschiebungen des Neurons schnell Ă€ndern, und ein kleiner bedeutet, dass sie sich langsam Ă€ndern. Genauer gesagt bezeichnet der Balken den âC / âb-Gradienten des Neurons, dh die Ănderungsrate der Kosten in Bezug auf den Versatz. In
Kapitel 2 haben wir gesehen, dass dieser Gradientenwert nicht nur die Ănderungsrate der Verschiebung wĂ€hrend des Trainings steuert, sondern auch die Ănderungsrate der eingegebenen Neuronengewichte. Machen Sie sich keine Sorgen, wenn Sie sich nicht an diese Details erinnern können: Sie mĂŒssen nur bedenken, dass diese Balken angeben, wie schnell sich die Gewichte und Verschiebungen der Neuronen wĂ€hrend des Trainings des Netzwerks Ă€ndern.
Um das Diagramm zu vereinfachen, habe ich nur sechs obere Neuronen in zwei versteckten Schichten gezeichnet. Ich habe die ankommenden Neuronen gesenkt, weil sie keine Gewichte oder Vorurteile haben. Ich habe auch Ausgangsneuronen weggelassen, da wir zwei Schichten vergleichen und es sinnvoll ist, Schichten mit der gleichen Anzahl von Neuronen zu vergleichen. Das Diagramm wurde mit dem Programm generate_gradient.py zu Beginn des Trainings erstellt, dh unmittelbar nach der Initialisierung des Netzwerks.

Das Netzwerk wurde zufĂ€llig initialisiert, daher ist diese Vielfalt in der Geschwindigkeit des Trainings von Neuronen nicht ĂŒberraschend. Es fĂ€llt jedoch sofort auf, dass in der zweiten verborgenen Schicht die Streifen im Grunde viel mehr sind als in der ersten. Infolgedessen lernen Neuronen in der zweiten Schicht viel schneller als in der ersten. Ist dies ein Zufall oder lernen Neuronen in der zweiten Schicht im Allgemeinen schneller als die Neuronen in der ersten?
Um genau zu wissen, ist es gut, eine allgemeine Methode zum Vergleichen der Lerngeschwindigkeit in der ersten und zweiten verborgenen Ebene zu haben. Dazu bezeichnen wir den Gradienten als ÎŽlj = âC / âblj, dh als Gradienten des Neurons Nr. J in der Schicht Nr. 1. Im zweiten Kapitel haben wir es einen "Fehler" genannt, aber hier werde ich es informell einen "Gradienten" nennen. Informell - da dieser Wert nicht explizit partielle Ableitungen der Gewichtskosten enthĂ€lt, ist âC / âw. Der Gradient ÎŽ
1 kann als ein Vektor betrachtet werden, dessen Elemente bestimmen, wie schnell die erste verborgene Schicht lernt, und ÎŽ
2 als ein Vektor, dessen Elemente bestimmen, wie schnell die zweite verborgene Schicht lernt. Wir verwenden die LÀngen dieser Vektoren als ungefÀhre SchÀtzungen der Lerngeschwindigkeit der Schichten. Das ist zum Beispiel die LÀnge || Ύ
1 || misst die Lerngeschwindigkeit der ersten verborgenen Ebene und die LĂ€nge || ÎŽ
2 || misst die Lerngeschwindigkeit der zweiten verborgenen Schicht.
Mit solchen Definitionen und der gleichen Konfiguration wie oben finden wir, dass || ÎŽ
1 || = 0,07 und || ÎŽ
2 || = 0,31. Dies bestÀtigt unseren Verdacht: Die Neuronen in der zweiten verborgenen Schicht lernen viel schneller als die Neuronen in der ersten verborgenen Schicht.
Was passiert, wenn wir mehr versteckte Ebenen hinzufĂŒgen? Mit drei versteckten Schichten im Netzwerk [784,30,30,30,10] betragen die entsprechenden Lerngeschwindigkeiten 0,012, 0,060 und 0,283. Wieder lernen die ersten verborgenen Schichten viel langsamer als die letzten. FĂŒge eine weitere versteckte Ebene mit 30 Neuronen hinzu. In diesem Fall betragen die entsprechenden Lerngeschwindigkeiten 0,003, 0,017, 0,070 und 0,285. Das Muster bleibt erhalten: Die frĂŒhen Schichten lernen langsamer als die spĂ€teren.
Wir haben die Lerngeschwindigkeit gleich zu Beginn untersucht - direkt nach der Initialisierung des Netzwerks. Wie Ă€ndert sich diese Geschwindigkeit beim Lernen? Gehen wir zurĂŒck und betrachten das Netzwerk mit zwei versteckten Schichten. Die Lerngeschwindigkeit Ă€ndert sich folgendermaĂen:

Um diese Ergebnisse zu erhalten, habe ich einen Batch-Gradientenabstieg mit 1000 Trainingsbildern und ein Training fĂŒr 500 Epochen verwendet. Dies unterscheidet sich geringfĂŒgig von unseren ĂŒblichen Verfahren - ich habe keine Minipakete verwendet und nur 1000 Trainingsbilder anstelle eines vollstĂ€ndigen Satzes von 50.000 Teilen aufgenommen. Ich versuche nicht, Sie auszutricksen und zu tĂ€uschen, aber es stellt sich heraus, dass die Verwendung eines stochastischen Gradientenabfalls mit Minipaketen viel mehr Rauschen zu den Ergebnissen fĂŒhrt (aber wenn Sie das Rauschen mitteln, sind die Ergebnisse Ă€hnlich). Mit den von mir gewĂ€hlten Parametern ist es einfach, die Ergebnisse zu glĂ€tten, damit wir sehen können, was passiert.
Wie wir sehen, beginnen auf jeden Fall zwei Schichten mit zwei sehr unterschiedlichen Geschwindigkeiten (die wir bereits kennen) mit dem Training. Dann fĂ€llt die Geschwindigkeit beider Schichten sehr schnell ab, wonach ein RĂŒckprall auftritt. WĂ€hrend dieser ganzen Zeit lernt die erste verborgene Ebene jedoch viel langsamer als die zweite.
Was ist mit komplexeren Netzwerken? Hier sind die Ergebnisse eines Àhnlichen Experiments, jedoch mit einem Netzwerk mit drei verborgenen Schichten [784,30,30,30,10]:

Und wieder lernen die ersten verborgenen Schichten viel langsamer als die letzten. Lassen Sie uns abschlieĂend versuchen, eine vierte verborgene Ebene (Netzwerk [784,30,30,30,30,10]) hinzuzufĂŒgen und zu sehen, was passiert, wenn es trainiert wird:

Und wieder lernen die ersten verborgenen Schichten viel langsamer als die letzten. In diesem Fall lernt die erste verborgene Ebene etwa 100-mal langsamer als die letzte. Kein Wunder, dass wir solche Probleme hatten, diese Netzwerke zu lernen!
Wir haben eine wichtige Beobachtung gemacht: Zumindest bei einigen GNS nimmt der Gradient ab, wenn man sich entlang versteckter Schichten in die entgegengesetzte Richtung bewegt. Das heiĂt, die Neuronen in den ersten Schichten werden viel langsamer trainiert als die Neuronen in der letzten. Und obwohl wir diesen Effekt nur in einem Netzwerk beobachtet haben, gibt es grundlegende GrĂŒnde, warum dies in vielen NS passiert. Dieses PhĂ€nomen ist als âverschwindendes Gradientenproblemâ bekannt (siehe Arbeiten
1 ,
2 ).
Warum gibt es ein Problem mit dem verblassenden Gradienten? Gibt es Möglichkeiten, dies zu vermeiden? Wie gehen wir damit um, wenn wir STS trainieren? TatsĂ€chlich werden wir bald feststellen, dass dies nicht unvermeidlich ist, obwohl die Alternative fĂŒr sie nicht sehr attraktiv erscheint: Manchmal ist der Gradient in den ersten Schichten viel gröĂer! Dies ist bereits ein Problem des explosiven Gradientenwachstums, und es ist darin nicht besser als im Problem eines verschwindenden Gradienten. Im Allgemeinen stellt sich heraus, dass der Gradient im STS instabil ist und entweder zu explosivem Wachstum neigt oder in den ersten Schichten verschwindet. Diese InstabilitĂ€t ist ein grundlegendes Problem fĂŒr das Gradienten-GNS-Training. Dies ist es, was wir verstehen und möglicherweise irgendwie lösen mĂŒssen.
Eine der Reaktionen auf einen verblassenden (oder instabilen) Gradienten besteht darin, darĂŒber nachzudenken, ob dies tatsĂ€chlich ein ernstes Problem ist. Lassen Sie uns kurz vom NS ablenken und uns vorstellen, dass wir versuchen, die Funktion f (x) einer Variablen numerisch zu minimieren. WĂ€re es nicht schön, wenn die Ableitung f '(x) klein wĂ€re? WĂŒrde das nicht bedeuten, dass wir schon dem Extrem nahe sind? Und bedeutet ein kleiner Gradient in den ersten Schichten des GNS nicht, dass wir Gewichte und Verschiebungen nicht mehr stark anpassen mĂŒssen?
NatĂŒrlich nicht. Denken Sie daran, dass wir die Gewichte und Offsets des Netzwerks zufĂ€llig initialisiert haben. Es ist höchst unwahrscheinlich, dass unsere ursprĂŒnglichen Gewichte und Mischungen gut mit dem ĂŒbereinstimmen, was wir von unserem Netzwerk erwarten. Betrachten Sie als spezifisches Beispiel die erste Schicht von Gewichten im Netzwerk [784,30,30,30,10], die die Zahlen MNIST klassifiziert. ZufĂ€llige Initialisierung bedeutet, dass die erste Ebene die meisten Informationen ĂŒber das eingehende Bild auswirft. Selbst wenn die spĂ€teren Schichten sorgfĂ€ltig trainiert wĂŒrden, wĂ€re es fĂŒr sie Ă€uĂerst schwierig, die eingehende Nachricht zu bestimmen, einfach weil es an Informationen mangelt. Es ist daher absolut unmöglich sich vorzustellen, dass die erste Schicht einfach nicht trainiert werden muss. Wenn wir STS trainieren wollen, mĂŒssen wir verstehen, wie das Problem eines verschwindenden Gradienten gelöst werden kann.
Was verursacht das Problem des Fading-Gradienten? Instabile Gradienten in GNS
Um zu verstehen, wie das Problem eines verschwindenden Gradienten auftritt, betrachten Sie die einfachste NS: mit nur einem Neuron in jeder Schicht. Hier ist ein Netzwerk mit drei versteckten Schichten:

Hier sind w
1 , w
2 , ... Gewichte, b
1 , b
2 , ... Verschiebungen, C ist eine bestimmte Kostenfunktion. Zur Erinnerung möchte ich sagen, dass die Ausgabe a
j von Neuron Nr. J gleich Ï (z
j ) ist, wobei Ï die ĂŒbliche Sigmoidaktivierungsfunktion ist und z
j = w
j a
j - 1 + b
j die gewichtete Eingabe des Neurons ist. Ich habe die Kostenfunktion am Ende dargestellt, um zu betonen, dass die Kosten eine Funktion der Netzwerkleistung sind, und
4 : Wenn die tatsĂ€chliche Leistung nahe an dem liegt, was Sie möchten, sind die Kosten gering, und wenn weit, sind sie groĂ.
Wir untersuchen den Gradienten âC / âb
1 , der mit dem ersten versteckten Neuron assoziiert ist. Wir finden den Ausdruck fĂŒr âC / âb
1 und nachdem wir ihn untersucht haben, werden wir verstehen, warum das Problem des verschwindenden Gradienten auftritt.
Wir beginnen mit der Demonstration des Ausdrucks fĂŒr âC / âb
1 . Es sieht uneinnehmbar aus, aber tatsĂ€chlich ist seine Struktur einfach und ich werde es bald beschreiben. Hier ist dieser Ausdruck (ignorieren Sie vorerst das Netzwerk selbst und beachten Sie, dass Ï nur eine Ableitung der Funktion Ï ist):

Die Struktur des Ausdrucks ist wie folgt: FĂŒr jedes Neuron im Netzwerk gibt es einen Multiplikationsterm Ï '(z
j ), fĂŒr jedes Gewicht gibt es w
j und es gibt auch den letzten Term âC / âa
4 , der der Kostenfunktion entspricht. Beachten Sie, dass ich die entsprechenden Mitglieder ĂŒber den entsprechenden Teilen des Netzwerks platziert habe. Daher ist das Netzwerk selbst eine mnemonische Ausdrucksregel.
Sie können diesen Ausdruck auf Glauben nehmen und seine Diskussion direkt an die Stelle ĂŒberspringen, an der erklĂ€rt wird, wie er sich auf das Problem des verblassenden Gradienten bezieht. Daran ist nichts auszusetzen, da dieser Ausdruck ein Sonderfall aus unserer Diskussion ĂŒber die RĂŒckausbreitung ist. Es ist jedoch leicht, seine Treue zu erklĂ€ren, so dass es fĂŒr Sie sehr interessant (und vielleicht lehrreich) sein wird, diese ErklĂ€rung zu studieren.
Stellen Sie sich vor, wir hĂ€tten eine kleine Ănderung von Îb
1 zum Versatz b
1 vorgenommen . Dadurch werden eine Reihe von kaskadierenden Ănderungen im Rest des Netzwerks gesendet. Erstens bewirkt dies, dass sich die Ausgabe des ersten versteckten Neurons Îa
1 Ă€ndert. Dies wiederum zwingt Îz
2 , sich in der gewichteten Eingabe in das zweite versteckte Neuron zu Ă€ndern. Dann Ă€ndert sich Îa
2 in der Ausgabe des zweiten versteckten Neurons. Und so weiter bis zu einer Ănderung von ÎC im Ausgangswert. Es stellt sich heraus, dass:
frac partiellesC partiellesb1 approx frac DeltaC Deltab1 tag114
Dies legt nahe, dass wir einen Ausdruck fĂŒr den Gradienten âC / âb
1 ableiten können, indem wir den Einfluss jedes Schritts in dieser Kaskade sorgfĂ€ltig ĂŒberwachen.
Lassen Sie uns dazu ĂŒberlegen, wie Îb
1 bewirkt, dass sich die Ausgabe a
1 des ersten versteckten Neurons Àndert. Wir haben also a
1 = Ï (z
1 ) = Ï (w
1 a
0 + b
1 )
Deltaa1 approx frac partielles Sigma(w1a0+b1) partiellesb1 Deltab1 tag115
= sigmaâČ(z1) Deltab1 tag116
Der Term Ï âČ (z
1 ) sollte bekannt vorkommen: Dies ist der erste Term unseres Ausdrucks fĂŒr den Gradienten âC / âb
1 . Intuitiv wandelt es die Ănderung des Offsets & Dgr; b
1 in die Ănderung & Dgr; a
1 der Ausgangsaktivierung um. Die Ănderung von Îa
1 bewirkt wiederum eine Ănderung der gewichteten Eingabe z
2 = w
2 a
1 + b
2 des zweiten versteckten Neurons:
Deltaz2 approx frac teilweisez2 teilweisea1 Deltaa1 tag117
=w2 Deltaa1 tag118
Wenn wir die AusdrĂŒcke fĂŒr Îz
2 und Îa
1 kombinieren, sehen wir, wie sich die Ănderung der Vorspannung b
1 entlang des Netzwerks ausbreitet und z
2 beeinflusst :
Deltaz2 approx sigmaâČ(z1)w2 Deltab1 tag119
Und das sollte auch bekannt sein: Dies sind die ersten beiden Begriffe in unserem angegebenen Ausdruck fĂŒr den Gradienten âC / âb
1 .
Dies kann weiter fortgesetzt werden, indem ĂŒberwacht wird, wie sich Ănderungen im Rest des Netzwerks verbreiten. Auf jedem Neuron wĂ€hlen wir den Term Ï '(z
j ) und durch jedes Gewicht den Term w
j . Als Ergebnis wird ein Ausdruck erhalten, der die endgĂŒltige Ănderung & Dgr; C der Kostenfunktion mit der anfĂ€nglichen Ănderung & Dgr; b
1 der Vorspannung in Beziehung setzt:
DeltaC approx sigmaâČ(z1)w2 sigmaâČ(z2) ldots sigmaâČ(z4) frac partiellesC partiellesa4 Deltab1 tag120
Wenn wir es durch Îb
1 teilen, erhalten wir wirklich den gewĂŒnschten Ausdruck fĂŒr den Gradienten:
frac partiellesC partiellesb1= sigmaâČ(z1)w2 sigmaâČ(z2) ldots sigmaâČ(z4) frac partiellesC partiellesa4 tag121
Warum gibt es ein Problem mit dem verblassenden Gradienten?
Um zu verstehen, warum das Problem des verschwindenden Gradienten auftritt, schreiben wir unseren gesamten Ausdruck fĂŒr den Gradienten im Detail:
frac partiellesC partiellesb1= sigmaâČ(z1) w2 sigmaâČ(z2) w3 sigmaâČ(z3)w 4 s i g m a ' ( z 4 ) f r a c p a r t i e l l e s C p a r t i e l l e s a 4 t a g 122
ZusÀtzlich zum letzten Term ist dieser Ausdruck das Produkt von Termen der Form w
j Ï âČ (z
j ). Um zu verstehen, wie sich jeder von ihnen verhĂ€lt, betrachten wir den Graphen der Funktion Ï:

Der Graph erreicht ein Maximum am Punkt Ï '(0) = 1/4. Wenn wir den Standardansatz zum Initialisieren der Netzwerkgewichte verwenden, wĂ€hlen wir die Gewichte unter Verwendung der GauĂschen Verteilung aus, dh des quadratischen Mittelwerts Null und der Standardabweichung 1. Daher erfĂŒllen die Gewichte normalerweise die Ungleichung | w
j | <1. Wenn wir all diese Beobachtungen vergleichen, sehen wir, dass die Terme w
j Ï '(z
j ) normalerweise die Ungleichung | w
j Ï' (z
j ) | <1/4 erfĂŒllen. Und wenn wir das Produkt aus der Menge solcher Begriffe nehmen, wird es exponentiell abnehmen: Je mehr Begriffe, desto kleiner das Produkt. Es scheint eine mögliche Lösung fĂŒr das Problem des verschwindenden Gradienten zu sein.
Um dies genauer zu schreiben, vergleichen wir den Ausdruck fĂŒr âC / âb
1 mit dem Ausdruck des Gradienten in Bezug auf den nĂ€chsten Versatz, zum Beispiel âC / âb
3 . NatĂŒrlich haben wir keinen detaillierten Ausdruck fĂŒr âC / âb
3 aufgeschrieben, aber er folgt den gleichen Gesetzen wie oben fĂŒr âC / âb
1 beschrieben . Und hier ist ein Vergleich zweier AusdrĂŒcke:

Sie haben mehrere gemeinsame Mitglieder. Der Gradient âC / âb
1 enthÀlt jedoch zwei zusÀtzliche Terme, von denen jeder die Form w
j Ï âČ (z
j ) hat. Wie wir gesehen haben, ĂŒberschreiten solche Begriffe normalerweise nicht 1/4. Daher ist der Gradient âC / âb
1 normalerweise 16 (oder mehr) Mal kleiner als âC / âb
3 . Und dies ist die Hauptursache fĂŒr das Problem des verschwindenden Gradienten.
Dies ist natĂŒrlich kein genauer, aber informeller Beweis fĂŒr das Problem. Es gibt mehrere EinschrĂ€nkungen. Insbesondere könnte man daran interessiert sein, ob die Gewichte w
j wĂ€hrend des Trainings zunehmen werden. In diesem Fall erfĂŒllen die Terme w
j Ï '(z
j ) im Produkt nicht mehr die Ungleichung | w
j Ï' (z
j ) | <1/4. Und wenn sich herausstellt, dass sie groĂ genug sind, mehr als 1, haben wir nicht mehr das Problem eines verblassenden Gradienten. Stattdessen wĂ€chst der Farbverlauf exponentiell, wenn Sie sich durch die Ebenen zurĂŒckbewegen. Und anstelle des Problems des verschwindenden Gradienten erhalten wir das Problem des explosiven Gradientenwachstums.
Das Problem des explosiven Gradientenwachstums
Schauen wir uns ein konkretes Beispiel fĂŒr einen explosiven Gradienten an. Das Beispiel wird etwas kĂŒnstlich sein: Ich werde die Netzwerkparameter anpassen, um das Auftreten eines explosiven Wachstums zu gewĂ€hrleisten. Obwohl das Beispiel kĂŒnstlich ist, zeigt es deutlich, dass das explosive Wachstum des Gradienten keine hypothetische Möglichkeit ist, aber es kann wirklich passieren.
FĂŒr ein explosives Gradientenwachstum mĂŒssen Sie zwei Schritte ausfĂŒhren. ZunĂ€chst wĂ€hlen wir groĂe Gewichte im gesamten Netzwerk aus, z. B. w1 = w2 = w3 = w4 = 100. Dann wĂ€hlen wir solche Verschiebungen so, dass die Terme Ï âČ (z
j ) nicht zu klein sind. Und das ist ganz einfach: Wir mĂŒssen nur solche Verschiebungen so auswĂ€hlen, dass die gewichtete Eingabe jedes Neurons zj = 0 ist (und dann Ï âČ (
zj ) = 1/4). Daher brauchen wir zum Beispiel z
1 = w
1 a
0 + b
1 = 0. Dies kann erreicht werden, indem b
1 = â100 â a
0 gesetzt wird . Die gleiche Idee kann verwendet werden, um andere Offsets auszuwÀhlen. Als Ergebnis werden wir sehen, dass alle Terme w
j Ï '(z
j ) gleich 100 â 14 = 25 sind. Und dann bekommen wir ein explosives Gradientenwachstum.
Instabiles Gradientenproblem
Das grundlegende Problem ist nicht das verschwindende Gradientenproblem oder das explosive Wachstum des Gradienten. Es ist so, dass der Gradient in den ersten Schichten das Produkt von Elementen aus allen anderen Schichten ist. Und wenn es viele Schichten gibt, wird die Situation im Wesentlichen instabil. Und die einzige Möglichkeit, mit der alle Ebenen ungefĂ€hr gleich schnell lernen können, besteht darin, solche Mitglieder der Arbeit auszuwĂ€hlen, die sich gegenseitig ausgleichen. Und da es keinen Mechanismus oder Grund fĂŒr einen solchen Ausgleich gibt, ist es unwahrscheinlich, dass dies zufĂ€llig geschieht.
Kurz gesagt, das eigentliche Problem ist, dass NS unter dem Problem eines instabilen Gradienten leidet. Und am Ende lernen verschiedene Schichten des Netzwerks mit furchtbar unterschiedlichen Geschwindigkeiten, wenn wir standardmĂ€Ăige gradientenbasierte Lerntechniken verwenden.Ăbung
- , |ÏâČ(z)|<1/4. , , . ?
Wir haben gesehen, dass der Gradient in den ersten Schichten eines tiefen Netzwerks verschwinden oder explosionsartig wachsen kann. TatsĂ€chlich verschwindet bei Verwendung von Sigmoidneuronen der Gradient normalerweise. Um zu verstehen, warum, betrachten Sie erneut den Ausdruck | wÏ âČ (z) |. Um das Problem des verschwindenden Gradienten zu vermeiden, benötigen wir | wÏ âČ (z) | â„1. Sie können entscheiden, dass dies mit sehr groĂen Werten von w leicht zu erreichen ist. In Wirklichkeit ist es jedoch nicht so einfach. Der Grund ist, dass der Term Ï '(z) auch von w abhĂ€ngt: Ï' (z) = Ï '(wa + b), wobei a die Eingangsaktivierung ist. Und wenn wir w groĂ machen, mĂŒssen wir versuchen, Ï âČ (wa + b) nicht parallel klein zu machen. Und dies stellt sich als ernsthafte EinschrĂ€nkung heraus. Der Grund ist, dass wenn wir w groĂ machen, wir wa + b sehr groĂ machen. Wenn Sie sich den Graphen von Ï 'ansehen, können Sie sehen, dass dies uns zu den âFlĂŒgelnâ der Funktion Ï' fĂŒhrt.wo es sehr kleine Werte annimmt. Die einzige Möglichkeit, dies zu vermeiden, besteht darin, die eingehende Aktivierung in einem relativ engen Wertebereich zu halten. Manchmal passiert das zufĂ€llig. Aber öfter passiert das nicht. Daher haben wir im allgemeinen Fall das Problem eines verschwindenden Gradienten.Die Aufgaben
Wir haben Spielzeugnetzwerke mit nur einem Neuron in jeder verborgenen Schicht untersucht. Was ist mit komplexeren tiefen Netzwerken, die viele Neuronen in jeder verborgenen Schicht haben?
In solchen Netzwerken passiert fast dasselbe. Zu Beginn des Kapitels ĂŒber die RĂŒckausbreitung haben wir gesehen, dass der Gradient in Schicht #l eines Netzwerks mit L Schichten wie folgt angegeben wird:ÎŽl=ÎŁâČ(zl)(wl+1)TÎŁâČ(zl+1)(wl+2)TâŠÎŁâČ(zL)âaC
Hier ist ÎŁ '(z l ) die Diagonalmatrix, deren Elemente die Werte von Ï' (z) fĂŒr die gewichteten Eingaben der Schicht Nr. 1 sind. w l sind Gewichtsmatrizen fĂŒr verschiedene Schichten. Und â a C ist der Vektor partieller Ableitungen von C in Bezug auf Ausgangsaktivierungen.Dieser Ausdruck ist viel komplizierter als bei einem Neuron. Und doch, wenn Sie genau hinschauen, wird seine Essenz sehr Ă€hnlich sein, mit einer Reihe von Paaren der Form (w j ) T ÎŁ âČ (z j ). DarĂŒber hinaus haben die Matrizen ÎŁ '(z j ) diagonal kleine Werte, nicht mehr als 1/4. Wenn die Gewichtsmatrizen w j nicht zu groĂ sind, ist jeder zusĂ€tzliche Term (w j ) T ÎŁ âČ (z l) neigt dazu, den Gradientenvektor zu reduzieren, was zu einem verschwindenden Gradienten fĂŒhrt. Im allgemeinen Fall fĂŒhrt eine gröĂere Anzahl von Multiplikationstermen zu einem instabilen Gradienten, wie in unserem vorherigen Beispiel. In der Praxis, empirisch normalerweise in Sigmoid-Netzwerken, verschwinden Gradienten in den ersten Schichten exponentiell schnell. Infolgedessen verlangsamt sich das Lernen in diesen Ebenen. Und die Verlangsamung ist kein Unfall oder eine Unannehmlichkeit: Sie ist eine grundlegende Folge unseres gewĂ€hlten Lernansatzes.Andere Hindernisse fĂŒr tiefes Lernen
In diesem Kapitel habe ich mich auf das Verblassen von VerlĂ€ufen - und allgemein auf instabile VerlĂ€ufe - als Hindernis fĂŒr tiefes Lernen konzentriert. In der Tat sind instabile Gradienten nur ein Hindernis fĂŒr die Entwicklung des Zivilschutzes, wenn auch ein wichtiges und grundlegendes. Ein wesentlicher Teil der aktuellen Forschung versucht, die Probleme, die beim Unterrichten von GO auftreten können, besser zu verstehen. Ich werde nicht alle diese Werke im Detail beschreiben, aber ich möchte kurz einige Werke erwĂ€hnen, um Ihnen eine Vorstellung von einigen Fragen zu geben, die von Menschen gestellt werden.Als erstes Beispiel im Jahr 2010Es wurden Beweise dafĂŒr gefunden, dass die Verwendung von Sigmoid-Aktivierungsfunktionen zu Problemen beim Lernen von NS fĂŒhren kann. Insbesondere wurde festgestellt, dass die Verwendung eines Sigmoid dazu fĂŒhrt, dass die Aktivierungen der letzten verborgenen Schicht wĂ€hrend des Trainings in der Region 0 gesĂ€ttigt sind, was das Training ernsthaft verlangsamt. Es wurden mehrere alternative Aktivierungsfunktionen vorgeschlagen, die nicht so stark unter dem SĂ€ttigungsproblem leiden (siehe auch ein anderes Diskussionspapier ).Als erstes Beispiel wurde 2013 der Effekt der zufĂ€lligen Initialisierung von Gewichten und des Impulsgraphen in einem stochastischen Gradientenabstieg basierend auf einem Impuls auf dem GO untersucht. In beiden FĂ€llen beeinflusste eine gute Wahl die FĂ€higkeit, STS zu trainieren, erheblich.Diese Beispiele legen nahe, dass die Frage âWarum ist STS so schwer zu trainieren?â sehr kompliziert. In diesem Kapitel haben wir uns auf die InstabilitĂ€ten konzentriert, die mit dem Gradiententraining von GNS verbunden sind. Die Ergebnisse der beiden vorhergehenden AbsĂ€tze zeigen, dass die Wahl der Aktivierungsfunktion, die Methode zum Initialisieren der Gewichte und sogar die Details der DurchfĂŒhrung des Trainings basierend auf dem Gradientenabstieg ebenfalls eine Rolle spielen. Und natĂŒrlich wird die Wahl der Netzwerkarchitektur und anderer Hyperparameter wichtig sein. Daher können viele Faktoren eine Rolle bei der Schwierigkeit spielen, tiefe Netzwerke zu lernen, und das Problem des VerstĂ€ndnisses dieser Faktoren ist Gegenstand laufender Forschung. Aber das alles wirkt eher dĂŒster und fĂŒhrt zu Pessimismus. Es gibt jedoch gute Nachrichten - im nĂ€chsten Kapitel werden wir alles zu unseren Gunsten einpacken und verschiedene AnsĂ€tze in GO entwickeln.die in gewissem MaĂe in der Lage sein wird, all diese Probleme zu ĂŒberwinden oder zu umgehen.