1

I am giving variable size images (all 278 images of different size 139 of each category) input to my cnn model. As a fact that cnn required fixed size images, so from here i got solution for this is to make input_shape=(None,Nonen,1) (for tensorflow backend and gray scale). but this solution doesnot work with flatten layer, so from their only i got solution of using GlobleMaxpooling or Globalaveragepooling. So from uses these facrts i am making a cnn model in keras to train my network with following code:

import os,cv2
import numpy as np
from sklearn.utils import shuffle
from keras import backend as K
from keras.utils import np_utils
from keras.models import Sequential
from keras.optimizers import SGD,RMSprop,adam
from keras.layers import Conv2D, MaxPooling2D,BatchNormalization,GlobalAveragePooling2D
from keras.layers import Activation, Dropout, Flatten, Dense
from keras import regularizers
from keras import initializers 
from skimage.io import imread_collection
from keras.preprocessing import image
from keras import Input
import keras
from keras import backend as K

#%%

PATH = os.getcwd()
# Define data path
data_path = PATH+'/current_exp'
data_dir_list = os.listdir(data_path)

img_rows=None
img_cols=None
num_channel=1

# Define the number of classes
num_classes = 2

img_data_list=[]

for dataset in data_dir_list:
    img_list=os.listdir(data_path+'/'+ dataset)
    print ('Loaded the images of dataset-'+'{}\n'.format(dataset))
    for img in img_list:
        input_img=cv2.imread(data_path + '/'+ dataset + '/'+ img,0)
        img_data_list.append(input_img)

img_data = np.array(img_data_list)

if num_channel==1:
    if K.image_dim_ordering()=='th':
        img_data= np.expand_dims(img_data, axis=1) 
        print (img_data.shape)
    else:
        img_data= np.expand_dims(img_data, axis=4) 
        print (img_data.shape)

else:
    if K.image_dim_ordering()=='th':
        img_data=np.rollaxis(img_data,3,1)
        print (img_data.shape)


#%%
num_classes = 2

#Total 278 sample, 139 for 0 category and 139 for category 1
num_of_samples = img_data.shape[0]

labels = np.ones((num_of_samples,),dtype='int64')

labels[0:138]=0
labels[138:]=1

x,y = shuffle(img_data,labels, random_state=2)
y = keras.utils.to_categorical(y, 2)

model = Sequential()
model.add(Conv2D(32,(2,2),input_shape=(None,None,1),activation='tanh',kernel_initializer=initializers.glorot_uniform(seed=100)))
model.add(Conv2D(32, (2,2),activation='tanh'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Conv2D(64, (2,2),activation='tanh'))
model.add(Conv2D(64, (2,2),activation='tanh'))
model.add(MaxPooling2D())
model.add(Dropout(0.25))
#model.add(Flatten())
model.add(GlobalAveragePooling2D())
model.add(Dense(256,activation='tanh'))
model.add(Dropout(0.25))
model.add(Dense(2,activation='softmax'))
model.compile(loss='categorical_crossentropy',optimizer='rmsprop',metrics=['accuracy'])
model.fit(x, y,batch_size=1,epochs=5,verbose=1)

but i am getting following error:

ValueError: Error when checking input: expected conv2d_1_input to have 4 dimensions, but got array with shape (278, 1)

how to solve it.

Hitesh
  • 1,285
  • 6
  • 20
  • 36

2 Answers2

1

In the docs for Conv2D it says that the input tensor has to be in this format:

(samples, channels, rows, cols)

I believe you can't have a variable input size unless your network is fully convolutional.

Maybe what you want to do is to keep it to a fixed input size, and just resize the image to that size before feeding it into your network?

NorwegianClassic
  • 935
  • 8
  • 26
1

Your array with input data cannot have variable dimensions (this is a numpy limitation).

So the array, instead of being a regular array of numbers with 4 dimensions is being created as an array of arrays.

You should fit each image individually because of this limitation.

for epoch in range(epochs):    
    for img,class in zip(x,y):

        #expand the first dimension of the image to have a batch size 
        img = img.reshape((1,) + img.shape)) #print and check there are 4 dimensions, like (1, width, height, 1).    
        class = class.reshape((1,) + class.shape)) #print and check there are two dimensions, like (1, classes).

        model.train_on_batch(img,class,....)
Daniel Möller
  • 84,878
  • 18
  • 192
  • 214