Was soll ich tun, wenn mein neuronales Netzwerk nicht lernt?

147

Ich trainiere ein neuronales Netzwerk, aber der Trainingsverlust nimmt nicht ab. Wie kann ich das beheben?

Ich frage nicht nach Überanpassung oder Regularisierung. Ich frage, wie ich das Problem lösen soll, bei dem sich die Leistung meines Netzwerks im Trainingssatz nicht verbessert .


Diese Frage ist absichtlich allgemein gehalten, so dass andere Fragen zum Trainieren eines neuronalen Netzwerks als Duplikat dieser Frage geschlossen werden können. Dabei lautet die Einstellung: "Wenn Sie einem Mann einen Fisch geben, füttern Sie ihn für einen Tag, aber wenn Sie a Mann zu fischen, können Sie ihn für den Rest seines Lebens füttern. " In diesem Meta-Thread finden Sie eine Diskussion: Wie kann ich die Frage "Mein neuronales Netzwerk funktioniert nicht, bitte beheben" am besten beantworten?

Wenn sich Ihr neuronales Netzwerk nicht gut verallgemeinert, lesen Sie: Was kann ich tun, wenn sich mein neuronales Netzwerk nicht gut verallgemeinert?

Sycorax
quelle
1
Hier ist der Fall, wo der NN nicht weiterkommen konnte. youtu.be/iakFfOmanJU?t=144
Joshua
4
Ivanovs Blog " Gründe, warum Ihr neuronales Netzwerk nicht funktioniert ", insbesondere die Abschnitte II, III und IV, könnten hilfreich sein.
user5228

Antworten:

187

Unit Testing ist dein Freund

Es gibt ein Sprichwort unter den Schriftstellern, dass "alles Schreiben ein Umschreiben ist" - das heißt, der größte Teil des Schreibens wird überarbeitet. Für Programmierer (oder zumindest Datenwissenschaftler) könnte der Ausdruck wie folgt umformuliert werden: "Die gesamte Codierung ist Debugging."

Jedes Mal, wenn Sie Code schreiben, müssen Sie sicherstellen, dass er wie beabsichtigt funktioniert. Die beste Methode, die ich je zur Überprüfung der Richtigkeit gefunden habe, besteht darin, den Code in kleine Segmente zu unterteilen und zu überprüfen, ob jedes Segment funktioniert. Dies kann erreicht werden, indem die Segmentausgabe mit der richtigen Antwort verglichen wird. Dies wird Unit-Test genannt . Das Schreiben guter Komponententests ist ein Schlüsselelement, um ein guter Statistiker / Datenwissenschaftler / Experte für maschinelles Lernen / Praktiker für neuronale Netze zu werden. Es gibt einfach keinen Ersatz.

Sie müssen überprüfen, ob Ihr Code fehlerfrei ist, bevor Sie die Netzwerkleistung optimieren können! Andernfalls können Sie Liegestühle auf der RMS Titanic auch neu anordnen .

Bei neuronalen Netzen gibt es zwei Merkmale, die die Verifizierung noch wichtiger machen als bei anderen Arten des maschinellen Lernens oder bei statistischen Modellen.

  1. Neuronale Netze sind keine Standardalgorithmen wie zufällige Gesamtstrukturen oder logistische Regressionen. Selbst bei einfachen Feed-Forward-Netzwerken muss der Benutzer zahlreiche Entscheidungen darüber treffen, wie das Netzwerk konfiguriert, verbunden, initialisiert und optimiert wird. Dies bedeutet das Schreiben von Code und das Schreiben von Code das Debuggen.

  2. Selbst wenn ein neuronaler Netzwerkcode ausgeführt wird, ohne eine Ausnahme auszulösen, kann das Netzwerk dennoch Fehler aufweisen! Diese Fehler könnten sogar die heimtückische Art sein, für die das Netzwerk trainiert, bleiben aber bei einer suboptimalen Lösung hängen, oder das resultierende Netzwerk weist nicht die gewünschte Architektur auf. ( Dies ist ein Beispiel für den Unterschied zwischen einem syntaktischen und einem semantischen Fehler .)

Dieses Medium Beitrag „ Wie Unit - Test für maschinelles Lernen Code “ von Chase Robert diskutiert Komponententests für die Modelle für maschinelles Lernen im Detail. Ich habe dieses Beispiel für Buggy-Code aus dem Artikel ausgeliehen:

def make_convnet(input_image):
    net = slim.conv2d(input_image, 32, [11, 11], scope="conv1_11x11")
    net = slim.conv2d(input_image, 64, [5, 5], scope="conv2_5x5")
    net = slim.max_pool2d(net, [4, 4], stride=4, scope='pool1')
    net = slim.conv2d(input_image, 64, [5, 5], scope="conv3_5x5")
    net = slim.conv2d(input_image, 128, [3, 3], scope="conv4_3x3")
    net = slim.max_pool2d(net, [2, 2], scope='pool2')
    net = slim.conv2d(input_image, 128, [3, 3], scope="conv5_3x3")
    net = slim.max_pool2d(net, [2, 2], scope='pool3')
    net = slim.conv2d(input_image, 32, [1, 1], scope="conv6_1x1")
    return net

Siehst du den fehler Viele der verschiedenen Operationen werden nicht verwendet, da vorherige Ergebnisse mit neuen Variablen überschrieben werden. Die Verwendung dieses Codeblocks in einem Netzwerk wird weiterhin trainiert und die Gewichte werden aktualisiert und der Verlust kann sich sogar verringern - aber der Code tut definitiv nicht das, was beabsichtigt war. (Der Autor ist auch in Bezug auf die Verwendung von einfachen oder doppelten Anführungszeichen inkonsistent, aber das ist rein stilistisch.)

Die häufigsten Programmierfehler bei neuronalen Netzen sind

  • Variablen werden erstellt, aber nie verwendet (normalerweise aufgrund von Fehlern beim Kopieren und Einfügen).
  • Ausdrücke für Gradientenaktualisierungen sind falsch.
  • Gewichtsaktualisierungen werden nicht angewendet.
  • Verlustfunktionen werden nicht auf der richtigen Skala gemessen (zum Beispiel kann der Kreuzentropieverlust in Form von Wahrscheinlichkeiten oder Logs ausgedrückt werden)
  • Der Verlust ist für die Aufgabe nicht geeignet (z. B. Verwendung eines kategorialen entropieübergreifenden Verlusts für eine Regressionsaufgabe).

Kriechen, bevor Sie gehen; Gehen Sie, bevor Sie rennen

Breite und tiefe neuronale Netze und neuronale Netze mit exotischer Verkabelung sind derzeit das A und O beim maschinellen Lernen. Aber diese Netzwerke sind nicht vollständig entstanden. Ihre Designer haben sich aus kleineren Einheiten zusammengesetzt. Erstellen Sie zunächst ein kleines Netzwerk mit einer einzelnen verborgenen Ebene und stellen Sie sicher, dass es ordnungsgemäß funktioniert. Fügen Sie dann schrittweise zusätzliche Modellkomplexität hinzu und vergewissern Sie sich, dass jede dieser Funktionen auch funktioniert.

  • Zu wenige Neuronen in einer Ebene können die Darstellung, die das Netzwerk lernt, einschränken und zu einer Unteranpassung führen. Zu viele Neuronen können zu einer Überanpassung führen, da sich das Netzwerk die Trainingsdaten "merkt".

    Auch wenn Sie mathematisch nachweisen können, dass nur eine geringe Anzahl von Neuronen zur Modellierung eines Problems erforderlich ist, ist es für den Optimierer häufig einfacher , eine "gute" Konfiguration zu finden , wenn "ein paar" Neuronen vorhanden sind. (Ich glaube jedoch, dass niemand vollständig versteht, warum dies der Fall ist.) Ich gebe hier ein Beispiel im Zusammenhang mit dem XOR-Problem: Werden meine Iterationen nicht benötigt, um NN für XOR mit MSE <0,001 zu hoch zu trainieren? .

  • Wenn Sie die Anzahl der ausgeblendeten Ebenen auswählen, lernt das Netzwerk eine Abstraktion aus den Rohdaten. Deep Learning ist heutzutage der letzte Schrei, und Netzwerke mit einer großen Anzahl von Ebenen haben beeindruckende Ergebnisse gezeigt. Das Hinzufügen zu vieler versteckter Ebenen kann jedoch zu einer Überanpassung des Risikos führen oder die Optimierung des Netzwerks erheblich erschweren.

  • Die Wahl einer cleveren Netzwerkverkabelung kann einen Großteil der Arbeit für Sie erledigen. Ist Ihre Datenquelle für spezielle Netzwerkarchitekturen geeignet? Faltungs-Neuronale Netze können beeindruckende Ergebnisse bei "strukturierten" Datenquellen, Bild- oder Audiodaten erzielen. Wiederkehrende neuronale Netze eignen sich gut für sequenzielle Datentypen wie natürliche Sprache oder Zeitreihendaten. Verbleibende Verbindungen können tiefe Feed-Forward-Netzwerke verbessern.

Neuronales Netzwerktraining ist wie das Öffnen von Schlössern

Um hochmoderne oder nur gute Ergebnisse zu erzielen, müssen Sie alle Teile so konfiguriert haben, dass sie gut zusammenarbeiten . Das Einrichten einer neuronalen Netzwerkkonfiguration, die tatsächlich lernt, ähnelt dem Aufheben eines Schlosses: Alle Teile müssen genau richtig ausgerichtet sein. Ebenso wenig, wie es nicht ausreicht, einen einzelnen Becher am richtigen Ort zu haben, reicht es auch nicht aus, nur die Architektur oder nur den Optimierer korrekt einzurichten.

Das Einstellen der Konfigurationsoptionen ist nicht so einfach, als dass gesagt wird, dass eine Art der Konfigurationsauswahl (z. B. Lernrate) mehr oder weniger wichtig ist als eine andere (z. B. Anzahl der Einheiten), da alle diese Auswahlmöglichkeiten mit allen anderen Auswahlmöglichkeiten interagieren Wahl kann in Kombination mit einer anderen Wahl gut tun, die anderswo getroffen wird .

Dies ist eine nicht vollständige Liste der Konfigurationsoptionen, bei denen es sich nicht nur um Regularisierungsoptionen oder numerische Optimierungsoptionen handelt.

Alle diese Themen sind aktive Forschungsbereiche.

Eine nicht konvexe Optimierung ist schwierig

Die objektive Funktion eines neuronalen Netzwerks ist nur konvex, wenn es keine versteckten Einheiten gibt, alle Aktivierungen linear sind und die Entwurfsmatrix den vollen Rang hat - da diese Konfiguration identisch zu einem normalen Regressionsproblem ist.

In allen anderen Fällen ist das Optimierungsproblem nicht konvex und die nicht konvexe Optimierung ist schwierig. Die Herausforderungen beim Training neuronaler Netze sind bekannt (siehe: Warum ist es schwierig, tiefe neuronale Netze zu trainieren? ). Darüber hinaus haben neuronale Netze eine sehr große Anzahl von Parametern, was uns auf Methoden erster Ordnung beschränkt (siehe: Warum wird Newtons Methode beim maschinellen Lernen nicht häufig verwendet? ). Dies ist ein sehr aktives Forschungsgebiet.

  • Wenn Sie die Lernrate zu groß einstellen, läuft die Optimierung auseinander, da Sie von einer Seite des "Canyons" zur anderen springen. Wenn Sie diesen Wert zu klein einstellen, können Sie keine wirklichen Fortschritte erzielen, und möglicherweise kann das mit SGD verbundene Rauschen Ihre Gradientenschätzungen überfordern.

  • Gradient Clipping skaliert die Norm des Gradienten neu, wenn sie einen bestimmten Schwellenwert überschreitet. Früher dachte ich, dass dies ein Set-and-Forget-Parameter ist, normalerweise 1.0, aber ich fand heraus, dass ich ein LSTM-Sprachmodell dramatisch verbessern kann, indem ich es auf 0.25 setze. Ich weiß nicht warum das so ist.

  • Die Planung der Lernrate kann die Lernrate im Laufe des Trainings verringern. Meiner Erfahrung nach ähnelt der Versuch, die Zeitplanung zu verwenden, einem regulären Ausdruck : Er ersetzt ein Problem ("Wie lerne ich, nach einer bestimmten Epoche fortzufahren?") Durch zwei Probleme ("Wie lerne ich, nach einer bestimmten Epoche fortzufahren") "und" Wie wähle ich einen guten Zeitplan aus? "). Andere Leute bestehen darauf, dass Terminplanung unerlässlich ist. Ich lasse dich entscheiden.

  • Die Wahl einer guten Minibatch-Größe kann den Lernprozess indirekt beeinflussen, da ein größerer Minibatch tendenziell eine geringere Varianz ( ) aufweist als ein kleinerer Minibatch. Sie möchten, dass der Mini-Batch groß genug ist, um über die Richtung des Gradienten zu informieren, aber klein genug, damit SGD Ihr Netzwerk regulieren kann.

  • Es gibt eine Reihe von Varianten für den stochastischen Gradientenabstieg, die Impulse, adaptive Lernraten, Nesterov-Aktualisierungen usw. verwenden, um die Vanille-SGD zu verbessern. Das Entwerfen eines besseren Optimierers ist ein sehr aktives Forschungsgebiet. Einige Beispiele:

  • Als es herauskam, stieß der Adam-Optimierer auf großes Interesse. Einige neuere Forschungen haben jedoch herausgefunden, dass SGD mit Impuls adaptive Gradientenmethoden für neuronale Netze übertreffen kann. " Der Grenzwert adaptiver Gradientenmethoden im maschinellen Lernen " von Ashia C. Wilson, Rebecca Roelofs, Mitchell Stern, Nathan Srebro und Benjamin Recht

  • Andererseits schlägt dieses kürzlich erschienene Papier einen neuen Optimierer für adaptive Lernraten vor, der die Lücke zwischen adaptiven Methoden und SGD mit Schwung schließen soll. " Schließung der Generalisierungslücke adaptiver Gradientenmethoden beim Training tiefer neuronaler Netze " von Jinghui Chen, Quanquan Gu

    Es wurde beobachtet, dass adaptive Gradientenmethoden, die historische Gradienteninformationen verwenden, um die Lernrate automatisch anzupassen, eine schlechtere als die stochastische Gradientenabnahme (SGD) mit Momentum beim Trainieren tiefer neuronaler Netze verallgemeinern. Daher ist es ein offenes Problem, wie die Generalisierungslücke bei adaptiven Gradientenmethoden geschlossen werden kann. In dieser Arbeit zeigen wir, dass adaptive Gradientenmethoden wie Adam, Amsgrad manchmal "überangepasst" sind. Wir entwerfen einen neuen Algorithmus namens Partially Adaptive Momentum Estimation Method (Padam), der Adam / Amsgrad mit SGD vereint, um das Beste aus beiden Welten zu erzielen. Experimente mit Standardbenchmarks zeigen, dass Padam eine schnelle Konvergenzrate wie Adam / Amsgrad aufrechterhalten kann, während es beim Training tiefer neuronaler Netze Generalisierung und SGD durchführt.

Normalisierung

Der Umfang der Daten kann beim Training einen großen Unterschied machen.

  • Bevor Sie Daten einem neuronalen Netzwerk präsentieren, können Sie das Training verbessern , indem Sie die Daten so standardisieren , dass sie einen Mittelwert von 0 und eine Einheitsvarianz aufweisen oder in einem kleinen Intervall wie . Dies stellt eine Vorkonditionierung dar und beseitigt die Auswirkung, die eine Auswahl in Einheiten auf die Netzwerkgewichte hat. Beispielsweise repräsentieren Länge in Millimetern und Länge in Kilometern dasselbe Konzept, sind jedoch unterschiedlich skaliert. Die genauen Details zur Standardisierung der Daten hängen davon ab, wie Ihre Daten aussehen.[0.5,0.5]

  • Durch die Normalisierung der Schichten kann das Netzwerktraining verbessert werden, indem der Mittelwert und die Standardabweichung für die Neuronenaktivierungen beibehalten werden. Es ist nicht klar, warum dies der Ausbildung hilft, und es bleibt ein aktives Forschungsgebiet.

Regulierung

Die Auswahl und Optimierung der Netzwerk-Regularisierung ist ein wesentlicher Bestandteil der Erstellung eines Modells, das sich gut verallgemeinern lässt (dh ein Modell, das nicht zu den Trainingsdaten passt). Zu der Zeit, in der Ihr Netzwerk Probleme hat, den Verlust der Trainingsdaten zu verringern - wenn das Netzwerk nicht lernt - kann die Regularisierung das Problem verdecken.

Wenn mein Netzwerk nicht lernt, deaktiviere ich alle Regularisierungen und stelle sicher, dass das nicht regularisierte Netzwerk ordnungsgemäß funktioniert. Dann füge ich jedes Regularisierungsstück zurück und überprüfe, ob jedes auf dem Weg funktioniert.

Diese Taktik kann genau bestimmen, wo eine Regularisierung möglicherweise schlecht eingestellt ist. Einige Beispiele sind

Führen Sie ein Logbuch der Experimente

Wenn ich ein neuronales Netzwerk einrichte, codiere ich keine Parametereinstellungen fest. Stattdessen mache ich das in einer Konfigurationsdatei (z. B. JSON), die gelesen und zum Auffüllen von Netzwerkkonfigurationsdetails zur Laufzeit verwendet wird. Ich behalte all diese Konfigurationsdateien. Wenn ich Parameter ändere, erstelle ich eine neue Konfigurationsdatei. Schließlich füge ich als Kommentar alle epochenbezogenen Verluste für Training und Validierung hinzu.

Der Grund, warum ich so besessen davon bin, alte Ergebnisse beizubehalten, ist, dass es sehr einfach ist, zurück zu gehen und frühere Experimente zu wiederholen. Es schützt auch davor, das gleiche Dead-End-Experiment fälschlicherweise zu wiederholen. Psychologisch gesehen können Sie auch zurückblicken und beobachten: "Nun, das Projekt ist vielleicht nicht dort, wo ich es heute haben möchte, aber ich mache Fortschritte im Vergleich zu dem, wo ich vor Wochen war."k

Als Beispiel wollte ich etwas über LSTM-Sprachmodelle lernen, deshalb habe ich mich für einen Twitter-Bot entschieden, der als Antwort auf andere Twitter-Benutzer neue Tweets schreibt. Daran habe ich in meiner Freizeit gearbeitet, zwischen Schule und Beruf. Es dauerte ungefähr ein Jahr, und ich durchlief über 150 verschiedene Modelle, bevor ich zu einem Modell kam, das genau das tat, was ich wollte: einen neuen Text in englischer Sprache zu generieren, der (irgendwie) Sinn ergibt. (Ein wesentlicher Knackpunkt und ein Grund dafür, dass so viele Versuche unternommen wurden, ist, dass es nicht ausreichte, nur einen geringen Verlust außerhalb der Stichprobe zu erzielen, da frühe Modelle mit geringem Verlust es geschafft hatten, die Trainingsdaten zu speichern.) es wurden also nur wichtige Textblöcke wörtlich als Antwort auf Eingabeaufforderungen reproduziert - es waren einige Anpassungen erforderlich, um das Modell spontaner zu gestalten und dennoch einen geringen Verlust zu erzielen.)

Sycorax
quelle
11
Es gibt viele gute Ratschläge. Es ist interessant, wie viele Ihrer Kommentare den Kommentaren ähneln, die ich in Bezug auf das Debuggen der Schätzung von Parametern oder Vorhersagen für komplexe Modelle mit MCMC-Stichprobenschemata abgegeben habe (oder die andere gesehen haben). (Beispielsweise scheint der Code zu funktionieren, wenn er nicht korrekt implementiert ist.)
Glen_b
11
@Glen_b Ich denke, dass die besten Methoden für das Codieren in den meisten Statistiken / Lehrplänen für maschinelles Lernen nicht genug Beachtung finden, weshalb ich diesen Punkt so stark betont habe. Ich habe eine Reihe von NN-Posts gesehen, in denen OP einen Kommentar hinterlassen hat: "Oh, ich habe einen Fehler gefunden, jetzt funktioniert er."
Sycorax,
7
Ich unterrichte einen Programmierkurs für Data Science in Python, und am ersten Tag führen wir Funktionen und Unit-Tests als primäre Konzepte durch. Kampf gegen den guten Kampf.
Matthew Drury
8
+1 für "Alle Codierungen debuggen". Ich bin erstaunt, wie viele Poster auf SO zu denken scheinen, dass das Codieren eine einfache Übung ist, die nur wenig Aufwand erfordert. die erwarten, dass ihr Code beim ersten Ausführen korrekt funktioniert; und wer scheint nicht in der Lage zu sein, fortzufahren, wenn dies nicht der Fall ist. Das Lustige ist, dass sie zur Hälfte Recht haben: Das Codieren ist einfach - aber das Programmieren ist schwierig.
Bob Jarvis
41

Die Antworten sind großartig und ich wollte ein paar "Sanity Checks" hinzufügen, die mir in der Vergangenheit sehr geholfen haben.

1) Trainieren Sie Ihr Modell an einem einzelnen Datenpunkt. Wenn dies funktioniert, trainieren Sie es an zwei Eingängen mit unterschiedlichen Ausgängen.

Dies bestätigt einige Dinge. Erstens zeigt es Ihnen schnell, dass Ihr Modell in der Lage ist, zu lernen, indem es überprüft, ob Ihr Modell Ihre Daten überpasst. In meinem Fall mache ich ständig dumme Fehler, wenn ich Dense(1,activation='softmax')vs Dense(1,activation='sigmoid')für binäre Vorhersagen mache , und der erste gibt Müllergebnisse.

Wenn Ihr Modell nicht in der Lage ist, einige Datenpunkte zu überfüllen, ist es entweder zu klein (was im heutigen Zeitalter unwahrscheinlich ist) oder es stimmt etwas mit der Struktur oder dem Lernalgorithmus nicht.

2) Achten Sie auf Ihren Anfangsverlust.

Fortsetzen des binären Beispiels: Wenn Ihre Daten 30% 0 und 70% 1 sind, liegt der erwartete Anfangsverlust bei . Dies liegt daran, dass Ihr Modell fast zufällig raten sollte.L=0.3ln(0.5)0.7ln(0.5)0.7

Oft werden Sie einen anfänglichen Verlust von etwas Lächerlichem sehen, wie z. B. 6.5. Konzeptionell bedeutet dies, dass Ihre Ausgabe stark gesättigt ist, zum Beispiel in Richtung 0. Zum Beispiel . Wenn Sie also einen Verlust sehen, der größer als 1 ist, ist es wahrscheinlich Ihr Modell ist sehr schief. Dies geschieht normalerweise, wenn die Gewichte Ihres neuronalen Netzwerks nicht richtig ausgeglichen sind, insbesondere näher am Softmax / Sigmoid. Dies würde Ihnen also sagen, ob Ihre Initialisierung schlecht ist.0.3ln(0.99)0.7ln(0.01)=3.2

Sie können dies weiter untersuchen, indem Sie Ihr Modell anhand einiger tausend Beispiele vorhersagen lassen und dann die Ausgaben histogrammieren. Dies ist besonders nützlich, um zu überprüfen, ob Ihre Daten korrekt normalisiert sind. Wenn Sie beispielsweise erwarten, dass Ihre Ausgabe stark in Richtung 0 verschoben ist, ist es möglicherweise eine gute Idee, Ihre erwarteten Ausgaben (Ihre Trainingsdaten) zu transformieren, indem Sie die Quadratwurzeln der erwarteten Ausgabe verwenden. Dies vermeidet Gradientenprobleme bei gesättigten Sigmoiden am Ausgang.

3) Verallgemeinern Sie Ihre Modellausgaben zum Debuggen

Stellen Sie sich beispielsweise vor, Sie verwenden einen LSTM, um Vorhersagen aus Zeitreihendaten zu treffen. Vielleicht interessiert Sie in Ihrem Beispiel nur die neueste Vorhersage, sodass Ihr LSTM einen einzelnen Wert und keine Sequenz ausgibt. Schalten Sie den LSTM um, um bei jedem Schritt Vorhersagen zurückzugeben (in Keras ist dies return_sequences=True). Dann können Sie nach jedem Schritt einen Blick auf Ihre Hidden-State-Ausgänge werfen und sicherstellen, dass sie sich tatsächlich unterscheiden. Eine Anwendung davon ist, um sicherzustellen, dass beim Maskieren Ihrer Sequenzen (dh beim Auffüllen mit Daten, um diese gleich lang zu machen) das LSTM Ihre maskierten Daten korrekt ignoriert. Ohne Verallgemeinerung Ihres Modells werden Sie dieses Problem nie finden .

4) Betrachten Sie die einzelnen Schichten

Tensorboard bietet eine nützliche Möglichkeit zur Visualisierung Ihrer Ebenenausgaben . Dies kann dazu beitragen, sicherzustellen, dass die Ein- / Ausgänge in jeder Ebene ordnungsgemäß normalisiert sind. Es kann auch fehlerhafte Aktivierungen abfangen. Sie können Layer-Ausgaben in Keras auch nach einer Reihe von Vorhersagen abfragen und dann nach Layern suchen, bei denen die Aktivierungen verdächtig verzerrt sind (entweder alle 0 oder alle ungleich Null).

5) Erstellen Sie zuerst ein einfacheres Modell

Sie haben entschieden, dass der beste Ansatz zur Lösung Ihres Problems die Verwendung eines CNN in Kombination mit einem Bounding-Box-Detektor ist, der Bildausschnitte weiterverarbeitet und dann alles mit einem LSTM kombiniert. Es dauert nur 10 Minuten, bis Ihre GPU Ihr Modell initialisiert hat.

Erstellen Sie stattdessen einen Stapel gefälschter Daten (dieselbe Form) und zerlegen Sie Ihr Modell in Komponenten. Stellen Sie dann anstelle jeder Komponente Dummy-Modelle her (Ihre "CNN" könnte nur eine einzige 2x2-Faltung mit 20 Schritten sein, die LSTM mit nur 2 versteckten Einheiten). Auf diese Weise können Sie sicherstellen, dass Ihre Modellstruktur korrekt ist und keine unnötigen Probleme auftreten. Ich hatte eine Weile Probleme mit einem solchen Modell, und als ich eine einfachere Version ausprobierte, stellte ich fest, dass eine der Ebenen aufgrund eines Keras-Fehlers nicht richtig maskiert wurde. Sie können interne Modellebenen einfach (und schnell ) abfragen und prüfen, ob Sie Ihr Diagramm korrekt eingerichtet haben.

6) Standardisieren Sie Ihre Vorverarbeitungs- und Paketversionen

Insbesondere neuronale Netze reagieren sehr empfindlich auf kleine Änderungen Ihrer Daten. Als ein Beispiel sind zwei populäre Bildladepakete cv2und PIL. Durch das Öffnen eines JPEGs werden in beiden Paketen leicht unterschiedliche Bilder erstellt. Die Unterschiede sind normalerweise sehr gering, aber Sie werden gelegentlich aufgrund solcher Dinge einen Rückgang der Modellleistung feststellen. Außerdem wird das Debuggen zum Albtraum: Sie haben während des Trainings eine Validierungsbewertung erhalten und später verwenden Sie einen anderen Loader und erhalten unterschiedliche Genauigkeit für denselben verdammten Datensatz.

Wenn Sie also ein Modell von github herunterladen, achten Sie genau auf die Vorverarbeitung. Welche Image Loader verwenden sie? Welche Bildvorverarbeitungsroutinen verwenden sie? Welche Interpolation wird beim Ändern der Bildgröße verwendet? Ändern sie zuerst die Größe und normalisieren dann das Bild? Oder umgekehrt? Wie ist die Kanalreihenfolge für RGB-Bilder?

Die sicherste Methode zum Standardisieren von Paketen besteht darin, eine requirements.txtDatei zu verwenden, in der alle Pakete bis auf die keras==2.1.5Versionsnummern genau wie beim Setup Ihres Trainingssystems aufgeführt sind. Theoretisch sollte die Verwendung von Docker zusammen mit der gleichen GPU wie auf Ihrem Trainingssystem dann zu den gleichen Ergebnissen führen.

Alex R.
quelle
7
(+1) Die Überprüfung des anfänglichen Verlusts ist ein großartiger Vorschlag. Ich bedaure, dass ich es aus meiner Antwort herausgelassen habe.
Sycorax
7
Es ist eine hervorragende Idee, sicherzustellen, dass Ihr Modell überarbeitet werden kann. Ich bin es so gewohnt, Überanpassung als Schwäche zu betrachten, dass ich nie explizit gedacht habe (bis Sie es erwähnt haben), dass die Fähigkeit zur Überanpassung tatsächlich eine Stärke ist.
John Coleman
15

Trainieren Sie zunächst kein neuronales Netz!

Alle Antworten sind großartig, aber es gibt einen Punkt, der erwähnt werden sollte: Gibt es etwas, das Sie aus Ihren Daten lernen können? (was als eine Art Test angesehen werden könnte).

Wenn die Bezeichnung, die Sie vorhersagen möchten, nicht von Ihren Funktionen abhängt, kann sich der Trainingsverlust wahrscheinlich nur schwer reduzieren.

Beginnen Sie stattdessen mit der Kalibrierung einer linearen Regression, einer zufälligen Gesamtstruktur (oder einer beliebigen Methode, deren Anzahl von Hyperparametern niedrig ist und deren Verhalten Sie verstehen können).

Wenn Sie mit diesen Modellen eine anständige Leistung erzielen (besser als zufällige Schätzungen), können Sie mit der Optimierung eines neuronalen Netzwerks beginnen (und die Antwort von @Sycorax löst die meisten Probleme).

RUser4512
quelle
5
Ich stimme dieser Antwort zu. Neuronale Netze und andere Formen von ML sind "gerade jetzt so heiß". Oft werden die einfacheren Formen der Regression übersehen. Wenn es darum geht, Ihr Modell zu erklären, kommt jemand und fragt: "Wie wirkt sich auf das Ergebnis aus?" und alles, was Sie tun können, ist Ihre Schultern zucken. Schauen Sie sich nur nach Lösungen für maschinelles Lernen um, wenn Sie mit den einfacheren Techniken gescheitert sind. xk
Ingolifs
11

Der grundlegende Workflow für das Training eines NN / DNN-Modells ist im Kern mehr oder weniger immer derselbe:

  1. Definieren Sie die NN-Architektur (wie viele Schichten, welche Art von Schichten, die Verbindungen zwischen Schichten, die Aktivierungsfunktionen usw.)

  2. Lesen Sie Daten aus einer bestimmten Quelle (dem Internet, einer Datenbank, einer Reihe lokaler Dateien usw.), sehen Sie sich einige Beispiele an (um sicherzustellen, dass der Import erfolgreich war) und führen Sie bei Bedarf eine Datenbereinigung durch. Dieser Schritt ist nicht so einfach, wie die Leute normalerweise annehmen. Der Grund dafür ist, dass wir bei DNNs normalerweise mit riesigen Datenmengen arbeiten, die mehrere Größenordnungen größer sind als wir es gewohnt sind, wenn wir mehr standardisierte nichtlineare parametrische statistische Modelle verwenden (theoretisch gehören NNs zu dieser Familie).

  3. Normalisieren oder standardisieren Sie die Daten auf irgendeine Weise. Da NNs nichtlineare Modelle sind, kann die Normalisierung der Daten nicht nur die numerische Stabilität, sondern auch die Trainingszeit und die NN-Ausgaben beeinflussen (eine lineare Funktion wie die Normalisierung pendelt nicht mit einer nichtlinearen hierarchischen Funktion).

  4. Teilen Sie die Daten in Training / Validierung / Test-Set oder in mehreren Falten, wenn Sie die Kreuzvalidierung verwenden.

  5. Trainieren Sie das neuronale Netzwerk und kontrollieren Sie gleichzeitig den Verlust des Validierungssatzes. Hier können Sie die aufregenden Freuden der nicht-konvexen Optimierung genießen, bei der Sie nicht wissen, ob eine Lösung vorhanden ist, ob mehrere Lösungen vorhanden sind, welche die beste (n) Lösung (en) in Bezug auf Generalisierungsfehler ist (n) und wie nahe Sie daran sind es. Der Vergleich zwischen Trainingsverlust- und Validierungsverlustkurve führt Sie natürlich, aber unterschätzen Sie nicht die harte Einstellung von NNs (und insbesondere DNNs): Sie zeigen häufig einen (möglicherweise langsam) abnehmenden Trainings- / Validierungsverlust, selbst wenn Sie dies getan haben lähmende Fehler in Ihrem Code.

  6. Überprüfen Sie die Genauigkeit des Testsatzes und erstellen Sie einige diagnostische Diagramme / Tabellen.

  7. Kehren Sie zu Punkt 1 zurück, da die Ergebnisse nicht gut sind. Wiederholen Sie die Übelkeit .

Natürlich werden sich die Details je nach Anwendungsfall ändern, aber angesichts dieser groben Leinwand können wir uns überlegen, was mit größerer Wahrscheinlichkeit schief geht.

Grundlegende Architekturprüfungen

Dies kann zu Problemen führen. Normalerweise mache ich diese vorläufigen Überprüfungen:

  • Suchen Sie nach einer einfachen Architektur, die für Ihr Problem gut geeignet ist (z. B. MobileNetV2 bei der Klassifizierung von Bildern), und wenden Sie eine geeignete Initialisierung an (auf dieser Ebene ist in der Regel eine zufällige Initialisierung ausreichend). Wenn dies Ihre Daten korrekt trainiert, wissen Sie zumindest, dass der Datensatz keine offensichtlichen Probleme enthält. Wenn Sie keine einfache, getestete Architektur finden, die in Ihrem Fall funktioniert, stellen Sie sich eine einfache Grundlinie vor . Zum Beispiel ein Naive Bayes-Klassifikator zur Klassifizierung (oder auch nur zur Klassifizierung der am häufigsten verwendeten Klasse) oder ein ARIMA-Modell zur Vorhersage von Zeitreihen

  • Komponententests erstellen. Die Nichtbeachtung (und die Verwendung des verdammten Jupyter-Notizbuchs) sind normalerweise die Hauptursachen für Probleme im NN-Code, die ich überprüfen muss, insbesondere wenn das Modell in der Produktion bereitgestellt werden soll. Da die am besten bewertete Antwort bereits Unit-Tests behandelt hat, möchte ich hinzufügen, dass es eine Bibliothek gibt, die die Entwicklung von Unit-Tests für NN unterstützt (leider nur in Tensorflow).

Trainingsset

Überprüfen Sie Ihre Eingabedaten. Überprüfen Sie, ob Sie beispielsweise die Beschriftungen für Trainings- und Test-Sets vertauscht haben (mir ist das einmal passiert -___-) oder ob Sie die falsche Datei importiert haben. Schauen Sie sich einige Eingabebeispiele und die zugehörigen Beschriftungen an und vergewissern Sie sich, dass sie sinnvoll sind. Stellen Sie sicher, dass die normalisierten Daten wirklich normalisiert sind (sehen Sie sich ihren Bereich an). Reale Datasets sind außerdem verschmutzt: Bei der Klassifizierung kann es zu einem starken Etikettenrauschen kommen (Proben mit falscher Klassenbezeichnung), oder bei der Vorhersage multivariater Zeitreihen fehlen in einigen Zeitreihenkomponenten möglicherweise viele Daten ( Ich habe Zahlen von bis zu 94% für einige der Eingaben gesehen).

Die Reihenfolge, in der der Trainingssatz während des Trainings dem Netz zugeführt wird, kann sich auswirken. Versuchen Sie eine zufällige Mischung des Trainingssatzes ( ohne die Zuordnung zwischen Eingängen und Ausgängen zu unterbrechen ) und prüfen Sie, ob der Trainingsverlust abnimmt.

Schließlich können Sie am besten überprüfen, ob Probleme mit dem Trainingssatz vorliegen, indem Sie einen anderen Trainingssatz verwenden. Wenn Sie eine Bildklassifizierung durchführen, verwenden Sie anstelle der von Ihnen gesammelten Bilder einen Standarddatensatz wie CIFAR10 oder CIFAR100 (oder ImageNet, wenn Sie es sich leisten können, darauf zu trainieren). Diese Datensätze sind gut getestet: Wenn Ihr Trainingsverlust hier, aber nicht in Ihrem ursprünglichen Datensatz, sinkt, haben Sie möglicherweise Probleme mit dem Datensatz.

Machen Sie die Goldenen Tests

Es gibt zwei Tests, die ich Golden Tests nenne und die sehr nützlich sind, um Probleme in einem NN zu finden, das nicht trainiert:

  • Reduzieren Sie das Trainingsset auf 1 oder 2 Proben und trainieren Sie dies. Der NN sollte den Trainingssatz sofort überfüllen und sehr schnell eine Genauigkeit von 100% des Trainingssatzes erreichen, während die Genauigkeit des Validierungs- / Testsatzes 0% beträgt. Wenn dies nicht der Fall ist, enthält Ihr Code einen Fehler.

  • der gegenteilige test: du behältst das komplette trainingsset bei, mischst aber die etiketten. Die einzige Möglichkeit, wie der NN jetzt lernen kann, ist das Speichern des Trainingssatzes, was bedeutet, dass der Trainingsverlust sehr langsam abnimmt, während der Testverlust sehr schnell zunimmt. Insbesondere sollten Sie den zufälligen Zufallsverlust auf dem Testsatz erreichen . Das heißt, wenn Sie 1000 Klassen haben, sollten Sie eine Genauigkeit von 0,1% erreichen. Wenn Sie keinen Unterschied zwischen dem Trainingsverlust vor und nach dem Mischen der Etiketten sehen, bedeutet dies, dass Ihr Code fehlerhaft ist (denken Sie daran, dass wir die Etiketten des Trainingssatzes im vorherigen Schritt bereits überprüft haben).

Überprüfen Sie, ob Ihre Trainingsmetrik sinnvoll ist

Genauigkeit (0-1 Verlust) ist eine bescheidene Messgröße, wenn Sie ein starkes Klassenungleichgewicht haben. Probieren Sie etwas Bedeutsameres aus, wie beispielsweise den Verlust der Kreuzentropie: Sie möchten nicht nur richtig klassifizieren, sondern Sie möchten auch mit hoher Genauigkeit klassifizieren.

Bring die großen Waffen raus

Wenn nichts geholfen hat, ist es jetzt an der Zeit, mit Hyperparametern zu experimentieren. Dies ist leicht der schlechteste Teil des NN-Trainings, aber dies sind gigantische, nicht identifizierbare Modelle, deren Parameter durch Lösen einer nicht konvexen Optimierung angepasst werden, sodass diese Iterationen häufig nicht vermieden werden können.

  • Probieren Sie verschiedene Optimierer aus: SGD trainiert langsamer, führt aber zu einem geringeren Generalisierungsfehler, während Adam schneller trainiert, aber der Testverlust bleibt auf einem höheren Wert stehen
  • Versuchen Sie, die Stapelgröße zu verringern
  • Erhöhen Sie zunächst die Lernrate und verringern Sie sie dann oder verwenden Sie eine zyklische Lernrate
  • Ebenen hinzufügen
  • füge versteckte Einheiten hinzu
  • Entfernen Sie die Regularisierung schrittweise (wechseln Sie möglicherweise die Chargennorm für einige Schichten). Der Trainingsverlust sollte jetzt abnehmen, aber der Testverlust kann zunehmen.
  • Visualisieren Sie die Verteilung der Gewichte und Vorspannungen für jede Ebene. Ich musste nie hierher kommen, aber wenn Sie BatchNorm verwenden, würden Sie ungefähr normale Standarddistributionen erwarten. Sehen Sie, ob die Norm der Gewichte mit den Epochen abnorm ansteigt.
  • Wenn während des Trainings ein Fehler auftritt , googeln Sie diesen Fehler . Ich habe einen Morgen verschwendet, als ich versucht habe, eine perfekt funktionierende Architektur zu reparieren, nur um herauszufinden, dass die Version von Keras, die ich installiert hatte, fehlerhafte Multi-GPU-Unterstützung hatte und ich sie aktualisieren musste. Manchmal musste ich das Gegenteil tun (Downgrade einer Paketversion).
  • aktualisiere deinen Lebenslauf und suche einen anderen Job :-)
DeltaIV
quelle
+1, aber "verdammtes Jupyter-Notizbuch"? Möchtest du das kommentieren? :)
Amöbe
2
Hier ist , warum ich Jupyter Notebooks hassen . TL; DR: Verborgener Zustand, Unterschiede sind ein Schmerz, Sicherheitsprobleme und fördern schlechte Programmierpraktiken, z. B. das Nichtverwenden von Unit- / Regressions- / Integrationstests. NNs zu trainieren ist schon schwer genug, ohne dass man die Grundlagen der Programmierung vergisst.
DeltaIV
2
Ich bin möglicherweise zu negativ, aber ehrlich gesagt hatte ich genug damit, dass Leute Jupyter Notebooks von GitHub klonen. Ich dachte, es wäre nur eine Frage von Minuten, den Code an ihren Anwendungsfall anzupassen, und beschwerte mich dann, dass nichts funktioniert. Um Himmels willen, besorgen Sie sich eine echte IDE wie PyCharm oder VisualStudio Code und erstellen Sie einen gut strukturierten Code, anstatt ein Notebook zu kochen! Besonders wenn Sie vorhaben, das Modell in die Produktion zu schicken, wird dies die Sache viel einfacher machen.
DeltaIV
2
Lol. 'Jupyter Notebook' und 'Unit Testing' sind antikorreliert.
Sycorax
2
(+1) Dies ist eine gute Zusammenfassung. Die Vorschläge für Randomisierungstests sind wirklich großartige Möglichkeiten, an fehlerhafte Netzwerke heranzukommen.
Sycorax
6

Wenn das Modell nicht lernt, besteht eine gute Chance, dass Ihre Backpropagation nicht funktioniert. Aber es gibt so viele Dinge, die mit einem Black-Box-Modell wie Neural Network schief gehen können. Es gibt viele Dinge, die Sie überprüfen müssen. Ich denke, Sycorax und Alex liefern beide sehr gute umfassende Antworten. Ich möchte nur eine Technik hinzufügen, die noch nicht besprochen wurde.

ϵ

Anthony Lei
quelle