orome
orome

Reputation: 48616

Does 'tf.assign' return its argument?

The Tensorflow documentation says that tf.assign(ref, ...) returns ref, but it appears instead (not surprisingly) to return a Tensor (attached to the assign op):

import tensorflow as tf
sess = tf.InteractiveSession()

Q = tf.Variable(tf.constant(range(1, 12)))
sess.run(tf.global_variables_initializer())
qop = tf.assign(Q, tf.zeros(Q.shape, tf.int32))#.eval()

print(Q.eval())
print(qop.eval())
print(Q.eval())

produces

[ 1  2  3  4  5  6  7  8  9 10 11]
[0 0 0 0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0 0 0 0]

demonstrating that the argument Q and what's returned qop behave differently (and that Q is unchanged until qop is executed).

Is the return value of tf.assign described correctly in the documentation?

Upvotes: 2

Views: 342

Answers (1)

Jadiel de Armas
Jadiel de Armas

Reputation: 8802

Take a look at the documentation of Tensorflow about operations. tf.assign returns an Operation, which represents a graph node that performs computations on tensors. You use the operations to compose a graph of computations. Those computations actually occur at a later time, when you call eval on any of the operations of the graph.

In your example qop is the definition of an operation that assigns zeros to variable Q. The graph of your example would look something like Q --> qep. For pedagogical purposes, let's change the order of your code to something like this:

Q = tf.Variable(tf.constant(range(1, 12)))

Q.eval()  # Error: Variable has not been initalized.

sess.run(tf.global_variables_initializer())

Q.eval()  # Output: array([ 1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11], dtype=int32)

qop = tf.assign(Q, tf.zeros(Q.shape, tf.int32))

Q.eval() # Output: array([ 1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11], dtype=int32)

qop.eval()

Q.eval() # Output array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int32)

The first time you evaluate Q you get an error, because the variable represented by Q does not contain anything in it yet. But after you run sess.run(tf.global_variables_initializer()) the error goes away. That is because that line of code runs an operation that initializes all the global variables of the current graph. When you run Q.eval() after defining the qop operation, Q still has the same values, because operation qop was defined, but not yet executed. Once you execute qop (qop.eval) is that the value of the variable represnted by Q changes.

Upvotes: 1

Related Questions