tf.assign al segmento variable no funciona dentro de tf.while_loop

¿Qué está mal con el siguiente código? La tf.assign funciona bien cuando se aplica a una porción de una tf.Variable si ocurre fuera de un bucle. Pero, en este contexto, da el error de abajo.

 import tensorflow as tf v = [1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0] n = len(v) a = tf.Variable(v, name = 'a') def cond(i, a): return i < n def body(i, a): tf.assign(a[i], a[i-1] + a[i-2]) return i + 1, a i, b = tf.while_loop(cond, body, [2, a]) 

resultados en:

 Traceback (most recent call last): File "", line 1, in  File "/home/hrbigelow/anaconda3/lib/python3.6/site-packages/tensorflow/python/ops/control_flow_ops.py", line 3210, in while_loop result = loop_context.BuildLoop(cond, body, loop_vars, shape_invariants) File "/home/hrbigelow/anaconda3/lib/python3.6/site-packages/tensorflow/python/ops/control_flow_ops.py", line 2942, in BuildLoop pred, body, original_loop_vars, loop_vars, shape_invariants) File "/home/hrbigelow/anaconda3/lib/python3.6/site-packages/tensorflow/python/ops/control_flow_ops.py", line 2879, in _BuildLoop body_result = body(*packed_vars_for_body) File "/home/hrbigelow/ai/lb-wavenet/while_var_test.py", line 11, in body tf.assign(a[i], a[i-1] + a[i-2]) File "/home/hrbigelow/anaconda3/lib/python3.6/site-packages/tensorflow/python/ops/state_ops.py", line 220, in assign return ref.assign(value, name=name) File "/home/hrbigelow/anaconda3/lib/python3.6/site-packages/tensorflow/python/ops/array_ops.py", line 697, in assign raise ValueError("Sliced assignment is only supported for variables") ValueError: Sliced assignment is only supported for variables 

Su variable no es una salida de las operaciones que se ejecutan dentro de su bucle, es una entidad externa que vive fuera del bucle. Entonces no tienes que proporcionarlo como un argumento.

Además, debe imponer la actualización para que tenga lugar, por ejemplo, utilizando tf.control_dependencies en el body .

 import tensorflow as tf v = [1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0] n = len(v) a = tf.Variable(v, name = 'a') def cond(i): return i < n def body(i): op = tf.assign(a[i], a[i-1] + a[i-2]) with tf.control_dependencies([op]): return i + 1 i = tf.while_loop(cond, body, [2]) sess = tf.InteractiveSession() tf.global_variables_initializer().run() i.eval() print(a.eval()) # [ 1 1 2 3 5 8 13 21 34 55 89] 

Es posible que desee ser cauteloso y configurar el valor de parallel_iterations=1 para hacer que el bucle se ejecute secuencialmente.

Tiene sentido desde una perspectiva CUDA no permitir la asignación de índices individuales, ya que niega todos los beneficios de rendimiento de la computación paralela heterogénea.

Sé que esto agrega un poco de sobrecarga computacional pero funciona.

 import tensorflow as tf v = [1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0] n = len(v) a = tf.Variable(v, name = 'a',dtype=tf.float32) def cond(i, a): return i < n def body(i, a1): e = tf.eye(n,n)[i] a1 = a1 + e *(a1[i-1] + a1[i-2]) return i + 1, a1 i, b = tf.while_loop(cond, body, [2, a]) with tf.Session() as sess: sess.run(tf.global_variables_initializer()) print('i: ',sess.run(i)) print('b: ',sess.run(b)) 

Estuve ejecutando esto unas cuantas veces y no es consistente. Pero los segmentos variables funcionan dentro del bucle while.

Intenté dividir la gráfica dentro del cuerpo porque los resultados son incorrectos a veces.

La respuesta correcta (11, array([ 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89])) se devuelve a veces pero no siempre.

 import tensorflow as tf v = [1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0] n = len(v) a1 = tf.Variable(v, name = 'a') def cond(i, _): return i < n s = tf.InteractiveSession() s.run(tf.global_variables_initializer()) def body( i, _): x = a1[i-1] y = a1[i-2] z = tf.add(x,y) op = a1[i].assign( z ) with tf.control_dependencies([op]): #Edit This fixed the inconsistency. increment = tf.add(i, 1) return increment, op print(s.run(tf.while_loop(cond, body, [2, a1])))