ValueError: Shapes (None, None) and (None, 296, 296, 6) are incompatible

Question:

I am trying to build a model for image recognition (images have 6 different classes) using Cov2D but after many tests every time I get the error "ValueError: Shapes (None, None) and (None, 296, 296, 6) are incompatible".

from sklearn.preprocessing import normalize
im_shape = (300, 300)

val_data_generator = ImageDataGenerator(preprocessing_function=normalize,validation_split=0.2)

train_generator = data_generator.flow_from_directory(TRAINING_DIR, target_size=im_shape, shuffle=True,
                                                class_mode='categorical', batch_size=BATCH_SIZE, subset="training")

validation_generator = val_data_generator.flow_from_directory(TRAINING_DIR, target_size=im_shape, shuffle=False,
                                                class_mode='categorical', batch_size=BATCH_SIZE, subset="validation")


test_generator = ImageDataGenerator(preprocessing_function=normalize)
test_generator = test_generator.flow_from_directory(TEST_DIR, target_size=im_shape, shuffle=False,
                                                class_mode='categorical', batch_size=BATCH_SIZE)
nb_train_samples = train_generator.samples
nb_validation_samples = validation_generator.samples
nb_test_samples = test_generator.samples
num_classes  = 6

model = models.Sequential()
model.add(layers.Conv2D(32, (3, 3),activation="elu", kernel_initializer="glorot_uniform", input_shape=(300, 300, 3)))
model.add(layers.Dropout(0.2))
model.add(layers.BatchNormalization())
model.add(layers.Conv2D(64, (3, 3), activation="elu", kernel_initializer="glorot_uniform"))
model.add(layers.Dropout(0.2))
model.add(layers.BatchNormalization())
model.add(layers.Dense(100, activation="elu", kernel_initializer="he_normal"))
model.add(layers.Dropout(0.2))
model.add(layers.BatchNormalization())
model.add(layers.Dense(100, activation="elu", kernel_initializer="he_normal"))
model.add(layers.Dropout(0.2))
model.add(layers.BatchNormalization())
model.add(layers.Dense(6, activation="softmax", kernel_initializer="glorot_uniform"))

model.compile(optimizer=Adam(), loss='categorical_crossentropy',metrics=['accuracy'])
history = model.fit(
train_generator,
steps_per_epoch=nb_train_samples // BATCH_SIZE,
epochs=150,
callbacks = [keras.callbacks.EarlyStopping(monitor='val_loss', patience=30,verbose=1)],
validation_data=validation_generator,
verbose = 1,
validation_steps=nb_validation_samples // BATCH_SIZE)
Asked By: I'mStuckOnLine911

||

Answers:

The error you’re getting is because the loss function is expecting an input (Batch_size, No_Categories) and was incompatible with the model’s output.

This is the description of your model:
enter image description here

When I checked your model with an image of correct shape, it doesn’t give any errors and gives the desired output.
enter image description here

But what I believe you’re trying to do is to get the end shape as (1,6). You have missed the step where you have to flatten your Convolution layers. That is usually done, when you’ve done writing your convolution layers and now are about to define Dense Layers.So, Try to change your model code to do the following.

model = models.Sequential()
model.add(layers.Conv2D(32, (3, 3),activation="elu", kernel_initializer="glorot_uniform", input_shape=(300, 300, 3)))
model.add(layers.Dropout(0.2))
model.add(layers.BatchNormalization())
model.add(layers.Conv2D(64, (3, 3), activation="elu", kernel_initializer="glorot_uniform"))
model.add(layers.Dropout(0.2))
model.add(layers.BatchNormalization())
model.add(layers.Dense(100, activation="elu", kernel_initializer="he_normal"))
model.add(layers.Dropout(0.2))
model.add(layers.BatchNormalization())
#Changed Line below
model.add(layers.Flatten())
model.add(layers.Dense(100, activation="elu", kernel_initializer="he_normal"))
model.add(layers.Dropout(0.2))
model.add(layers.BatchNormalization())
model.add(layers.Dense(6, activation="softmax", kernel_initializer="glorot_uniform"))

model.compile(optimizer=Adam(), loss='categorical_crossentropy',metrics=['accuracy'])

# Testing:
my_image = np.ones((1,300,300,3), dtype = 'uint8')
output = model(my_image)
print(output.shape)

The output will be (1,6). (1 being the batch size and 6 being the classes you wanted). What I suggest is to always check your model with a dummy numpy data after initializing the model.

Answered By: Sangam Khanal

use this code before training,

BATCH_SIZE = 32 # Change Batch size according to you
model.build(input_shape=(BATCH_SIZE, 300, 300, 3))
Answered By: aman raj