Tensorflow enthält ein Beispiel-Tutorial zur Klassifizierung von CIFAR-10 . Im Tutorial wird der durchschnittliche Kreuzentropieverlust über die Charge minimiert.
def loss(logits, labels):
"""Add L2Loss to all the trainable variables.
Add summary for for "Loss" and "Loss/avg".
Args:
logits: Logits from inference().
labels: Labels from distorted_inputs or inputs(). 1-D tensor
of shape [batch_size]
Returns:
Loss tensor of type float.
"""
# Calculate the average cross entropy loss across the batch.
labels = tf.cast(labels, tf.int64)
cross_entropy = tf.nn.sparse_softmax_cross_entropy_with_logits(
logits, labels, name='cross_entropy_per_example')
cross_entropy_mean = tf.reduce_mean(cross_entropy, name='cross_entropy')
tf.add_to_collection('losses', cross_entropy_mean)
# The total loss is defined as the cross entropy loss plus all of the weight
# decay terms (L2 loss).
return tf.add_n(tf.get_collection('losses'), name='total_loss')
Siehe cifar10.py , Zeile 267.
Warum wird stattdessen nicht die Summe über die Charge minimiert? Macht es einen Unterschied? Ich verstehe nicht, wie sich dies auf die Backprop-Berechnung auswirken würde.
neural-networks
loss-functions
tensorflow
Zusammenstoß
quelle
quelle
Antworten:
Wie von pkubik erwähnt, gibt es normalerweise einen Regularisierungsterm für die Parameter, der nicht von der Eingabe abhängt, beispielsweise im Tensorflow
In diesem Fall hilft die Mittelung über die Mini-Charge dabei, ein festes Verhältnis zwischen
cross_entropy
Verlust undregularizer
Verlust beizubehalten, während die Chargengröße geändert wird.Darüber hinaus ist die Lernrate auch abhängig von der Größe des Verlusts (Gradienten). Um das Ergebnis unterschiedlicher Chargengrößen zu normalisieren, scheint es eine bessere Option zu sein, den Durchschnitt zu verwenden.
Aktualisieren
Dieses Papier von Facebook (Accurate, Large Minibatch SGD: Training ImageNet in 1 Stunde) zeigt, dass die Skalierung der Lernrate entsprechend der Stapelgröße recht gut funktioniert:
Dies ist im Wesentlichen dasselbe, um den Gradienten mit k zu multiplizieren und die Lernrate unverändert zu lassen. Ich denke, es ist nicht notwendig, den Durchschnitt zu nehmen.
quelle
Ich werde mich auf den Teil konzentrieren:
Zunächst haben Sie wahrscheinlich bereits bemerkt, dass der einzige Unterschied zwischen den resultierenden Verlustwerten darin besteht, dass der durchschnittliche Verlust in Bezug auf die Summe um den Faktor verkleinert wird1B. L.S.U.M.= B ⋅ L.A V.G , wo B. ist die Chargengröße. Wir können leicht beweisen, dass dieselbe Beziehung für eine Ableitung einer Variablen wrt gilt. die Verlustfunktionen (dL.S.U.M.dx= B dL.A V.Gdx ) anhand der Definition des Derivats:
dL.dx= limΔ → 0L ( x + Δ ) - L ( x )Δ
Nun möchten wir den Wert der Funktion multiplizieren und sehen, wie sie sich auf die Ableitung auswirkt:
d( c ⋅ L )dx= limΔ → 0c ≤ L ( x + Δ ) - c ≤ L ( x )Δ
Wenn wir die Konstante herausrechnen und vor die Grenze verschieben, sollten wir sehen, dass wir die ursprüngliche Ableitungsdefinition multipliziert mit einer Konstanten finden, was genau das ist, was wir beweisen wollten:
d( c ⋅ L )dx= c ⋅ limΔ → 0L ( x + Δ ) - L ( x )Δ= c ⋅ dL.dx
In SGD würden wir die Gewichte anhand ihres Gradienten multipliziert mit der Lernrate aktualisierenλ und wir können deutlich sehen, dass wir diesen Parameter so wählen können, dass die endgültigen Gewichtsaktualisierungen gleich sind. Die erste Aktualisierungsregel:
W.: = W.+ λ1dL.S.U.M.dW.
und die zweite Update-Regel (stellen Sie sich das vor λ1= λ2B. ):
W.: = W.+ λ1dL.A V.GdW.= W.+ λ2B.dL.S.U.M.dW.
Der ausgezeichnete Befund von dontloo könnte darauf hindeuten, dass die Verwendung der Summe ein wenig angemessener ist. Um den Durchschnitt zu rechtfertigen, der populärer zu sein scheint, möchte ich hinzufügen, dass die Verwendung der Summe wahrscheinlich einige Probleme bei der Gewichtsregulierung verursachen könnte. Das Einstellen des Skalierungsfaktors für die Regularisierer für verschiedene Chargengrößen kann genauso ärgerlich sein wie das Einstellen der Lernrate.
quelle