Malik M Barakathullah
Malik M Barakathullah

Reputation: 11

Tensorflow ValueError: Input 0 of layer conv2d is incompatible with the layer: : expected min_ndim=4, found ndim=2. Full shape received: (None, 1)

The input layer takes the shape of (128,128,1) i.e., single channel images:

inputs = keras.Input(shape=(128,128,1))

The model is fed from the generators for train and test sets as follows:

ds_train = tf.data.Dataset.list_files(str(PATH))
ds_test = tf.data.Dataset.list_files(str(PATH.parent/ 'test'/'*.png'))

ds_train = (ds_train.map(load_augment,num_parallel_calls=tf.data.AUTOTUNE)
            .shuffle(578)
            .batch(batch_size))

ds_test = ds_test.shuffle(144).batch(batch_size)

The mapping function load_augment() is given below:

@tf.function()
def load_augment(image_file)
  image1, image2 = load(image_file) # loads using tf.io and returns two images
  image1, image2 = resize(image1, image2, 128, 128) # resizes pairs of images
  if tf.random.uniform(()) > 0.5:
     image1 = tf.image.flip_left_right(image1) #flips the images
     image2 = tf.image.flip_left_right(image2)
  image1, image2 = resize(image1, image2, img_size[0]+20, img_size[1]+20)
  image1, image2 = random_crop(image1, image2) # random-crops to get a pair of images of 128x128
  return image2, image2

The model is compiled and trained as

model.compile(optimizer=optimizer, loss="sparse_categorical_crossentropy")

callbacks = [
    keras.callbacks.ModelCheckpoint("a_name.h5")
]

epochs = 200
model.fit(ds_train, epochs=epochs, 
          validation_data=ds_test, 
          callbacks=callbacks) # ds_test is the test dataset shown above

This throws the error after running for the first epoch:

ValueError: Input 0 of layer conv2d is incompatible with the layer: : expected min_ndim=4, found ndim=2. Full shape received: (None, 1)

I will appreciate if anyone can help.

More information:

The the functions resize() and random_crop() writes tensors as they use tf.image tools.

I checked the shapes of the tensors in the generator as follows:

ds = ds_train.take(1)
iter_ds = iter(ds)
ds1 = next(iter_ds)
ds1[0].shape # returns TensorShape([4, 128, 128, 1])
ds1[1].shape # returns TensorShape([4, 128, 128, 1])

Upvotes: 0

Views: 398

Answers (1)

Malik M Barakathullah
Malik M Barakathullah

Reputation: 11

The issue got solved when I applied a mapping function, load() on the test set. So, I changed the the line ds_test = ds_test.shuffle(144).batch(batch_size) by

ds_test = (ds_test.map(load,num_parallel_calls=tf.data.AUTOTUNE)
            .shuffle(144)
            .batch(batch_size))

Without the mapping function load(), the test set was containing only filenames and not pairs of images it is supposed to have had.

The function load() was written such that it acted on each element of the test dataset and loaded the files and spilt them into to pairs of images.

Upvotes: 1

Related Questions