Möglichkeiten zur Implementierung von Multi-GPU-BN-Schichten mit Synchronisationsmitteln und Variablen

8

Ich würde gerne die Möglichkeiten kennen lernen, Batch-Normalisierungsebenen mit Batchstatistiken zu synchronisieren, wenn Sie mit Multi-GPU trainieren.

Caffe Vielleicht gibt es einige Varianten von caffe, die das tun könnten, wie link . Aber für BN-Schicht ist mein Verständnis, dass es immer noch nur die Ausgänge von Schichten synchronisiert, nicht die Mittel und Vars. Vielleicht MPI kann Mittel und Vars synchronisieren, aber ich denke, MPI ist ein wenig schwierig zu implementieren.

Fackel Ich habe einige Kommentare hier und hier , die zeigen, dass running_mean und running_var synchronisiert werden können, aber ich denke, Batch-Mean und Batch-Var können nicht oder sind schwer zu synchronisieren.

Tensorflow Normalerweise ist es das gleiche wie Caffe und Fackel. Die Implementierung von BN bezieht sich dies . Ich weiß, dass Tensorflow eine Operation auf jedes Gerät verteilen kann, das von tf.device() angegeben wird. Aber die Berechnung von means und vars ist in der Mitte der BN-Ebene, also wenn ich die Mittelwerte und vars in cpu sammle, ist mein Code wie folgt:

%Vor%

Das ist nur für eine BN-Schicht. Um Statistiken in der CPU zu sammeln, muss ich den Code brechen. Wenn ich mehr als 100 BN-Schichten habe, wird das mühsam.

Ich bin kein Experte in diesen Bibliotheken, also vielleicht gibt es einige Missverständnisse, fühlen Sie sich frei, meine Fehler aufzuzeigen.

Es ist mir egal, wie schnell ich trainiere. Ich mache eine Bildsegmentierung, die viel GPU-Speicher verbraucht, und BN benötigt eine vernünftige Stapelgröße (z. B. größer als 16) für stabile Statistiken. Daher ist die Verwendung von Multi-GPU unvermeidlich. Meiner Meinung nach könnte Tensorflow die beste Wahl sein, aber ich kann das Problem des Brechens nicht lösen. Lösung mit anderen Bibliotheken wird ebenfalls willkommen sein.

    
Seven 27.03.2017, 21:42
quelle

1 Antwort

2

Ich bin mir nicht sicher, ob ich Ihre Frage vollständig verstanden habe, aber vorausgesetzt, Sie haben Ihren Variablenbereich richtig eingerichtet, sollte die tf.GraphKeys.UPDATE_OPS -Auflistung automatisch den Update-Befehl für Batch_Norm für jeden Ihrer Türme haben. Wenn alle update_ops synchron angewendet werden, werden sie implizit vom Parameterserver gemittelt. Sie müssen lediglich sicherstellen, dass die Aktualisierungen angewendet werden, bevor Sie einen Durchschnittswert berechnen und anwenden. (Wenn ich deine Absichten richtig verstehe).

Aufgrund des variablen Umfangs wird jede Gruppe von Update-Ops die gleichen Variablen aktualisieren. Um die Update-Ops zu synchronisieren, müssen Sie also nur die Gradientenberechnung für den gesamten Satz von Update-Ops durchführen. Sie sollten auch alle Ihre Stapel-Norm-Layer in einem einzigen name_scope einkapseln, um zu vermeiden, dass Sie irgendwelche überflüssigen Operationen in UPDATE_OPS übernehmen. Code-Skelett unten:

%Vor%

Wenn Sie dies mit einem vorhandenen Code versuchen möchten, versuchen Sie, die Zeile if i == 0 hier zu löschen: Ссылка

Sie werden etwas langsamer werden sehen (wir verwenden normalerweise nur einen Turm, um aus diesem Grund Batch-Norm-Statistiken zu berechnen), aber es sollte tun, was Sie wollen.

    
Eli Bixby 06.01.2018 00:15
quelle