Stack Exchange
How to fix the reshape process of train and test in CNN via Python
I have a problem about fixing reshape process of train and test in CNN via Python.
While train set has (270, 660, 3) , test set has (163, 600, 3). Because of this, these are not the same shape.
How can I fix it?
Here is my block shown below.
Here is CNN
classifier = Sequential()
classifier.add(Convolution2D(filters = 32, 
                             kernel_size=(3,3), 
                             data_format= "channels_last", 
                             input_shape=(270, 660, 3), 
                             activation="relu")
              )


classifier.add(MaxPooling2D(pool_size = (2,2)))

classifier.add(Convolution2D(32, (3, 3), activation = 'relu'))
classifier.add(MaxPooling2D(pool_size = (2, 2)))

classifier.add(Convolution2D(32, (3, 3), activation = 'relu'))
classifier.add(MaxPooling2D(pool_size = (2, 2)))

classifier.add(Flatten())

classifier.add(Dense(units = 128, activation = 'relu'))
classifier.add(Dense(units = 1, activation = 'sigmoid'))

classifier.compile(optimizer = 'adam', loss = 'binary_crossentropy', metrics = ['accuracy'])

Fitting the CNN to the images
train_datagen = ImageDataGenerator(
        rescale=1./255,
        shear_range=0.2,
        zoom_range=0.2,
        horizontal_flip=True)
test_datagen = ImageDataGenerator(rescale=1./255)

Create Training Test and Training Test
training_set = train_datagen.flow_from_directory(train_path, 
                                                 target_size=(270, 660), 
                                                 batch_size=32, 
                                                 class_mode='binary')

test_set = test_datagen.flow_from_directory(
        test_path,
        target_size=(270, 660),
        batch_size=32,
        class_mode='binary')

Fit the CNN to the training set and then evaluate our test set
classifier.fit_generator(
        training_set,
        steps_per_epoch=50,
        epochs=30,
        validation_data=test_set,
        validation_steps=200)

Prediction
directory = os.listdir(test_genuine_path)
print(directory[3])

print("Path : ", test_genuine_path + "/" + directory[3])

imgFGenuine = cv2.imread(test_genuine_path + "/" + directory[3])
plt.imshow(imgFGenuine)

pred = classifier.predict(np.expand_dims(imgFGenuine,0)) # ERROR
print("Probability of Genuine Signature : ", "%.2f" % (1 - pred))

The error :
ValueError: Error when checking input: expected conv2d_19_input to have 4 dimensions, but got array with shape (163, 660, 3)


Here is my answer
After this code plt.imshow(imgFGenuine) , I fix the issue to write down these code snippets.
imgFGenuine = cv2.resize(imgFGenuine, (270, 660))
imgFGenuine = imgFGenuine.reshape(270, 660,3)


You defined the input shape for a single sample. It expects 4-D shape. Check these
link and link
This is what you will have. I suggest you add a separate validation set to be used during training, which is a standard practise.
training_set = train_datagen.flow_from_directory(train_path, 
                                                 target_size=(270, 660), 
                                                 batch_size=32, 
                                                 class_mode='binary')

validation_set = validation_datagen.flow_from_directory(
        validation_path,
        target_size=(270, 660),
        batch_size=32,
        class_mode='binary')

test_set = test_datagen.flow_from_directory(
        test_path,
        target_size=(163, 660),
        batch_size=32,
        class_mode='binary')

classifier.fit_generator(
        training_set,
        steps_per_epoch=50,
        epochs=30,
        validation_data=validation_set,
        validation_steps=200)

### or train without validation set

classifier.fit_generator(
        training_set,
        steps_per_epoch=50,
        epochs=30)


To predict, you need to use predict_generator and include the batch size
batch_size = 100 

pred = classifier.predict_generator(test_set, batch_size)
print("Probability of Genuine Signature : ", "%.2f" % (1 - pred))

Based on this reference this

I already looked through the link you shared. How can I fix this line ? classifier.predict(np.expand_dims(imgFGenuine,0))

another issue i noticed is test size (163, 600, 3). You have trained and validated with (270, 660, 3). Try to reshape test to (163, 660, 3) and then ensure both train and test are 4-D. To summarize train = (270, 660, 3, 1), validation = (270, 660, 3, 1), and test = (163, 660, 3, 1)

@olahsymboI When I changed target_size=(163, 660) of test_set , there is an error in fitting model. Can you say me which code I should be able to change?

There is no validation path in dataset. Train path and test path are only defined. How can I reshape imgFGenuine (163, 600, 3)`

@TonyBrand ok, i have removed validation from training
