Zuweisen von op in TensorFlow: Was ist der Rückgabewert?

Ich habe versucht, eine Autoincrementing-Grafik in TensorFlow zu bauen. Ich dachte, dass die assign op könnte dafür geeignet sein, aber fand keine Dokumentation dafür.

Ich nahm an, dass dieses op seinen Wert wie in C-ähnlichen Sprachen zurückgibt und schrieb den folgenden Code:

 import tensorflow as tf counter = tf.Variable(0, name="counter") one = tf.constant(1) ten = tf.constant(10) new_counter = tf.add(counter, one) assign = tf.assign(counter, new_counter) result = tf.add(assign, ten) init_op = tf.initialize_all_variables() with tf.Session() as sess: sess.run(init_op) for _ in range(3): print sess.run(result) 

Und dieser Code funktioniert.

Die Frage ist: Ist das das erwartete Verhalten? Warum ist die Zuordnung hier nicht dokumentiert: https://www.tensorflow.org/versions/0.6.0/api_docs/index.html

Ist es eine nicht empfohlene op?

  • Zuordnen innerhalb if-Anweisung Python
  • Wie vergeben Sie bei der Definition einer Klasse in Python einen Wert auf mehrere Variablen?
  • 2 Solutions collect form web for “Zuweisen von op in TensorFlow: Was ist der Rückgabewert?”

    Der Operator tf.assign() ist der zugrunde liegende Mechanismus, der die Variable.assign() Methode implementiert. Es nimmt einen veränderlichen Tensor (mit tf.*_ref Typ) und einen neuen Wert und gibt einen veränderlichen Tensor zurück , der mit dem neuen Wert aktualisiert wurde. Der Rückgabewert wird zur Verfügung gestellt, um es einfacher zu machen, eine Zuordnung vor einem späteren Lesen zu bestellen, aber diese Funktion ist nicht gut dokumentiert. Ein Beispiel wird hoffentlich illustrieren:

     v = tf.Variable(0) new_v = v.assign(10) output = v + 5 # `v` is evaluated before or after the assignment. sess.run(v.initializer) result, _ = sess.run([output, new_v.op]) print result # ==> 10 or 15, depending on the order of execution. 

     v = tf.Variable(0) new_v = v.assign(10) output = new_v + 5 # `new_v` is evaluated after the assignment. sess.run(v.initializer) result = sess.run([output]) print result # ==> 15 

    In Ihrem Codebeispiel erzwingen die Dataflow-Abhängigkeiten die Reihenfolge der Ausführung [read counter] -> new_counter = tf.add(...) -> tf.assign(...) -> [read output of assign] -> result = tf.add(...) , was bedeutet, dass die Semantik eindeutig ist. Die Lese-Modifizierungs-Schreib-Schritte zum Aktualisieren des Zählers sind jedoch etwas ineffizient und können ein unerwartetes Verhalten haben, wenn mehrere Schritte gleichzeitig ausgeführt werden. Zum Beispiel könnten mehrere Threads, die auf dieselbe Variable zugreifen, den Zähler beobachten, der sich rückwärts bewegt (falls ein älterer Wert nach einem neueren Wert zurückgeschrieben wurde).

    Ich würde empfehlen, dass Sie Variable.assign_add() , um den Zähler wie folgt zu aktualisieren:

     counter = tf.Variable(0, name="counter") one = tf.constant(1) ten = tf.constant(10) # assign_add ensures that the counter always moves forward. updated_counter = counter.assign_add(one, use_locking=True) result = tf.add(updated_counter, ten) # ... 

    tf.assign() ist in den neuesten Versionen gut dokumentiert und wird häufig in den Projekten verwendet.

    Diese Operation gibt nach der Zuweisung "ref" aus. Dies macht es einfacher, Operationen zu ketten, die den Rücksetzwert verwenden müssen.

    In einfacheren Worten nimmt es deinen ursprünglichen Tensor und einen neuen Tensor. Es aktualisiert den ursprünglichen Wert deines Tensors mit einem neuen Wert und gibt die Referenz deines ursprünglichen Tensors zurück.

    Python ist die beste Programmiersprache der Welt.