10

I am trying to generate a random variable and use it twice. However, when I use it the second time, the generator creates a second random variable that is not identical to the first. Here is code to demonstrate:

import numpy as np
import tensorflow as tf

# A random variable
rand_var_1 = tf.random_uniform([5],0,10, dtype = tf.int32, seed = 0)
rand_var_2 = tf.random_uniform([5],0,10, dtype = tf.int32, seed = 0)

#Op1
z1 = tf.add(rand_var_1,rand_var_2)

#Op2
z2 = tf.add(rand_var_1,rand_var_2)

init = tf.initialize_all_variables()

with tf.Session() as sess:
    sess.run(init)
    z1_op = sess.run(z1)
    z2_op = sess.run(z2)
    print(z1_op,z2_op)

I want z1_op and z2_op to be equal. I think this is because the random_uniform op gets called twice. Is there a way to use TensorFlow (without using NumPy) to achieve this?

(My use case is more complicated, but this is the distilled question.)

mrry
  • 125,488
  • 26
  • 399
  • 400
Srikiran
  • 309
  • 1
  • 3
  • 9

2 Answers2

15

The current version of your code will randomly generate a new value for rand_var_1 and rand_var_2 on each call to sess.run() (although since you set the seed to 0, they will have the same value within a single call to sess.run()).

If you want to retain the value of a randomly-generated tensor for later use, you should assign it to a tf.Variable:

rand_var_1 = tf.Variable(tf.random_uniform([5], 0, 10, dtype=tf.int32, seed=0))
rand_var_2 = tf.Variable(tf.random_uniform([5], 0, 10, dtype=tf.int32, seed=0))

# Or, alternatively:
rand_var_1 = tf.Variable(tf.random_uniform([5], 0, 10, dtype=tf.int32, seed=0))
rand_var_2 = tf.Variable(rand_var_1.initialized_value())

# Or, alternatively:
rand_t = tf.random_uniform([5], 0, 10, dtype=tf.int32, seed=0)
rand_var_1 = tf.Variable(rand_t)
rand_var_2 = tf.Variable(rand_t)

...then tf.initialize_all_variables() will have the desired effect:

# Op 1
z1 = tf.add(rand_var_1, rand_var_2)

# Op 2
z2 = tf.add(rand_var_1, rand_var_2)

init = tf.initialize_all_variables()

with tf.Session() as sess:
    sess.run(init)        # Random numbers generated here and cached.
    z1_op = sess.run(z1)  # Reuses cached values for rand_var_1, rand_var_2.
    z2_op = sess.run(z2)  # Reuses cached values for rand_var_1, rand_var_2.
    print(z1_op, z2_op)   # Will print two identical vectors.
greeness
  • 15,956
  • 5
  • 50
  • 80
mrry
  • 125,488
  • 26
  • 399
  • 400
  • How would this work if I don't have control of `sess.run` ? I am using it in an Estimator, so all the session management is hidden. My function `g()` needs to call `f(t)` twice, with the same `t`. However, on every call to `g()`, I want a different `t`. Basically, I want to cache the result of `tf.random_uniform()` for the whole duration of my function `g()`. – Ciprian Tomoiagă Feb 14 '18 at 14:05
  • @CiprianTomoiagă: Ask a new question if you haven't done so already. – Peter O. Sep 22 '19 at 19:47
  • makes sense. I think I had figured it out. I'll writeup a Q/A after holiday. Thanks ! – Ciprian Tomoiagă Sep 27 '19 at 13:34
0

Your question has the same issue as this question, in that if you call random_uniform twice you will get two results, and as such you need to set your second variable to the value of the first. That means that, assuming you are not changing rand_var_1 later, you can do this:

rand_var_1 = tf.random_uniform([5],0,10, dtype = tf.int32, seed = 0)
rand_var_2 = rand_var_1

But, that said, if you want z1 and z2 to be equal, why have separate variables at all? Why not do:

import numpy as np
import tensorflow as tf

# A random variable
rand_var = tf.random_uniform([5],0,10, dtype = tf.int32, seed = 0)
op = tf.add(rand_var,rand_var)

init = tf.initialize_all_variables()

with tf.Session() as sess:
    sess.run(init)
    z1_op = sess.run(op)
    z2_op = sess.run(op)
    print(z1_op,z2_op)
Community
  • 1
  • 1
Nathaniel Ford
  • 20,545
  • 20
  • 91
  • 102
  • I will get two results, but since I am setting both the seeds to zero, the two results must be the same. Setting the second value to the first would not work for me because in my actual use case, the second value is a different function of the random variable. I apologize for my misleading example. And similarly, 'z1_op' and 'z2_op' are different in my code. I was just using them here to illustrate that different random numbers are being used in each step. – Srikiran Jan 20 '16 at 04:02