29

I wanted to initialize some of the variable on my network with numpy values. For the sake of the example consider:

init=np.random.rand(1,2)
tf.get_variable('var_name',initializer=init)

when I do that I get an error:

ValueError: Shape of a new variable (var_name) must be fully defined, but instead was <unknown>.

why is it that I am getting that error?

To try to fix it I tried doing:

tf.get_variable('var_name',initializer=init, shape=[1,2])

which yielded a even weirder error:

TypeError: 'numpy.ndarray' object is not callable

I tried reading the docs and examples but it didn't really help.

Is it not possible to initialize variables with numpy arrays with the get_variable method in TensorFlow?

Charlie Parker
  • 5,884
  • 57
  • 198
  • 323

3 Answers3

42

The following works, if you convert the constant NumPy array into a constant Tensor:

init = tf.constant(np.random.rand(1, 2))
tf.get_variable('var_name', initializer=init)

The documentation for get_variable is a little lacking indeed. Just for your reference, the initializer argument has to be either a TensorFlow Tensor object (which can be constructed by calling tf.constant on a numpy value in your case), or a 'callable' that takes two arguments, shape and dtype, the shape and data type of the value that it's supposed to return. Again, in your case, you can write the following in case you wanted to use the 'callable' mechanism:

init = lambda shape, dtype: np.random.rand(*shape)
tf.get_variable('var_name', initializer=init, shape=[1, 2])
Rohan Saxena
  • 3,133
  • 2
  • 16
  • 34
keveman
  • 8,427
  • 1
  • 38
  • 46
  • 2
    [This](http://stackoverflow.com/questions/111234/what-is-a-callable-in-python) is a great answer to your question. – keveman Jul 04 '16 at 19:13
  • A `callable` is a function or something that can be called like a function. – hpaulj Jul 04 '16 at 22:43
  • `tf.get_variable('var_name', initializer=np.random.rand(1, 2))` seems to work now on r0.10. – ldavid Aug 23 '16 at 20:40
  • It seems now this has slightly changed such that the `lambda` takes an additional input called `partition_info`, so I had to modify the definition to be `init = lambda shape, dtype, partition_info: np.random.rand(*shape)`. – user1953384 Aug 01 '18 at 11:14
10

@keveman Answered well, and for supplement, there is the usage of tf.get_variable('var_name', initializer=init), the tensorflow document did give a comprehensive example.

import numpy as np
import tensorflow as tf

value = [0, 1, 2, 3, 4, 5, 6, 7]
# value = np.array(value)
# value = value.reshape([2, 4])
init = tf.constant_initializer(value)

print('fitting shape:')
tf.reset_default_graph()
with tf.Session() :
    x = tf.get_variable('x', shape = [2, 4], initializer = init)
    x.initializer.run()
    print(x.eval())

    fitting shape :
[[0.  1.  2.  3.]
[4.  5.  6.  7.]]

print('larger shape:')
tf.reset_default_graph()
with tf.Session() :
    x = tf.get_variable('x', shape = [3, 4], initializer = init)
    x.initializer.run()
    print(x.eval())

    larger shape :
[[0.  1.  2.  3.]
[4.  5.  6.  7.]
[7.  7.  7.  7.]]

print('smaller shape:')
tf.reset_default_graph()
with tf.Session() :
    x = tf.get_variable('x', shape = [2, 3], initializer = init)

    * <b>`ValueError`< / b > : Too many elements provided.Needed at most 6, but received 8

https://www.tensorflow.org/api_docs/python/tf/constant_initializer

Nezha
  • 101
  • 1
  • 5
4

If the variable was already created (ie from some complex function), just use load.

https://www.tensorflow.org/api_docs/python/tf/Variable#load

x_var = tf.Variable(tf.zeros((1, 2), tf.float32))
x_val = np.random.rand(1,2).astype(np.float32)

sess = tf.Session()
x_var.load(x_val, session=sess)

# test
assert np.all(sess.run(x_var) == x_val)
James D
  • 1,580
  • 1
  • 13
  • 9