Cannot take the length of Shape with unknown rank

心不动则不痛 提交于 2020-06-27 07:41:35

问题


I have a neural network, from a tf.data data generator and a tf.keras model, as follows (a simplified version-because it would be too long):

dataset = ...

A tf.data.Dataset object that with the next_x method calls the get_next for the x_train iterator and for the next_y method calls the get_next for the y_train iterator. Each label is a (1, 67) array in one-hot form.

Layers:

input_tensor = tf.keras.layers.Input(shape=(240, 240, 3))  # dim of x
output = tf.keras.layers.Flatten()(input_tensor)
output= tf.keras.Dense(67, activation='softmax')(output)  # 67 is the number of classes

Model:

model = tf.keras.models.Model(inputs=input_tensor, outputs=prediction)
model.compile(optimizer=tf.train.AdamOptimizer(), loss=tf.losses.softmax_cross_entropy, metrics=['accuracy'])
model.fit_generator(gen(dataset.next_x(), dataset.next_y()), steps_per_epochs=100)

gen is defined like this:

def gen(x, y):
    while True:
        yield(x, y)

My problem is that when I try to run it, I get an error in the model.fit part:

ValueError: Cannot take the length of Shape with unknown rank.

Any ideas are appreciated!


回答1:


Could you post a longer stack-trace? I think your problem might be related to this recent tensorflow issue:

https://github.com/tensorflow/tensorflow/issues/24520

There's also a simple PR that fixes it (not yet merged). Maybe try it out yourself?

EDIT

Here is the PR: open tensorflow/python/keras/engine/training_utils.py

replace the following (line 232 at the moment):

  if (x.shape is not None
      and len(x.shape) == 1

with this:

  if tensor_util.is_tensor(x):
    x_shape_ndims = x.shape.ndims if x.shape is not None else None
  else:
    x_shape_ndims = len(x.shape)

  if (x_shape_ndims == 1



回答2:


I found out what was wrong. Actually I have to run next batch in a tf.Session before yielding it. Here is how it works (I don't write the rest of the code, since it stays the same):

model.fit_generator(gen(), steps_per_epochs=100)

def gen():
    with tf.Session() as sess:
        next_x = dataset.next_x()
        next_y = dataset.next_y()
        while True:
            x_batch = sess.run(next_x)
            y_batch = sess.run(next_y)
            yield x_batch, y_batch



回答3:


For the issue Cannot take the length of Shape with unknown rank, Thanks to above answer, I solved by add output_shape to from_generator according to this issue comment.

In my case, I was using Dataset.from_generator for dataset pipeline.

Before:

Dataset.from_generator(_generator_factory, 
                       output_types=(tf.float32, tf.int8))

Working code for me:

Dataset.from_generator(_generator_factory, 
                       output_types = (tf.float32, tf.int8),
                       output_shapes = (
                           tf.TensorShape([2, 224, 224, 3]), 
                           tf.TensorShape([1,])
                       ))
                                        

Also found this dataset official guide from tensorflow indicates that:

...

The output_shapes argument is not required but is highly recomended as many tensorflow operations do not support tensors with unknown rank. If the length of a particular axis is unknown or variable, set it as None in the output_shapes.

...



来源:https://stackoverflow.com/questions/53597406/cannot-take-the-length-of-shape-with-unknown-rank

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!