6

Say I have a certain the Tensor x whose dimensions are not defined upon graph initialization.

I can get its shape using:

x_shape = tf.shape(input=x)

Now if I want to create a variable based on the values defined in x_shape using:

y = tf.get_variable(variable_name="y", shape=[x_shape[0], 10])

I get an error, since the values passed to the argument shape must be int and not Tensor. How can I create such a dynamically shaped variable without using placeholders?

Filipe Aleixo
  • 3,924
  • 3
  • 41
  • 74

5 Answers5

3

I'm running out of time so this is quick and dirty, but maybe it helps you to get to your solution... It's based on this (dynamic size for tf.zeros) but extends the idea to tf.Variables. Since your variable needs to be initialized anyway - I choose 0s...

import tensorflow as tf
I1_ph = tf.placeholder(name = "I1",shape=(None,None,None),dtype=tf_dtype)

zerofill = tf.fill(tf.shape(I1_ph), 0.0)
myVar = tf.Variable(0.0)
updateMyVar = tf.assign(myVar,zerofill,validate_shape=False)

res, = sess.run([updateMyVar], { I1_ph:np.zeros((1,2,2)) } )
print ("dynamic variable shape",res.shape)

res, = sess.run([updateMyVar], { I1_ph:np.zeros((3,5,2)) } )
print ("dynamic  variable shape",res.shape)
Max
  • 485
  • 4
  • 13
  • 2
    However, in this case `updateMyVar` is no longer a `Variable`, it's simply a `Tensor`. So you wouldn't be able to do operations like tf.scatter_update or slice assignment. – Ataxias Mar 21 '19 at 23:45
2

You can use x.get_shape():

y = tf.get_variable('y', shape=[x.get_shape()[0], 10])
Vijay Mariappan
  • 16,921
  • 3
  • 40
  • 59
1
import tensorflow as tf

x = tf.zeros(shape=[10,20])
x_shape = x.get_shape().as_list()
y = tf.get_variable(shape=x_shape, name = 'y')

Update

You can't create tf.Variable with unknown size. For example this code is not valid:

y = tf.get_variable(shape=[None, 10], name = 'y')
Vladimir Bystricky
  • 1,320
  • 1
  • 11
  • 13
0

First argument is variable name.

x = tf.zeros(shape=[10,20])
x_shape = x.shape
variable_name ='y'
y = tf.get_variable(variable_name, shape=[x_shape[0], x_shape[1]])
Ishant Mrinal
  • 4,898
  • 3
  • 29
  • 47
  • My bad, I forgot to put the variable_name argument on my example. I should have written y = tf.get_variable(name="y", shape=[x_shape[0], x_shape[1]]). The problem remains after this change. – Filipe Aleixo Aug 17 '17 at 15:28
  • I guess the example I gave is not a good representation of my actual problem. On my case, the variable x doesn't have a defined shape upon graph initialization, so I am unable to use x.shape to define the shape of y – Filipe Aleixo Aug 17 '17 at 15:32
  • then you can just create a copy of the target variable. – Ishant Mrinal Aug 17 '17 at 15:33
  • I want to set the shape of y such that only the first dimension is inferred from x. I think now the example illustrates my problem well. – Filipe Aleixo Aug 17 '17 at 15:39
0

To the best of my knowledge, you cannot create a Variable with a dynamic shape through the shape argument, instead you have to pass this dynamic shape through the initializer of the tf.Variable.

This should work:

zero_init = tf.fill([x_shape[0], 10], tf.constant(0))
# Initialize
y = tf.get_variable(
    "my_var", shape=None, validate_shape=False, initializer=zero_init
)

Note that the shape has to be defined before, or with the first execution of tf.Session.run(...). So if your x is a placeholder, you will need to feed a value for it.

ffrank
  • 62
  • 1
  • 8