momo
momo

Reputation: 1122

InvalidArgumentError: Incompatible shapes: [3] vs. [4]

I'm trying to use the tf.data API for the first time with help from this example, I have 3D volume data, i.e instead of (height, width, channel), I have (depth, height, width, channel).

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()

Error:

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]]

I can't understand the error. I think it means the tf.random_crop is giving a 3D tensor shape while .get_next() part is giving a 4D tensor? I have doubt with the shape of train_dataset after readfile function is applied, why is the shape <unknown>, I would expect something like (?,100,256,256,3). Where am I going wrong?

Is there a way to visualise the frames in train_dataset so I know I'm doing it right? I have always used feed_dict and there it's easy to visualise the numpy frames so I know exactly what I'm feeding.

Upvotes: 1

Views: 1895

Answers (1)

figs_and_nuts
figs_and_nuts

Reputation: 5743

Based upon the limited information i see both fundamental and technical errors in your code:

I assume you have (equivalent of) 5 directories with 100 frames. You have a tensor train_dataset with 5 rows and 100 columns with each element being a directory and each value in the element being a path

Fundamental:

  1. This isnt an error but i lapse of understanding. When you run train_dataset = train_dataset.map(readfile, num_parallel_calls=16) you are actually sending in tensors of shape (100,) instead of (1,100) that you thought but, your function is written right and is handling (100,) the right way
  2. Inside readfile you are doing bunch = tf.concat([bunch,image],1). This will concatenate your images along dimension 1. If your images are (100,100,3) then you are creating (100,100*100,3) as the output of readfile. So, you are effectively getting (5,100,100*100,3) as the return value of train_dataset.map(readfile, num_parallel_calls=16). Maybe you want to use stack here. Also, 'MapDataset' object has no attribute 'elem_spec' so how you are getting unknown as the output of elem_spec of train_dataset beats me

Technical:

  1. Now,this is the line your code is breaking at train_dataset = train_dataset.map(lambda x: tf.random_crop(x, (100, 256, 256, 3))). x is shaped (5,100,100*100,3) so each element that random_crop is taking is (100,100*100,3) and you cannot crop it to (100,256,256,3). This is how cropping is used effectively
image = tf.image.random_crop(image, size=[28, 28, 1]) # Random crop back to 28x28

Here image is a batch of images of shape (34,34,1)

All things considered i think Your issue is generating from using tf.concat where you wanted to use tf.stack

Upvotes: 1

Related Questions