Umgang mit kleinen Losgrößen im SGD-Training

7

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_sizein der 'solver.prototxt'.

Dies kann auch in Pytorch erfolgen . Siehe diesen Beitrag zum Beispiel.

Shai
quelle
Bitte nicht überkreuzen. Wählen Sie die Site aus, auf der Sie den anderen Thread veröffentlichen und löschen möchten.
Gung - Reinstate Monica
@gung Derzeit erhalte ich auf beiden Seiten keine Antworten. Sobald ich auf einer der Websites eine Antwort erhalte, werde ich sie von der anderen entfernen.
Shai
@gung hier einen Puls bekommen, habe ich die ursprüngliche Frage für SO entfernt.
Shai

Antworten:

4

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 istBkönnen wir Gradienten einer Super-Batch-Größe berechnen BKIndem 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 dieBKGröße Super Batch. Wir führen dann nach jedem die Gewichtsaktualisierung durchK-te Charge wurde verarbeitet.

Wir werden das genau berechnen BKBatch-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.

Indie AI
quelle
Ich habe bereits alle Eingänge verkleinert, die ich skalieren konnte ... Es ist jetzt auf Mini-Batch-Größe reduziert ...
Shai
Vielen Dank für Ihre Antwort. Die Sache ist, dass ich wirklich darauf abziele, eine Expertenmeinung über die Fähigkeit des Impulses zu erhalten, als "Gradient Noise Reduction" -Komponente zu arbeiten
Shai
Ah, ich verstehe, ich habe meine Antwort aktualisiert, um dann eine andere Möglichkeit vorzuschlagen. Ich habe es nicht ausprobiert, aber vielleicht kann es für Sie funktionieren? Hoffe es hilft, auch wenn man herausfindet was nicht funktioniert.
Indie AI
Es ist ein interessanter Ansatz, aber in vielen Fällen benötigen Sie die "Vorwärts" -Informationen, um den "Rückwärts" -Gradienten zu berechnen. Daher müssen Sie alle Mini-Batches, die Sie mitteln möchten, "weiterleiten", um den Gradienten abzuschätzen. Dies ist in Bezug auf die Trainingszeit nicht möglich. Ich würde zur CPU wechseln und mit größeren Batches die gleiche Geschwindigkeit erzielen .
Shai
1
Okay, es macht jetzt mehr Sinn. Obwohl es sich sehr nach erhöhtem Momentum anhört ... Siehe den letzten Absatz hier : "[Momentum] bestimmt, wie viele Iterationen die vorherigen Gradienten in das aktuelle Update aufgenommen wurden"
Shai
0

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.

Shai
quelle