I'm trying to update a two dimensional tensor in a nested while_loop()
. When passing the variable to the second loop however, I cannot updated it using tf.assign()
as it throws this error:
ValueError: Sliced assignment is only supported for variables
Somehow it works fine if I create the variable outside the while_loop and use it only in the first loop.
How can I modify my 2D tf variable in the second while loop?
(I'm using python 2.7 and TensorFlow 1.2)
My code:
import tensorflow as tf
import numpy as np
tf.reset_default_graph()
BATCH_SIZE = 10
LENGTH_MAX_OUTPUT = 31
it_batch_nr = tf.constant(0)
it_row_nr = tf.Variable(0, dtype=tf.int32)
it_col_nr = tf.constant(0)
cost = tf.constant(0)
it_batch_end = lambda it_batch_nr, cost: tf.less(it_batch_nr, BATCH_SIZE)
it_row_end = lambda it_row_nr, cost_matrix: tf.less(it_row_nr, LENGTH_MAX_OUTPUT+1)
def iterate_batch(it_batch_nr, cost):
cost_matrix = tf.Variable(np.ones((LENGTH_MAX_OUTPUT+1, LENGTH_MAX_OUTPUT+1)), dtype=tf.float32)
it_rows, cost_matrix = tf.while_loop(it_row_end, iterate_row, [it_row_nr, cost_matrix])
cost = cost_matrix[0,0] # IS 1.0, SHOULD BE 100.0
return tf.add(it_batch_nr,1), cost
def iterate_row(it_row_nr, cost_matrix):
# THIS THROWS AN ERROR:
cost_matrix[0,0].assign(100.0)
return tf.add(it_row_nr,1), cost_matrix
it_batch = tf.while_loop(it_batch_end, iterate_batch, [it_batch_nr, cost])
sess = tf.InteractiveSession()
sess.run(tf.global_variables_initializer())
out = sess.run(it_batch)
print(out)
tf.Variable
objects cannot be used as loop variables in a while loop, as loop variables are implemented differently.
So either create your variable outside the loop and update it yourself with tf.assign in each iteration or manually keep track of the updates as you do with loop variables (by returning their updated values from the loop lambdas, and in your case using the value from the inner loop as the new value for the outer loop).
Got this to work, with @AlexandrePassos help, by placing the Variable outside the while_loop. However, I also had to force the execution of the commands using tf.control_dependencies()
(as the operations are not directly used on the loop variable). The loop now looks like this:
cost_matrix = tf.Variable(np.ones((LENGTH_MAX_OUTPUT+1, LENGTH_MAX_OUTPUT+1)), dtype=tf.float32)
def iterate_batch(it_batch_nr, cost):
it_rows = tf.while_loop(it_row_end, iterate_row, [it_row_nr])
with tf.control_dependencies([it_rows]):
cost = cost_matrix[0,0]
return tf.add(it_batch_nr,1), cost
def iterate_row(it_row_nr):
a = tf.assign(cost_matrix[0,0], 100.0)
with tf.control_dependencies([a]):
return tf.add(it_row_nr,1)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With