InvalidArgumentError:不兼容的形状:[3]与[4]

时间:2020-05-16 05:54:41

标签: python tensorflow

我尝试with help from this example首次使用tf.data API,我拥有3D体数据,即,我拥有(深度,高度,通道,深度,高度,宽度,通道)。

def readfile(filenames):
    name = filenames[0]
    string = tf.read_file(name)
    image = tf.image.decode_image(string, channels=3)
    bunch = image
    for name in filenames[1:]:
        string = tf.read_file(name)
        image = tf.image.decode_image(string, channels=3)
        bunch = tf.concat([bunch,image],1)   
    return bunch

with tf.device("/cpu:0"):

    #read data file paths, shape [5,100] (five elements each with 100 frames)
    train_dataset = tf.data.Dataset.from_tensor_slices(train_files) 
    #train_dataset.element_spec gives shape=(100,)
    train_dataset = train_dataset.map(readfile, num_parallel_calls=16)
    #readfile function takes element of shape (1,100) and 
    #reads each frame and appends to a tensor which is returned 
    #train_dataset.element_spec gives shape=<unknown>
    train_dataset = train_dataset.map(lambda x: tf.random_crop(x, (100, 256, 256, 3)))
    #train_dataset.element_spec gives shape=(100, 256, 256, 3)
    train_dataset = train_dataset.batch(1)

    x = train_dataset.make_one_shot_iterator().get_next()

错误:

Traceback (most recent call last):
  File "/anaconda3/envs/myenv/lib/python3.6/site-packages/tensorflow_core/python/client/session.py", line 1365, in _do_call
return fn(*args)
  File "/anaconda3/envs/myenv/lib/python3.6/site-packages/tensorflow_core/python/client/session.py", line 1350, in _run_fn
target_list, run_metadata)
  File "/anaconda3/envs/myenv/lib/python3.6/site-packages/tensorflow_core/python/client/session.py", line 1443, in _call_tf_sessionrun
run_metadata)
tensorflow.python.framework.errors_impl.InvalidArgumentError: {{function_node __inference_Dataset_map_<lambda>_258}} Incompatible shapes: [3] vs. [4]
 [[{{node random_crop/GreaterEqual}}]]
 [[IteratorGetNext]]

我无法理解该错误。我认为这意味着tf.random_crop提供3D张量形状,而.get_next()部分提供4D张量?我对应用了train_dataset函数后的readfile的形状感到怀疑,为什么形状为<unknown>,我会期望像(?,100,256,256,3)。我要去哪里错了?

有没有办法可视化train_dataset中的帧,所以我知道我做对了吗?我一直使用feed_dict,并且可以很容易地看到numpy框架,因此我确切地知道我在喂什么。

1 个答案:

答案 0 :(得分:1)

基于有限的信息,我在代码中同时看到了基本错误和技术错误:

我假设您有(等于)5个带有100帧的目录。您有一个具有5行100列的张量train_dataset,每个元素是一个目录,该元素中的每个值是一个路径

基本知识:

  1. 这不是错误,但我不了解。当您运行train_dataset = train_dataset.map(readfile, num_parallel_calls=16)时,实际上是在发送形状为(100,)的张量,而不是您认为的(1,100),但是,您的函数编写正确并且正在以正确的方式处理(100,)
  2. 您正在读取文件内部bunch = tf.concat([bunch,image],1)。这将沿着尺寸1连接图像。如果图像为(100,100,3),则您正在创建(100,100 * 100,3)作为readfile的输出。因此,您实际上将获得(5,100,100 * 100,3)作为train_dataset.map(readfile, num_parallel_calls=16)的返回值。也许您想在这里使用堆栈。此外,“ MapDataset”对象没有属性“ elem_spec”,所以当train_dataset的elem_spec的输出击败我时,您如何变得未知

技术:

  1. 现在,这是您的代码在train_dataset = train_dataset.map(lambda x: tf.random_crop(x, (100, 256, 256, 3)))处中断的行。 x的形状为(5,100,100 * 100,3),因此random_crop所采用的每个元素都是(100,100 * 100,3),您无法将其裁剪为(100,256,256,3)。这就是有效利用裁剪的方式
image = tf.image.random_crop(image, size=[28, 28, 1]) # Random crop back to 28x28

这里的图像是一批形状为(34,34,1)的图像

所有我认为的事情都由您要使用tf.stack的地方使用tf.concat引起。