Wie berechnet man den Einfluss des Mini-Batch-Speichers beim Training von Deep-Learning-Modellen?


17

Ich versuche anhand dieser Notizen von Andrej Karphaty zu berechnen, wie viel Speicher eine GPU zum Trainieren meines Modells benötigt: http://cs231n.github.io/convolutional-networks/#computational-considerations

Mein Netzwerk hat 532.752 Aktivierungen und 19.072.984 Parameter (Gewichte und Vorspannungen). Dies sind alles 32-Bit-Float-Werte, sodass jeder 4 Bytes im Speicher benötigt.

Mein Eingabebild ist 180x50x1 (Breite x Höhe x Tiefe) = 9.000 Float 32-Werte. Ich verwende keine Bildvergrößerung, daher denke ich, dass der sonstige Speicher nur mit der Größe des Minibatches zusammenhängt. Ich verwende eine Mini-Batch-Größe von 128 Bildern.

Auf Empfehlung von Andrej erhalte ich folgende Speichergrößen:

Aktivierungen: 532.752 * 4 / (1024 ^ 2) = 2,03 MB

Parameter: 19.072.984 × 4 / (1024 × 2) × 3 = 218,27 MB

Verschiedenes: 128 * 9.000 * 4 / (1024 ^ 2) = 4,39 MB

Der Gesamtspeicher zum Trainieren dieses Netzwerks beträgt also 224,69 MB .

Ich benutze TensorFlow und vermisse etwas. Ich habe das Training noch nicht durchgeführt, aber ich bin mir ziemlich sicher (basierend auf früheren Erfahrungen), dass der verwendete Speicher viel höher sein wird als von mir berechnet.

Wenn TensorFlow für jedes Bild im Mini - Batch die Farbverläufe beibehält, um sie später für einen einzelnen Schritt zur Aktualisierung der Gewichte / Vorspannungen zu normalisieren, sollte der Speicher meines Erachtens weitere 532.752 * 128 Werte (Farbverläufe für jedes Bild in der Grafik) berücksichtigen Mini-Batch). Wenn das der Fall ist, würde ich mehr 260,13 MB benötigen, um dieses Modell mit 128 Bildern / Mini-Batch zu trainieren.

Können Sie mir helfen, die Überlegungen zum Gedächtnis für das Training meines Deep-Learning-Modells zu verstehen? Stimmen die obigen Überlegungen?


Bitte sehen Sie meine (vorgeschlagene) Antwort auf Ihre Frage hier .
Adam Hendry

Antworten:


5

Ich denke, Sie sind auf dem richtigen Weg.

Ja, Sie müssen die Ableitungen der Aktivierungen und der Parameter für die Rückübertragung speichern.

Darüber hinaus kann Ihre Wahl der Optimierung von Bedeutung sein. Trainierst du mit SGD, Adam oder Adagrad? Diese haben alle unterschiedliche Speicheranforderungen. Beispielsweise müssen Sie den Schrittgrößen-Cache für eine momentumbasierte Methode speichern, obwohl dies im Vergleich zu den anderen von Ihnen erwähnten Speicherüberlegungen zweitrangig sein sollte.

Alles in allem scheinen Sie den Speicherbedarf für einen Vorwärtsdurchlauf berechnet zu haben. Andrej Karpathy erwähnt, dass der Rückwärtsdurchlauf bis zu dreimal so viel Speicherplatz beanspruchen kann wie der Vorwärtsdurchlauf. Daher wird möglicherweise ein solcher Unterschied angezeigt (scrollen Sie auf der Website zu „Fallstudien“, um ein Beispiel für VGGNet anzuzeigen).


4

@StatsSorceress TL; DR:

Ich gehe diese Aktivität durch, um zu sehen, ob ich den benötigten Speicher selbst berechnen kann:

Aktivierungen: 532.752 * 2 * 4 / (1024 ^ 2) = 4,06 MB

Parameter: 19.072.984 * 4 / (1024 ^ 2) * 3 = 218,27 MB

Verschiedenes: 128 * 9.000 * 4 / (1024 ^ 2) = 4,39 MB

Gesamtspeicher: (4,06 × 128 ) + 218,27 + 4,39 = 742,34 MB

( Bitte korrigieren Sie mich, wenn ich falsch liege. Zu Ihrer Information, Sie haben bereits Verschiedenes mit 128 multipliziert. Deshalb habe ich es oben nicht mit 128 multipliziert. )


Ich würde Sie auf diesen Artikel und das entsprechende Video verweisen . Sie haben mir geholfen zu verstehen, was viel besser läuft.

ANMERKUNG: Der für die Verwendung eines Netzwerks für Vorhersagen erforderliche Speicher ist aus zwei Gründen weitaus geringer als der für das Training erforderliche Speicher:

  • Bei der Vorhersage senden wir ein Bild nur vorwärts über das Netzwerk und nicht rückwärts (daher multiplizieren wir den Speicher nicht mit X 3; siehe unten).
  • Es gibt eine Vorhersage pro Bild (daher müssen wir den für ein Bild erforderlichen Speicher nicht mit einer Stapelgröße multiplizieren, da wir für die Vorhersage keine Stapel verwenden).

Prozess (Gedächtnis zu trainieren)

  1. Berechnen Sie den Speicher, der zum Trainieren eines Bildes erforderlich ist
  2. Multiplizieren Sie diese Zahl mit der Anzahl der Bilder in Ihrem Stapel

( ERINNERN SIE SICH: Mini-Batching besagt, dass wir eine Teilmenge unserer Daten nehmen, die Verläufe und Fehler für jedes Bild in der Teilmenge berechnen, diese dann mitteln und in Richtung des Durchschnitts voranschreiten. Bei Konvetten werden Gewichte und Verzerrungen geteilt, aber Die Anzahl der Aktivierungen wird durch die Anzahl der Bilder im Stapel multipliziert. ).

SCHRITT 1: Speicher für 1 Bild

Um ein Bild zu trainieren, müssen Sie Speicher reservieren für:

  • Modellparameter:

    Die Gewichte und Vorspannungen an jeder Schicht, deren Verläufe und ihre Impulsvariablen (wenn Adam, Adagrad, RMSProp usw. Optimierer verwendet werden)

    Um die Speicherkapazität hierfür zu schätzen, berechnen Sie die Speicherkapazität, die zum Speichern der Gewichte und Vorspannungen erforderlich ist, und multiplizieren Sie diese mit 3 (dh "mit 3"), da die Speicherkapazität, die zum Speichern der Gewichte und Vorspannungen erforderlich ist, (ungefähr) gleich ist das für die Steigungen und für die Impulsvariablen benötigt wird)

    Gleichungen:

    Faltungen:

    Gewichte (n) = Tiefe (n) * (Kernel_Breite * Kernel_Höhe) * Tiefe (n-1)

    Vorurteile (n) = Tiefe (n)

    Vollständig verbundene (dichte) Schichten:

    Gewichte (n) = Ausgänge (n) * Eingänge (n)

    Vorspannungen (n) = Ausgänge (n)

Dabei ist n die aktuelle Schicht und n-1 die vorherige Schicht, und Ausgänge sind die Anzahl der Ausgänge aus der FC-Schicht und Eingänge sind die Anzahl der Eingänge in die FC-Schicht (wenn die vorherige Schicht keine vollständig verbundene Schicht ist, Die Anzahl der Eingaben entspricht der Größe dieser Ebene (abgeflacht).

HINWEIS: Der Speicher für die Gewichte und Vorspannungen allein sowie der Speicher für die Aktivierungen für ein Bild (siehe unten) ist die Gesamtmenge des Speichers, die Sie für Vorhersagen benötigen (mit Ausnahme eines gewissen Overheads für den Speicher für Faltungen und einige andere Dinge).

  • Aktivierungen (das sind "Blobs" in Caffe):

(Ich benutze Begriffe hier locker, trage sie mit mir)

Jede Faltung in einer Faltungsebene erzeugt Aktivierungen " Anzahl der Pixel in Bild " (dh Sie durchlaufen ein Bild durch eine einzelne Faltung. Sie erhalten eine einzelne Feature-Map, die aus " m " Aktivierungen besteht, wobei " m " die Anzahl der Pixel von Ihnen ist Bild / Eingabe).

Bei vollständig verbundenen Layern entspricht die Anzahl der von Ihnen erzeugten Aktivierungen der Größe Ihrer Ausgabe.

Faltungen:

Aktivierungen (n) = image_width * image_height * image_num_channels

Vollständig verbundene (dichte) Schichten:

Aktivierungen (n) = Ausgänge (n)

Beachten Sie, dass Ihre Eingabe eigentlich nur ein Bild am Anfang des Netzwerks ist. Nach Faltungen verwandelt es sich in etwas anderes (Feature-Maps). Ersetzen Sie also "image_width", "image_height" und "image_num_channels" durch "input_width", "input_height" und "layer_depth", um genau zu sein. (Es fällt mir nur leichter, dieses Konzept in Bildern zu sehen.)

Da wir auch den Fehler für die Aktivierungen auf jeder Ebene speichern müssen (im Rückwärtsdurchlauf verwendet), multiplizieren wir die Anzahl der Aktivierungen mit 2, um die Gesamtanzahl der Entitäten zu erhalten, für die in unserem Speicherplatz Platz geschaffen werden muss. Die Anzahl der Aktivierungen nimmt mit der Anzahl der Bilder im Stapel zu, sodass Sie diese Anzahl mit der Stapelgröße multiplizieren.

SCHRITT 2: Memory to Train Batch

Summieren Sie die Anzahl der Gewichte und Vorspannungen (mal 3) und die Anzahl der Aktivierungen (mal 2 mal die Chargengröße). Multiplizieren Sie dies mit 4, und Sie erhalten die Anzahl der zum Trainieren des Stapels erforderlichen Bytes. Sie können durch 1024 ^ 2 dividieren, um die Antwort in GB zu erhalten.


Warum sagen Sie "wir verwenden keine Chargen für die Vorhersage"? Wenn ein Benutzer Vorhersagen für eine große Anzahl von Bildern treffen muss, kann es sinnvoll sein, Stapel für Vorhersagen zu verwenden.
user3731622

1

Alternativ können Sie auch eine beliebige Profiler-Bibliothek verwenden, um die Speicher- und CPU-Auslastung Ihres Programms zu analysieren. Es gibt viele Python-Bibliotheken, mit denen Sie einen Überblick über die Speicher- und CPU-Auslastung eines bestimmten Threads oder Prozesses im Millisekundenintervall erhalten.

Sie können den Teil Ihres Programms, den Sie überwachen möchten, in einem anderen Unterprozess mit popen ausführen und dessen Speicher- und CPU-Auslastung mithilfe der PID überwachen.

psutil finde ich gut für solche arbeit . Obwohl es viele andere gibt.

Ich hoffe das wird helfen.


3
Danke für die Antwort, @Anwar. Ich suche eher eine analytische Berechnung als eine empirische Beobachtung.
Barbolo
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.