¿Cómo asignar un valor a una variable de TensorFlow?

79

Estoy tratando de asignar un nuevo valor a una variable tensorflow en Python.

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())

Pero el resultado que obtengo es

0
0

Entonces el valor no ha cambiado. ¿Qué me estoy perdiendo?

abora
fuente

Respuestas:

124

En TF1, la declaración x.assign(1)en realidad no asignar el valor 1a x, sino que crea una tf.Operationque tiene que explícitamente ejecutar para actualizar la variable * Una llamada al. Operation.run(), O Session.run()puede ser utilizado para ejecutar la operación:

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

(* De hecho, devuelve un tf.Tensor, correspondiente al valor actualizado de la variable, para facilitar la cadena de asignaciones).

Sin embargo, en TF2 x.assign(1)ahora asignará el valor con entusiasmo:

x.assign(1)
print(x.numpy())
# ==> 1
señor
fuente
¡Gracias! assign_op.run () da un error: AttributeError: El objeto 'Tensor' no tiene el atributo 'ejecutar'. Pero sess.run (assign_op) funciona perfectamente bien.
abora
En este ejemplo, ¿se sobrescriben los datos Variable xalmacenados en la memoria antes de assignejecutar la operación / tensor mutable o se crea un nuevo tensor que almacena el valor actualizado?
dannygoldstein
3
La implementación actual de assign()sobrescribe el valor existente.
mrry
1
¿Hay alguna forma de asignar un nuevo valor a a Variablesin crear operaciones adicionales en el gráfico? Parece que cada variable ya tiene una operación Asignar creada para ella, pero llamando my_var.assign()o tf.assign()crea una nueva operación en lugar de usar la existente.
Nathan
No creo que esto sea relevante aquí, pero puedes darle a assignun parámetro tensorial como una operación matemática. Y de esta manera crear un contador que se actualiza cada vez que se evalúa la operación de asignación: op = t.assign(tf.add(t, 1)).
Eliel Van Hojman
40

También puede asignar un nuevo valor a una tf.Variablesin la adición de una operación a la gráfica: tf.Variable.load(value, session). Esta función también puede ahorrarle agregar marcadores de posición al asignar un valor desde fuera del gráfico y es útil en caso de que el gráfico esté finalizado.

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.

Actualización: esto está descatalogado en TF2 ya que la ejecución ávida es predeterminada y los gráficos ya no están expuestos en la API de cara al usuario .

Robin Dinse
fuente
2
Advertencia: no puede cargarlo con una matriz que tenga una forma diferente a la forma del valor inicial de la variable.
Rajarshee Mitra
1
Variable.load (de tensorflow.python.ops.variables) está obsoleto y se eliminará en una versión futura. Instrucciones para la actualización: Prefiera Variable.assign que tiene un comportamiento equivalente en 2.X. No estoy seguro de cómo cambiar los valores de una variable en Tensorflow 2.0 sin agregar una operación al gráfico
João Abrantes
15

En primer lugar, puede asignar valores a variables / constantes simplemente introduciendo valores en ellas de la misma manera que lo hace con los marcadores de posición. Entonces esto es perfectamente legal de hacer:

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})

Con respecto a su confusión con el operador tf.assign () . En TF no se ejecuta nada antes de ejecutarlo dentro de la sesión. Así que siempre tienes que hacer algo como esto: op_name = tf.some_function_that_create_op(params)y luego, dentro de la sesión, ejecutas sess.run(op_name). Usando asignar como ejemplo, hará algo como esto:

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)
Salvador Dalí
fuente
@RobinDinse, lo hace. En el ejemplo anterior, obtienes 0,1,1 como tu salida estándar.
Rajarshee Mitra
4
Tenga en cuenta que introducir el valor a través de feed_dictno asigna permanentemente ese valor a la variable, sino solo para esa llamada de ejecución en particular.
Robin Dinse
@RobinDinse ¿cómo puedo asignar ese valor de forma permanente? Si puede, vea mi pregunta aquí stackoverflow.com/questions/53141762/…
volperossa
3

Además, debe tenerse en cuenta que si está utilizando your_tensor.assign(), tf.global_variables_initializerno es necesario que se llame explícitamente ya que la operación de asignación lo hace por usted en segundo plano.

Ejemplo:

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 

Sin embargo, esto no inicializará todas las variables, sino que solo inicializará la variable en la que assignse ejecutó.

kmario23
fuente
1

Respondí una pregunta similar aquí . Busqué en muchos lugares que siempre creaban el mismo problema. Básicamente, no quería asignar un valor a los pesos, sino simplemente cambiar los pesos. La versión corta de la respuesta anterior es:

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

user5931
fuente
0

Aquí está el ejemplo de trabajo completo:

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))

Tenga en cuenta que la salida será:

0.0
-0.049999997
-2.499994

Esto significa que al principio la Variable era 0, como se definió, luego, después de un solo paso de degradado decente, la variable era -0.049999997, y después de 10.000 pasos más, llegamos a -2.499994 (según nuestra función de costo).

Nota: originalmente utilizó la sesión interactiva. La sesión interactiva es útil cuando es necesario ejecutar varias sesiones diferentes en el mismo script. Sin embargo, usé la sesión no interactiva para simplificar.

prosti
fuente
0

Use el modo de ejecución ansioso de Tensorflow, que es el más reciente.

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

Así que tuve un caso diferente en el que necesitaba asignar valores antes de ejecutar una sesión, así que esta era la forma más fácil de hacerlo:

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

aquí estoy creando una variable y asignándole valores al mismo tiempo

Prabhant Singh
fuente
-10

Hay un enfoque más sencillo:

x = tf.Variable(0)
x = x + 1
print x.eval()
Gordon Erlebacher
fuente
3
la operación estaba examinando el uso de tf.assign, no la adición.
vega