Überanpassung des neuronalen Faltungsnetzwerks. Ausfallende hilft nicht

16

Ich spiele ein bisschen mit Convnets. Insbesondere verwende ich den Datensatz kaggle cats-vs-dogs, der aus 25000 Bildern besteht, die entweder als Katze oder als Hund (jeweils 12500) gekennzeichnet sind.

Ich habe es geschafft, mit meinem Testset eine Klassifizierungsgenauigkeit von ca. 85% zu erreichen, habe mir jedoch das Ziel gesetzt, eine Genauigkeit von 90% zu erreichen.

Mein Hauptproblem ist die Überanpassung. Irgendwie passiert es immer (normalerweise nach Epoche 8-10). Die Architektur meines Netzwerks ist lose von VGG-16 inspiriert, genauer gesagt, meine Bilder werden auf 128x128x3 verkleinert , und dann führe ich Folgendes aus:

Convolution 1 128x128x32 (kernel size is 3, strides is 1)
Convolution 2 128x128x32 (kernel size is 3, strides is 1)
Max pool    1 64x64x32   (kernel size is 2, strides is 2)
Convolution 3 64x64x64   (kernel size is 3, strides is 1)
Convolution 4 64x64x64   (kernel size is 3, strides is 1)
Max pool    2 32x32x64   (kernel size is 2, strides is 2)
Convolution 5 16x16x128  (kernel size is 3, strides is 1)
Convolution 6 16x16x128  (kernel size is 3, strides is 1)
Max pool    3 8x8x128    (kernel size is 2, strides is 2)
Convolution 7 8x8x256    (kernel size is 3, strides is 1)
Max pool    4 4x4x256    (kernel size is 2, strides is 2)
Convolution 8 4x4x512    (kernel size is 3, strides is 1)
Fully connected layer 1024 (dropout 0.5)
Fully connected layer 1024 (dropout 0.5)

Alle Ebenen mit Ausnahme der letzten haben Relus als Aktivierungsfunktionen.

Beachten Sie, dass ich verschiedene Kombinationen von Windungen ausprobiert habe (ich habe mit einfacheren Windungen begonnen).

Außerdem habe ich den Datensatz durch Spiegeln der Bilder erweitert, sodass ich insgesamt 50000 Bilder habe.

Außerdem normalisiere ich die Bilder mithilfe der Min-Max-Normalisierung, wobei X das Bild ist

X=X0/2550

Der Code ist in Tensorflow geschrieben und die Chargengrößen sind 128.

Die Mini-Chargen von Trainingsdaten sind zu stark angepasst und haben eine Genauigkeit von 100%, während die Validierungsdaten bei etwa 84-85% nicht mehr zu lernen scheinen.

Ich habe auch versucht, die Abbrecherquote zu erhöhen / zu verringern.

Der verwendete Optimierer ist AdamOptimizer mit einer Lernrate von 0,0001

Im Moment spiele ich seit 3 ​​Wochen mit diesem Problem und 85% scheinen eine Barriere vor mir gesetzt zu haben.

Ich verstehe, dass ich Transferlernen verwenden könnte, um viel höhere Ergebnisse zu erzielen, aber ich bin daran interessiert, dieses Netzwerk als selbstlernende Erfahrung aufzubauen.

Aktualisieren:

Ich verwende das gleiche Netzwerk mit einer anderen Stapelgröße. In diesem Fall verwende ich eine viel kleinere Stapelgröße (16 statt 128). Bisher erreiche ich eine Genauigkeit von 87,5% (statt 85%). Trotzdem ist das Netzwerk ohnehin überfordert. Ich verstehe immer noch nicht, wie ein Ausfall von 50% der Einheiten nicht hilft ... offensichtlich mache ich hier etwas falsch. Irgendwelche Ideen?

Update 2:

Scheint, als hätte das Problem mit der Batchgröße zu tun, da ich mit einer kleineren Größe (16 statt 128) jetzt eine Genauigkeit von 92,8% auf meinem Test-Set erreiche. Mit der kleineren Batchgröße passt das Netzwerk immer noch (die Mini-Batches enden) mit einer Genauigkeit von 100%) nimmt der Verlust (Fehler) jedoch immer weiter ab und ist im Allgemeinen stabiler. Die Nachteile sind eine VIEL langsamere Laufzeit, aber das Warten lohnt sich auf jeden Fall.

Juan Antonio Gomez Moriano
quelle
2
Können Sie nähere Angaben zu Ihrer Einschätzung der Überanpassung machen? Zum Beispiel hat die Validierung Genauigkeit Abfall an jedem Punkt neben der Divergenz von der Ausbildung und Validierungsergebnissen? Wie wäre es mit der Verlustfunktion?
Neil Slater
Gute Frage, mit Überanpassung meine ich die Tatsache, dass die Mini-Chargen im Zug eine Genauigkeit von 100% und Verluste von 0,08 erreichen, während die Validierung nie unter 0,35 zu fallen scheint und ihre Genauigkeit jetzt bei 88% bleibt. Laut der Validierung scheint es nicht zu fallen (zumindest nicht zu viel), scheint flach zu werden, aber wie kommt es, dass die Mini-Charge einen so geringen Verlust erzielt, während die Validierung noch weit davon entfernt ist?
Juan Antonio Gomez Moriano
Ich kenne keine Antwort für Sie, aber dieses Verhalten - große Divergenz zwischen Zug und Validierung, aber immer noch in Ordnung - habe ich schon einige Male gesehen. Ich zögere fast, es als übermäßig zu bezeichnen, da die Testergebnisse manchmal akzeptabel sind.
Neil Slater
"Ich verstehe immer noch nicht, wie ein Ausfall von 50% der Einheiten nicht hilft."
Ricardo Cruz

Antworten:

14

Ok, also nach vielen Experimenten habe ich es geschafft, einige Ergebnisse / Einsichten zu bekommen.

Erstens, wenn alles gleich ist, helfen kleinere Chargen im Trainingssatz sehr, um die allgemeine Leistung des Netzwerks zu verbessern , da der Trainingsprozess auf der negativen Seite viel langsamer ist.

Zweitens sind Daten wichtig, nichts Neues, aber wie ich im Kampf gegen dieses Problem gelernt habe, scheinen immer mehr Daten ein bisschen zu helfen.

Drittens ist Dropout in großen Netzwerken mit vielen Daten und vielen Iterationen nützlich. In meinem Netzwerk habe ich Dropout nur auf die endgültigen, vollständig verbundenen Layer angewendet, Faltungs-Layer wurden nicht angewendet.

Vierter Punkt (und das lerne ich immer wieder): Neuronale Netze brauchen VIEL, um zu trainieren, auch auf guten GPUs (ich habe dieses Netzwerk auf floydhub trainiert, das recht teure NVIDIA-Karten verwendet), daher ist PATIENCE der Schlüssel .

Endgültige Schlussfolgerung: Losgrößen sind wichtiger als man denkt, anscheinend ist es einfacher, ein lokales Minimum zu erreichen, wenn die Losgrößen größer sind.

Der Code, den ich geschrieben habe, ist als Python-Notizbuch erhältlich. Ich denke, er ist anständig dokumentiert

https://github.com/moriano/loco-learning/blob/master/cats-vs-dogs/cats-vs-dogs.ipynb

Juan Antonio Gomez Moriano
quelle
Vielen Dank für die Veröffentlichung Ihrer Ergebnisse. Kurze Frage: Ich bin vor ein ähnliches Problem und ich sah dies im Notebook Sie auf dem Laufenden: NOTE USE EITHER mean centering or min-max, NOT BOTH. Ich input_fnteile momentan meine Eingabebilder durch 255 in meiner (Tensorflow Estimator API). Dann führe ich diese Eingabe innerhalb des Modells durch die Chargennorm. Sollte ich trotzdem nur eine dieser Normalisierungen durchführen? Siehe github.com/formigone/tf-imagenet/blob/master/models/…
rodrigo-silveira 10.08.18
Mein Verständnis ist, dass die Division durch 255 für jedes Bild nur einmal durchgeführt wird, und der Grund ist, alle Werte zwischen 0 und 1 zu belassen, da dies für numerische Stabilität sorgt.
Juan Antonio Gomez Moriano
Klar, ich verstehe das. Halten Sie es jedoch für sinnvoll, diese Werte im Bereich [0, 1] auch im Batch zu normalisieren?
Rodrigo-Silveira
Das weiß ich nicht, es ist schon eine Weile her, dass ich Batch-Normalisierung verwendet habe :)
Juan Antonio Gomez Moriano
3

Ich schlage vor, Sie analysieren die Lernkurven Ihrer Validierungsgenauigkeit, wie von Neil Slater vorgeschlagen. Wenn die Validierungsgenauigkeit nachlässt, versuchen Sie, die Größe Ihres Netzwerks zu verringern (scheint zu tief zu sein), fügen Sie den CONV-Layern und BatchNormalization nach jedem Layer Dropout hinzu. Es kann helfen, Überanpassung zu beseitigen und die Testgenauigkeit zu erhöhen.

HatemB
quelle
Danke für den Rat, werde es versuchen, ich hatte jedoch den Eindruck, dass CONV-Schichten keine Aussetzer erfordern, auf den meisten von mir gelesenen Papieren scheint der Aussetzer immer auf die am Ende vollständig verbundenen Schichten angewendet zu werden, nicht auf die Convolutins.
Juan Antonio Gomez Moriano
3

Für Ihr Problem gibt es mehrere mögliche Lösungen.

  1. Verwenden Sie Dropout auch in früheren Ebenen (Faltungsebenen).

  2. Ihr Netzwerk scheint für eine so "einfache" Aufgabe ziemlich groß zu sein. versuchen Sie es zu reduzieren. Die großen Architekturen werden auch auf viel größere Datensätze trainiert.

Wenn Sie Ihre "große" Architektur beibehalten möchten, versuchen Sie Folgendes:

  1. Bildverbesserung zur virtuellen Steigerung Ihrer Trainingsdaten

  2. Versuchen Sie ein gegnerisches Training. Es hilft manchmal.

Andreas Schau
quelle
"Ihr Netzwerk scheint für eine so" einfache "Aufgabe ziemlich groß zu sein. Versuchen Sie, es zu reduzieren. Die großen Architekturen werden auch auf viel größere Datensätze trainiert." Ich bin anderer Meinung, als ich mehr Windungen hinzufügte, erhöhte sich die Genauigkeit (anfangs erreichte ich 68% mit nur zwei Windungen). Außerdem erweitere ich bereits meinen Datensatz und arbeite mit 50000 Bildern.
Juan Antonio Gomez Moriano
2

Eine Sache, die noch nicht erwähnt wurde und die Sie für die Zukunft in Betracht ziehen können: Sie können Ihren Ausfall auf den vollständig verbundenen Ebenen noch steigern.

Ich habe einmal eine Zeitung gelesen, in der die Abbrecherquote bei 90% lag. Obwohl es viele viele Knoten hatte (2048, wenn ich mich richtig erinnere), habe ich dies selbst auf Ebenen mit weniger Knoten versucht und es war in einigen Fällen sehr hilfreich.

Ich habe nur nachgeschlagen, welches Papier es war. Ich kann mich nicht erinnern, an welches Papier ich mich gerade erinnert habe, aber ich fand diese Papiere, die auch mit 90% Abbruchraten einige Erfolge hatten.

A. Karpathy, G. Toderici, S. Shetty, T. Leung, R. Sukthankar & L. Fei-Fei (2014). Videoklassifizierung in großem Maßstab mit neuronalen Faltungsnetzen. In Proceedings of the IEEE Konferenz über Computer Vision und Mustererkennung (S. 1725-1732).

Simonyan, K. & Zisserman, A. (2014). Zwei-Stream-Faltungsnetzwerke für die Aktionserkennung in Videos. Fortschritte in neuronalen Informationsverarbeitungssystemen (S. 568-576).

Varol, G., Laptev, I. & Schmid, C. (2017). Langfristige zeitliche Faltungen zur Handlungserkennung. IEEE-Transaktionen zu Musteranalyse und Maschinenintelligenz.

Kefbach
quelle
0

Ich hatte auch dieses Problem. Nachdem ich mich stundenlang damit beschäftigt hatte, beschloss ich zufällig, die Daten zu mischen, bevor ich sie in das System einspeiste, und voila, es fing an zu funktionieren. Ich brauchte ein bisschen, um herauszufinden, dass es das Mischen war, das den Trick gemacht hat! Hoffe das rettet jemanden vor Frust!

user79129
quelle