Ich versuche, ein großes Modell (tiefes Netz mit Kaffee) mit stochastischem Gradientenabstieg (SGD) zu trainieren.
Das Problem ist, dass ich durch meine GPU-Speicherkapazität eingeschränkt bin und daher keine großen Mini-Batches für jede stochastische Gradientenschätzung verarbeiten kann.
Wie kann ich diese Instabilität in meinem Training überwinden?
Ein Gedanke, den ich hatte, war, Momentum zu verwenden und es auf einen höheren Wert zu setzen, als der Standardwert normalerweise ist. Ist das eine gültige Strategie?
Für diejenigen unter Ihnen, die zufällig Caffe verwenden , könnte es interessant sein zu wissen, dass Caffe die Gradientenakkumulation über Mini-Batches bereits implementiert hat (wie von Indie Al vorgeschlagen ). Sie müssen einfach definieren , iter_size
in der 'solver.prototxt'
.
Dies kann auch in Pytorch erfolgen . Siehe diesen Beitrag zum Beispiel.
Antworten:
Ich glaube, dass die SGD-Abstiegsrichtung bei einer kleinen Stapelgröße eine sehr verrauschte Schätzung der "wahren" Abstiegsrichtung wird (dh wenn wir sie für den gesamten Trainingssatz ausgewertet haben). Bei einer kleinen Chargengröße bin ich mir nicht sicher, wie viel eine Erhöhung des Impulses helfen würde, da sich der Impuls in sehr lauten Richtungen ansammeln würde. Aber ich könnte mich irren, vielleicht ist Ihr Optimierungsproblem gut genug gestellt, wo dies funktionieren könnte.
Wenn Sie nicht nach "State of the Art" -Ergebnissen streben, besteht eine Option für natürliche Bilddaten darin, die Größe der Bilder zu ändern. Ich denke tatsächlich, dass Modulo, das der Elite-Benchmarking-Leistung nachjagt, natürliche Bilder viele skalierungsinvariante Eigenschaften haben und viele ihrer semantischen Merkmale unter vernünftigen Skalierungstransformationen ziemlich robust sind. Dies würde einen Teil des GPU-Speichers entlasten und es Ihnen ermöglichen, Ihre Stapelgröße zu erhöhen, und Ihre SGD-Abstiegsrichtungen wären bessere Schätzungen der Abstiegsrichtungen.
Wenn Sie es mit einer trennbaren Verlustfunktion wie der negativen Log-Wahrscheinlichkeit zu tun haben, können wir die Tatsache ausnutzen, dass der Gradient einer großen Charge lediglich die Summe / der Durchschnitt der Gradienten ihrer Teilpartien ist. Zum Beispiel, wenn unsere Chargengröße istB. können wir Gradienten einer Super-Batch-Größe berechnen B K. Indem wir die Stapel wie gewohnt durchlaufen und jeden Stapelgradienten berechnen, aber anstatt die Gewichte zu aktualisieren, speichern wir jeden Gradienten in einer laufenden Summe oder einem Durchschnitt. Wenn wir angemessen mitteln, berechnen wir den genauen Gradienten für dieB K. Größe Super Batch. Wir führen dann nach jedem die Gewichtsaktualisierung durchK. -te Charge wurde verarbeitet.
Wir werden das genau berechnenB K. Batch-Gradienten durch Serialisierung der Berechnung wie oben beschrieben. Es gibt nur minimalen zusätzlichen Rechen- oder Speicheraufwand. Sie müssen lediglich den Minibatch-Iterator so ändern, dass er die Super-Batch-Serialisierung und den Gradienten-Cache enthält.
quelle
Kürzlich bin ich auf eine interessante Arbeit gestoßen:
Samuel L. Smith, Pieter-Jan Kindermans, Chris Ying und Quoc V. Le verringern die Lernrate nicht, erhöhen die Stapelgröße (ICLR 2018).
Diese Arbeit zeigt einen direkten Zusammenhang zwischen Stapelgröße und Lernrate. Insbesondere hat das Verringern der Lernrate den gleichen Effekt wie das Erhöhen der Stapelgröße und umgekehrt.
Wenn man ihre Schlussfolgerung auf das Äußerste bringt, könnte man in Betracht ziehen, die Chargengröße zu verringern und durch eine Erhöhung der Lernrate zu kompensieren.
Ich habe es aber noch nicht ausprobiert.
quelle