Sie haben Recht, dass weightsLayer1 = tf.div(weightsLayer1, math.sqrt(nInputUnits))
bei jedem Schritt ausgeführt wird. Aber das bedeutet NICHT, dass die Werte in der Gewichtsvariablen in jedem Schritt um sqrt(nInputUnits)
herunterskaliert werden. Diese Zeile ist keine direkte Operation, die sich auf die in der Variablen gespeicherten Werte auswirkt. Er berechnet einen neuen Tensor, der die Werte in der Variablen geteilt durch sqrt(nInputUnits)
enthält, und diesen Tensor nehme ich an, dann geht er in den Rest Ihres Berechnungsgraphen. Dies stört den Optimierer nicht. Sie definieren immer noch einen gültigen Berechnungsgraphen, nur mit einer etwas willkürlichen Skalierung der Gewichte. Der Optimierer kann immer noch die Gradienten in Bezug auf diese Variable berechnen (er wird sich durch Ihre Divisionsoperation zurück übertragen) und die entsprechenden Aktualisierungsoperationen erstellen.
In Bezug auf das Modell, das Sie definieren, sind die beiden Versionen völlig gleichwertig. Für jeden Wertebereich von weightsLayer1
im Originalmodell (wo Sie die Division nicht machen) können Sie sie einfach um sqrt(nInputUnits)
skalieren und Sie erhalten die identischen Ergebnisse mit Ihrem zweiten Modell. Die beiden repräsentieren genau die gleiche Modellklasse, wenn Sie so wollen.
Warum funktioniert einer besser als der andere? Deine Vermutung ist genauso gut wie meine. Wenn Sie für alle Ihre Variablen die gleiche Aufteilung vorgenommen haben, haben Sie Ihre Lernrate effektiv auf sqrt(nInputUnits)
aufgeteilt. Diese kleinere Lernrate könnte für das vorliegende Problem vorteilhaft gewesen sein.
Edit: Ich denke, dass die Tatsache, dass Sie der Variablen und dem neu erstellten Tensor denselben Namen geben, Verwirrung stiftet. Wenn Sie das tun
A = tf.Variable(1.0)
A = tf.mul(A, 2.0)
# Do something with A
erzeugt dann die zweite Zeile einen neuen Tensor (wie oben beschrieben) und Sie erneut binden den Namen (und es ist nur ein Name) A
zu diesem neuen Tensor. Für den zu definierenden Graph ist die Benennung absolut irrelevant. Der folgende Code definiert das gleiche Diagramm:
A = tf.Variable(1.0)
B = tf.mul(A, 2.0)
# Do something with B
Vielleicht wird deutlich, wenn Sie den folgenden Code ausführen:
A = tf.Variable(1.0)
print A
B = A
A = tf.mul(A, 2.0)
print A
print B
Der Ausgang ist
<tensorflow.python.ops.variables.Variable object at 0x7ff025c02bd0>
Tensor("Mul:0", shape=(), dtype=float32)
<tensorflow.python.ops.variables.Variable object at 0x7ff025c02bd0>
Das erste Mal, wenn Sie print A
es sagt Sie, dass A
ist ein variables Objekt. Nach der Ausführung von A = tf.mul(A, 2.0)
und dem erneuten Drucken von A
können Sie sehen, dass der Name A
jetzt an ein Objekt tf.Tensor
gebunden ist. Die Variable existiert jedoch immer noch, wie aus dem Blick auf das Objekt hinter dem Namen B
ersichtlich ist.
Zunächst einmal: In der Zwei-Zeilen-Implementierung machen Sie die Division zweimal durch '' sqrt (nInputUnits) '', effektiv dividiert durch '' nInputUnits''. Ist das beabsichtigt? Zweitens: Ich verstehe deine Frage nicht genau? Haben Sie Bedenken, dass die Variable '' weightsLayer1' 'jedes Mal neu initialisiert wird, wenn Sie einen Trainingsschritt ausführen? Wenn dem so ist, ist das nicht der Fall. Ich kann das näher ausführen, aber ich bin mir nicht ganz sicher, ob Sie das wirklich fragen. – lballes
Mein Fehler, der obige 2-Zeilen-Fall wurde hier falsch eingegeben, ich habe ihn oben korrigiert. Ich dividiere nur einmal mit 'sqrt (nInputUnits)'. Im 2-Zeilen-Fall weiß ich, dass 'weightsLayer1' nur einmal in der 'tf.Variable'-Zeile initialisiert wird. Meine Fragen: a) Stimmt es, dass die zweite Zeile ('weightsLayer1 = tf.div (weightsLayer1, math.sqrt (nInputUnits))' ') zur Laufzeit ausgeführt wird? b) Wenn ja, verändert es den Wert des 'WeightsLayer1', der vom Optimierer berechnet wurde und daher den Optimierungsprozess beeinflusst?c) Wenn ja, wie kann dies besser sein als die vom Optimizer berechneten "WeightsLayer1" -Werte? –
Okay, ich denke ich habe es jetzt bekommen. Siehe meine Antwort unten. – lballes