How to Assign a Value to a Tensorflow Variable

How to assign a value to a TensorFlow variable?

In TF1, the statement x.assign(1) does not actually assign the value 1 to x, but rather creates a tf.Operation that you have to explicitly run to update the variable.* A call to Operation.run() or Session.run() can be used to run the operation:

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

(* In fact, it returns a tf.Tensor, corresponding to the updated value of the variable, to make it easier to chain assignments.)

However, in TF2 x.assign(1) will now assign the value eagerly:

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

How to assign a value to a tf.Variable in TensorFlow without using tf.assign

Here is an example of how you could do what (I think) you want:

import tensorflow as tf
import numpy as np

with tf.Graph().as_default(), tf.Session() as sess:
params = [[1.0, 2.0, 3.0]]
M_gt = np.eye(4)
M_gt[0:3, 3] = [4.0, 5.0, 6.0]

M = tf.Variable(tf.eye(4, batch_shape=[1]), dtype=tf.float32)
params_t = tf.constant(params, dtype=tf.float32)

shape_m = tf.shape(M)
batch_size = shape_m[0]
num_m = shape_m[1]
num_params = tf.shape(params_t)[1]

last_column = tf.concat([tf.tile(tf.transpose(params_t)[tf.newaxis], (batch_size, 1, 1)),
tf.zeros((batch_size, num_m - num_params, 1), dtype=params_t.dtype)], axis=1)
replace = tf.concat([tf.zeros((batch_size, num_m, num_m - 1), dtype=params_t.dtype), last_column], axis=2)

r = tf.range(num_m)
ii = r[tf.newaxis, :, tf.newaxis]
jj = r[tf.newaxis, tf.newaxis, :]
mask = tf.tile((ii < num_params) & (tf.equal(jj, num_m - 1)), (batch_size, 1, 1))
M_replaced = tf.where(mask, replace, M)

loss = tf.nn.l2_loss(M_replaced - M_gt[np.newaxis])
optimizer = tf.train.AdamOptimizer(0.001)
train_op = optimizer.minimize(loss)
sess = tf.Session()
init = tf.global_variables_initializer()
sess.run(init)
M_val, M_replaced_val = sess.run([M, M_replaced])
print('M:')
print(M_val)
print('M_replaced:')
print(M_replaced_val)

Output:

M:
[[[ 1. 0. 0. 0.]
[ 0. 1. 0. 0.]
[ 0. 0. 1. 0.]
[ 0. 0. 0. 1.]]]
M_replaced:
[[[ 1. 0. 0. 1.]
[ 0. 1. 0. 2.]
[ 0. 0. 1. 3.]
[ 0. 0. 0. 1.]]]

How to assign tf.Variables using placeholders?

If you really want to do that with a tf.Variable, you can do that in two ways. You can use the desired expression as the initialization value for the variable. Then, when you initialize the variable, you pass the x value in the feed_dict.

import tensorflow as tf

# Placeholder shape must be specified or use validate_shape=False in tf.Variable
x = tf.placeholder(tf.int32, (), name="x")
# Initialization value for variable is desired expression
y = tf.Variable(2 * x ** 2 + 5, name="y")
with tf.Session() as sess:
for i in range(1,10):
# Initialize variable on each iteration
sess.run(y.initializer, feed_dict={x: i})
# Show value
print("Value of y for x =", i , "is:", sess.run(y))

Alternatively, you can do the same thing with a tf.assign operation. In this case, you pass the x value when you run the assignment.

import tensorflow as tf

# Here placeholder shape is not stricly required as tf.Variable already gives the shape
x = tf.placeholder(tf.int32, name="x")
# Specify some initialization value for variable
y = tf.Variable(0, name="y")
# Assign expression value to variable
y_assigned = tf.assign(y, 2 * x** 2 + 5)
# Initialization can be skipped in this case since we always assign new value
with tf.Graph().as_default(), tf.Session() as sess:
for i in range(1,10):
# Assign vale to variable in each iteration (and get value after assignment)
print("Value of y for x =", i , "is:", sess.run(y_assigned, feed_dict={x: i}))

However, as pointed out by Nakor, you may not need a variable if y is simply supposed to be the result of that expression for whatever value x takes. The purpose of a variable is to hold a value that will be maintained in future calls to run. So you would need it only if you want to set y to some value depending on x, and then maintain the same value even if x changes (or even if x is not provided at all).

Assign value inside tf.tensor

Yea because eager tensors are tensors that are immutable, meaning the value inside can't be changed, you have to use tf.Variable if you want to make a tensor that is changeable as such

import tensorflow as tf
import numpy as np

pred_window = tf.reshape(tf.range(1 * 12 * 4, dtype=tf.float32), (1, 12, 4))
pred_window_var = tf.Variable(pred_window)
'''
<tf.Tensor: shape=(1, 12, 4), dtype=float32, numpy=
array([[[ 0., 1., 2., 3.],
[ 4., 5., 6., 7.],
[ 8., 9., 10., 11.],
[12., 13., 14., 15.],
[16., 17., 18., 19.],
[20., 21., 22., 23.],
[24., 25., 26., 27.],
[28., 29., 30., 31.],
[32., 33., 34., 35.],
[36., 37., 38., 39.],
[40., 41., 42., 43.],
[44., 45., 46., 47.]]], dtype=float32)>'''

# Note that you must use the assign function along with the exact dimensions you are trying to fill up in this case here [1, 1, 4]
pred_window_var[:, 0:1, :].assign(tf.constant([[[1, 1, 1, 1]]], dtype=tf.float32))
pred_window_var[:, 1:2, :].assign(np.array([[[1, 1, 1, 2]]], dtype=np.float32))
'''
<tf.Variable 'UnreadVariable' shape=(1, 12, 4) dtype=float32, numpy=
array([[[ 1., 1., 1., 1.],
[ 1., 1., 1., 2.],
[ 8., 9., 10., 11.],
[12., 13., 14., 15.],
[16., 17., 18., 19.],
[20., 21., 22., 23.],
[24., 25., 26., 27.],
[28., 29., 30., 31.],
[32., 33., 34., 35.],
[36., 37., 38., 39.],
[40., 41., 42., 43.],
[44., 45., 46., 47.]]], dtype=float32)>'''

Tensorflow Assign and Save Variable

I executed this code in Tensorflow 1.x and found the same error, then I observed that if we dont use 'global_variables_initializer'("#sess.run(tf.compat.v1.global_variables_initializer()") after restoring the model, we get the updated variable(y=3) otherwise it takes first global initailized variable value which is y=2.

Find below replicated code and output:

import tensorflow as tf

tf.compat.v1.reset_default_graph()

g = tf.Graph()
with g.as_default(), tf.compat.v1.Session(graph=g) as sess:
w = tf.Variable(2,name = "VARIABLE")
sess.run(tf.compat.v1.global_variables_initializer())
y = sess.run(w)
print('initial value', y)

ww = tf.compat.v1.assign(w, 3)
y = sess.run(ww)
print('changed value', y)

saver = tf.compat.v1.train.Saver()
save_path = saver.save(sess, './test_1')


model_path = "./test_1.meta"

g = tf.Graph()
with g.as_default():
sess = tf.compat.v1.Session(graph=g)
saver = tf.compat.v1.train.import_meta_graph(model_path, clear_devices=True)
saver.restore(sess, model_path.replace('.meta', ''))
#sess.run(tf.compat.v1.global_variables_initializer())
gb = tf.compat.v1.global_variables()
print(gb)

w = gb[0]
y = sess.run(w)
print('loaded value', y)

Output:

initial value 2
changed value 3
INFO:tensorflow:Restoring parameters from ./test_1
[<tf.Variable 'VARIABLE:0' shape=() dtype=int32>]
loaded value 3

For more information, Please click here

How to change a value of a variable in TensorFlow?

After assigning a new value to the variable c with one of the methods you used, you need to evaluate it:

c.eval(session=s)

or

s.run(c)

Assign value to Variable in Tensorflow

You can't assign it directly but you can use .assign() operation to make it happen, here is the documentation. Also after you assign you have to run the operation using .run() or .eval(). In my opinion, this code should work:

layerOp = layer[0].assign(0)
sess.run(layerOp)

Please find this post for reference.



Related Topics



Leave a reply



Submit