2017-02-13 6 views
3

Im TensorFlow CIFAR10 example, trainiert über mehrere GPUs, scheint der Verlust für jeden "Turm" kombiniert zu sein, und der Gradient wird aus diesem kombinierten Verlust berechnet.Tensorflow CIFAR10 Multi GPU - Warum kombinierter Verlust?

# Build the portion of the Graph calculating the losses. Note that we will 
    # assemble the total_loss using a custom function below. 
    _ = cifar10.loss(logits, labels) 

    # Assemble all of the losses for the current tower only. 
    losses = tf.get_collection('losses', scope) 

    # Calculate the total loss for the current tower. 
    total_loss = tf.add_n(losses, name='total_loss') 

    # Attach a scalar summary to all individual losses and the total loss; do the 
    # same for the averaged version of the losses. 
    for l in losses + [total_loss]: 
     # Remove 'tower_[0-9]/' from the name in case this is a multi-GPU training 
     # session. This helps the clarity of presentation on tensorboard. 
     loss_name = re.sub('%s_[0-9]*/' % cifar10.TOWER_NAME, '', l.op.name) 
     tf.contrib.deprecated.scalar_summary(loss_name, l) 

    return total_loss 

Ich bin neu in TensorFlow, aber aus meinem Verständnis, jedes Mal cifar10.loss genannt wird, tf.add_to_collection('losses', cross_entropy_mean) ausgeführt wird und der Verlust aus der aktuellen Charge wird in der Sammlung gespeichert.

Dann wird losses = tf.get_collection('losses', scope) aufgerufen, und alle die Verluste werden aus der Sammlung abgerufen. Dann fügt tf.add_n op alle abgerufenen Verlusttensoren von diesem "Turm" zusammen.

erwartete ich den Verlust nur aus dem aktuellen Trainingsschritt/Charge, nicht alle Chargen zu sein.

Habe ich etwas falsch verstanden? Oder gibt es einen Grund, die Verluste zu kombinieren?

+0

Sie Verlust von einem großen Stapel, und dies wird durch Spaltung Charge in mehrere kleinere Chargen, eine pro GPU implementiert, und dann unter Verwendung 'add_n' –

+0

danke für den Kommentar den vollständigen Verlust zu erholen. Ich bekomme, dass Sie die Charge in kleinere Chargen aufteilen, aber Sie erhalten nur Verluste von der * aktuellen * Turm: 'Verluste = tf.get_collection ('Verluste', Umfang)' filtert die Tensoren durch den Geltungsbereich – deef

+0

oh I Schau, was du meinst. Gibt es mehr als einen Verlust in der "Verluste" -Sammlung? Ich würde erwarten, dass es einen Verlust gibt, also wäre 'add_n' ein No-Op –

Antwort

1

Wenn die Gewichtsverringerung aktiviert ist, wird sie auch zur Verlustsammlung hinzugefügt. Daher wird für jeden Turm (Scope) add_n alle Verluste: cross_entropy_mean und weight_decay.

Dann werden die Gradienten für jeden Turm (Scope) berechnet. Am Ende werden alle Gradienten für verschiedene Türme (Bereiche) in den Durchschnittswerten gemittelt.

1

Warum kombinierten Verlust

Das Beispiel, das Sie beziehen sind ein Beispiel für Datenparallelität über mehrere GPUs ist. Datenparallelität hilft bei der Entwicklung eines tieferen Modells mit größerer Batchgröße. In dieser Einstellung müssen Sie den Verlust aus den GPUs kombinieren, da jeder der GPUs einen Teil des Input-Batch enthält (Verlust und Gradient entsprechend diesem Input-Teil). Eine Abbildung wird im folgenden Beispiel von tensorflow data parallism example bereitgestellt.

Hinweis: Bei Modellparallelität werden verschiedene Untergraphen des Modells, die auf separaten GPUS- und Zwischenausgängen ausgeführt werden, vom Master erfasst.

Beispiel

wenn Sie das Modell mit einer Chargengröße von 256, für ein tieferes Modell (zum Beispiel RESNET/Anfang), die in einem einzigen gpu passen mayn't (zum Beispiel ein 8 GB trainieren möchten Speicher), so dass Sie die Charge in zwei Chargen der Größe 128 aufteilen und den Modelldurchlauf mit den beiden Chargen auf separaten GPUs durchführen und Verluste und Verläufe berechnen können. Die berechneten (Verlustgradienten) von jedem der GPUs werden gesammelt und gemittelt. Der gemittelte Gradient wird verwendet, um die Modellparameter zu aktualisieren.

enter image description here