I'm trying to reshape some of my data with Dataset API. In particular, I have created a dataset like this:
dataset = tf.data.TFRecordDataset(filenames)
dataset = dataset.map(parse).filter(filter_empty).batch(batch_size)
After this if I print my shape within map function I get the following:
def print_shape(x):
print(x.shape)
dataset.map(print_shape)
>>> (?, ?, ?)
So the shape of the batch is not clear and hence if I want to reshape some of my variables by accessing them via x.shape, it fails with an error:
TypeError: Failed to convert object of type <class 'list'> to Tensor. Contents: [1, 1, Dimension(None)]. Consider casting elements to a supported type.
How can I access shape within dataset creation so that I cam reshape some of my variables?
Another detail: I use eager mode.
Solved via using tf.shape instead.
Solved via using
tf.shapeinstead.
How did you use tf.shape to solve this issue?
I have been facing similar issues ,try using tf.expand_dims.
x=tf.expand_dims(x, -1)
This helped me sorting the issue.
Solved via using
tf.shapeinstead.
How did you use tf.shape to solve this issue? could you please give more details about the solution?
@Liusandian @Shruthi-Sampathkumar
Let's assume x is a Tensor of shape [10, ?, ?]. It can be a tensor with a undetermined size when it is TF 1.x, running non-eagerly on TF 2.x (e.g. using tf.function + autograph), or running inside tf.Dataset (as in @nd7141's case).
x.shape will give you [10, None, None]. You cannot reshape it because you do not know the dimension statically. For example, some tensor manipulations tf.reshape(x, [-1, x.shape[1], x.shape[0]]) will fail.
However, h = tf.shape(x)[1]; w = tf.shape(x)[2] will let h, w be symbolic or graph-mode tensors (integer) that will contain a dimension of x. The value will be determined runtime. In such a case, tf.reshape(x, [-1, w, h]) will produce a (symbolic) tensor of shape [?, ?, ?] (still unknown) whose tensor shape will be known on runtime.
TL;DR) tf.shape(x) gives a tf.Tensor of integer dtype whose elements are not None (it is just undetermined), where as x.shape gives a static value as a list/tuple. But if any shape dimension is unknown, it will be None.
Most helpful comment
@Liusandian @Shruthi-Sampathkumar
Let's assume
xis a Tensor of shape [10, ?, ?]. It can be a tensor with a undetermined size when it is TF 1.x, running non-eagerly on TF 2.x (e.g. usingtf.function+ autograph), or running insidetf.Dataset(as in @nd7141's case).x.shapewill give you[10, None, None]. You cannot reshape it because you do not know the dimension statically. For example, some tensor manipulationstf.reshape(x, [-1, x.shape[1], x.shape[0]])will fail.However,
h = tf.shape(x)[1]; w = tf.shape(x)[2]will leth,wbe symbolic or graph-mode tensors (integer) that will contain a dimension ofx. The value will be determined runtime. In such a case,tf.reshape(x, [-1, w, h])will produce a (symbolic) tensor of shape[?, ?, ?](still unknown) whose tensor shape will be known on runtime.TL;DR)
tf.shape(x)gives atf.Tensorof integer dtype whose elements are notNone(it is just undetermined), where asx.shapegives a static value as a list/tuple. But if any shape dimension is unknown, it will beNone.