【问题标题】:Cannot take the length of Shape with unknown rank无法获取具有未知等级的形状的长度
【发布时间】:2019-10-26 12:21:19
【问题描述】:

我有一个神经网络,来自一个tf.data 数据生成器和一个tf.keras 模型,如下(简化版——因为它会太长):

dataset = ...

使用next_x 方法为x_train 迭代器调用get_next 并为next_y 方法调用get_nexty_train 迭代器的tf.data.Dataset 对象。每个标签都是一个单热形式的(1, 67) 数组。

层:

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 = 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 是这样定义的:

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

我的问题是,当我尝试运行它时,model.fit 部分出现错误:

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

感谢任何想法!

【问题讨论】:

  • 我有同样的错误。我正在通过数据集 api 读取 tfrecords 并将结果传递给 model.fit 方法,但它给出了与上述相同的错误。你知道如何解决这个问题吗?
  • @user238607,数据集产生的记录的类型和形状是什么?
  • 你能分享生成数据的函数吗?
  • 您是否尝试过在生成器中调用 next_x()next_y() 而不是通过参数调用它?
  • @DanielMöller:我已经在这里单独提出了我的问题:stackoverflow.com/questions/53851793/…你能看一下吗?

标签: python tensorflow keras deep-learning


【解决方案1】:

您能发布更长的堆栈跟踪吗?我认为您的问题可能与最近的 tensorflow 问题有关:

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

还有一个简单的 PR 可以修复它(尚未合并)。可以自己试试吗?

编辑

这是公关: 打开tensorflow/python/keras/engine/training_utils.py

替换以下内容(目前为第 232 行):

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

用这个:

  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

【讨论】:

  • 虽然此链接可能会回答问题,但最好在此处包含答案的基本部分并提供链接以供参考。如果链接页面发生更改,仅链接答案可能会失效。 - From Review
  • 已编辑以包含 PR 更改
【解决方案2】:

我发现出了什么问题。实际上,我必须在 tf.Session 中的下一批 run 才能产生它。 这是它的工作原理(我不编写其余代码,因为它保持不变):

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】:

    对于问题Cannot take the length of Shape with unknown rank, 感谢上面的回答,我根据这个issue commentoutput_shape添加到from_generator解决了。

    就我而言,我使用Dataset.from_generator 进行数据集管道。

    之前:

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

    我的工作代码:

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

    还发现this dataset official guide from tensorflow表示:

    ...

    output_shapes 参数不是必需的,但强烈推荐因为许多 tensorflow 操作不支持未知等级的张量。如果特定轴的长度未知或变量,在 output_shapes 中将其设置为 None。

    ...

    【讨论】:

      猜你喜欢
      • 2019-05-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多