Wie ordne ich einer TensorFlow-Variablen einen Wert zu?


78

Ich versuche, einer Tensorflow-Variablen in Python einen neuen Wert zuzuweisen.

import tensorflow as tf
import numpy as np

x = tf.Variable(0)
init = tf.initialize_all_variables()
sess = tf.InteractiveSession()
sess.run(init)

print(x.eval())

x.assign(1)
print(x.eval())

Aber die Ausgabe, die ich bekomme, ist

0
0

Der Wert hat sich also nicht geändert. Was vermisse ich?

Antworten:


123

In TF1 weist die Anweisung x.assign(1)den Wert nicht tatsächlich 1zu x, sondern erstellt einen Wert tf.Operation, den Sie explizit ausführen müssen , um die Variable zu aktualisieren. * Ein Aufruf von Operation.run()oder Session.run()kann zum Ausführen der Operation verwendet werden:

assign_op = x.assign(1)
sess.run(assign_op)  # or `assign_op.op.run()`
print(x.eval())
# ==> 1

(* Tatsächlich wird a zurückgegeben tf.Tensor, was dem aktualisierten Wert der Variablen entspricht, um die Verkettung von Zuweisungen zu vereinfachen.)

In TF2 x.assign(1)wird der Wert nun jedoch eifrig vergeben:

x.assign(1)
print(x.numpy())
# ==> 1

Vielen Dank! assign_op.run () gibt einen Fehler aus: AttributeError: Das Objekt 'Tensor' hat kein Attribut 'run'. Aber sess.run (assign_op) läuft einwandfrei.
Abora

Werden in diesem Beispiel die Daten, die Variable xvor dem assignAusführen der Operation / des veränderlichen Tensors im Speicher gespeichert wurden, überschrieben oder wird ein neuer Tensor erstellt, der den aktualisierten Wert speichert?
Danny Goldstein

3
Die aktuelle Implementierung von assign()überschreibt den vorhandenen Wert.
heiraten

1
Gibt es eine Möglichkeit, a einen neuen Wert zuzuweisen, Variableohne zusätzliche Operationen im Diagramm zu erstellen? Es scheint, dass für jede Variable bereits eine Zuweisungsoperation erstellt wurde, aber eine neue Operation aufgerufen my_var.assign()oder tf.assign()erstellt wird, anstatt die vorhandene zu verwenden.
Nathan

Ich denke nicht, ob dies hier relevant ist, aber Sie können assigneinen Tensorparameter wie die mathematische Operation angeben. Erstellen Sie auf diese Weise einen Zähler, der jedes Mal aktualisiert wird, wenn die Zuweisungsoperation ausgewertet wird : op = t.assign(tf.add(t, 1)).
Eliel Van Hojman

40

Sie können a auch einen neuen Wert zuweisen, tf.Variableohne dem Diagramm eine Operation hinzuzufügen : tf.Variable.load(value, session). Mit dieser Funktion können Sie auch Platzhalter hinzufügen, wenn Sie einen Wert von außerhalb des Diagramms zuweisen. Dies ist nützlich, wenn das Diagramm fertiggestellt ist.

import tensorflow as tf
x = tf.Variable(0)
sess = tf.Session()
sess.run(tf.global_variables_initializer())
print(sess.run(x))  # Prints 0.
x.load(1, sess)
print(sess.run(x))  # Prints 1.

Update: Dies ist in TF2 nicht möglich, da die eifrige Ausführung standardmäßig ist und Diagramme in der benutzerbezogenen API nicht mehr angezeigt werden .


2
Vorsichtsmaßnahme: Sie können es nicht mit einem Array laden, das eine andere Form als die Form des Anfangswertes der Variablen hat!
Rajarshee Mitra

1
Variable.load (von tensorflow.python.ops.variables) ist veraltet und wird in einer zukünftigen Version entfernt. Anweisungen zum Aktualisieren: Bevorzugen Sie Variable.assign, das in 2.X ein gleichwertiges Verhalten aufweist. Ich bin mir nicht sicher, wie ich die Werte einer Variablen in Tensorflow 2.0 ändern soll, ohne dem Diagramm eine Operation hinzuzufügen
João Abrantes

15

Zunächst können Sie Variablen / Konstanten Werte zuweisen, indem Sie ihnen Werte hinzufügen, wie Sie es mit Platzhaltern tun. Das ist also völlig legal:

import tensorflow as tf
x = tf.Variable(0)
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    print sess.run(x, feed_dict={x: 3})

In Bezug auf Ihre Verwechslung mit dem Operator tf.assign () . In TF wird nichts ausgeführt, bevor Sie es innerhalb der Sitzung ausführen. Sie müssen also immer so etwas tun: op_name = tf.some_function_that_create_op(params)und dann innerhalb der Sitzung, die Sie ausführen sess.run(op_name). Am Beispiel von "Zuweisen" tun Sie Folgendes:

import tensorflow as tf
x = tf.Variable(0)
y = tf.assign(x, 1)
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    print sess.run(x)
    print sess.run(y)
    print sess.run(x)

@RobinDinse, das tut es. Im obigen Beispiel erhalten Sie 0,1,1 als Standard.
Rajarshee Mitra

4
Beachten Sie, dass das Zuführen des Werts über das den Wert feed_dictnicht dauerhaft der Variablen zuweist, sondern nur für diesen bestimmten Laufaufruf.
Robin Dinse

@RobinDinse Wie kann ich diesen Wert dauerhaft zuweisen? Wenn Sie können, sehen Sie meine Frage hier stackoverflow.com/questions/53141762/…
volperossa

3

Außerdem hat darauf hingewiesen, dass , wenn Sie verwenden your_tensor.assign(), dann ist die tf.global_variables_initializerNotwendigkeit nicht explizit aufgerufen werden , da der assign Betrieb es für Sie im Hintergrund tut.

Beispiel:

In [212]: w = tf.Variable(12)
In [213]: w_new = w.assign(34)

In [214]: with tf.Session() as sess:
     ...:     sess.run(w_new)
     ...:     print(w_new.eval())

# output
34 

Dadurch werden jedoch nicht alle Variablen initialisiert, sondern nur die Variable, für die assignausgeführt wurde.


1

Ich antwortete eine ähnliche Frage hier . Ich habe an vielen Orten gesucht, die immer das gleiche Problem verursacht haben. Grundsätzlich wollte ich den Gewichten keinen Wert zuweisen, sondern einfach die Gewichte ändern. Die Kurzversion der obigen Antwort lautet:

tf.keras.backend.set_value(tf_var, numpy_weights)


0

Hier ist das vollständige Arbeitsbeispiel:

import numpy as np
import tensorflow as tf

w= tf.Variable(0, dtype=tf.float32) #good practice to set the type of the variable
cost = 10 + 5*w + w*w
train = tf.train.GradientDescentOptimizer(0.01).minimize(cost)

init = tf.global_variables_initializer()
session = tf.Session()
session.run(init)

print(session.run(w))

session.run(train)
print(session.run(w)) # runs one step of gradient descent

for i in range(10000):
  session.run(train)

print(session.run(w))

Beachten Sie, dass die Ausgabe wie folgt lautet:

0.0
-0.049999997
-2.499994

Dies bedeutet, dass die Variable zu Beginn wie definiert 0 war, dann war die Variable nach nur einem Gradientengradienten -0,049999997 und nach 10.000 weiteren Schritten erreichen wir -2,499994 (basierend auf unserer Kostenfunktion).

Hinweis: Sie haben ursprünglich die interaktive Sitzung verwendet. Eine interaktive Sitzung ist nützlich, wenn mehrere verschiedene Sitzungen im selben Skript ausgeführt werden mussten. Der Einfachheit halber habe ich jedoch die nicht interaktive Sitzung verwendet.


0

Verwenden Sie den neuesten Tensorflow-Eifrig-Ausführungsmodus.

import tensorflow as tf
tf.enable_eager_execution()
my_int_variable = tf.get_variable("my_int_variable", [1, 2, 3])
print(my_int_variable)

-1

Ich hatte also einen anderen Fall, in dem ich vor dem Ausführen einer Sitzung Werte zuweisen musste. Dies war also der einfachste Weg, dies zu tun:

other_variable = tf.get_variable("other_variable", dtype=tf.int32,
  initializer=tf.constant([23, 42]))

Hier erstelle ich eine Variable und weise ihr gleichzeitig Werte zu


-10

Es gibt einen einfacheren Ansatz:

x = tf.Variable(0)
x = x + 1
print x.eval()

3
Die Operation untersuchte die Verwendung von tf.assign, nicht die Hinzufügung.
Vega
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.