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 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
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.
quelle
Antworten:
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
quelle
NOTE USE EITHER mean centering or min-max, NOT BOTH
. Ichinput_fn
teile 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/…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.
quelle
Für Ihr Problem gibt es mehrere mögliche Lösungen.
Verwenden Sie Dropout auch in früheren Ebenen (Faltungsebenen).
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:
Bildverbesserung zur virtuellen Steigerung Ihrer Trainingsdaten
Versuchen Sie ein gegnerisches Training. Es hilft manchmal.
quelle
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.
quelle
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!
quelle