1
votes

I used this code to produce my dataset in keras. but when I implement my code it produces this error:

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

and I can not solve it. could you please tell me what is the problem? I expand the dimension before using in network but it does not work! could you please answer me fast, due to I search for several days but I could not find the solution and I do not have enough time:

import os,cv2
import numpy as np
import matplotlib.pyplot as plt

from sklearn.utils import shuffle
from sklearn.cross_validation import train_test_split

from keras import backend as K
#K.set_image_dim_ordering('th')

from keras.utils import np_utils
from keras.models import Sequential
from keras.layers.core import Dense, Dropout, Activation, Flatten
from keras.layers.convolutional import Convolution2D, MaxPooling2D
from keras.optimizers import SGD,RMSprop,adam

#%%

PATH = os.getcwd()
# Define data path
data_path = r"E:\PhD\thesis\deepwatermark\databasetest\train"
data_dir_list = os.listdir(data_path)

img_rows=512
img_cols=512
num_channel=1
num_epoch=20

# Define the number of classes
num_classes = 7

labels_name={'CRP':0,'GF':1,'GN':2,'JPG':3,'MED':4,'ROT':5,'SP':6}

img_data_list=[]
labels_list = []

for dataset in data_dir_list:
    img_list=os.listdir(data_path+'/'+ dataset)
    print ('Loading the images of dataset-'+'{}\n'.format(dataset))
    label = labels_name[dataset]
    for img in img_list:
        input_img=cv2.imread(data_path + '/'+ dataset + '/'+ img )
        input_img=cv2.cvtColor(input_img, cv2.COLOR_BGR2GRAY)
        input_img_resize=cv2.resize(input_img,(512,512))
        img_data_list.append(input_img_resize)
        labels_list.append(label)

img_data = np.array(img_data_list)
img_data = img_data.astype('float32')
img_data /= 255
print (img_data.shape)

labels = np.array(labels_list)
# print the count of number of samples for different classes
print(np.unique(labels,return_counts=True))
# convert class labels to on-hot encoding
Y = np_utils.to_categorical(labels, num_classes)

#Shuffle the dataset
x,y = shuffle(img_data,Y, random_state=2)
# Split the dataset
X_train, X_test, y_train, y_test = train_test_split(x, y, test_size=0.2, random_state=2)
img_data= np.expand_dims(img_data, axis=4)** 
print (img_data.shape)


# Defining the model
input_shape=img_data[0].shape

model = Sequential()

model.add(Convolution2D(32, 3,3,border_mode='same',input_shape=input_shape))
model.add(Activation('relu'))
model.add(Convolution2D(32, 3, 3))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.5))

model.add(Convolution2D(64, 3, 3))
model.add(Activation('relu'))
#model.add(Convolution2D(64, 3, 3))
#model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.5))

model.add(Flatten())
model.add(Dense(64))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(num_classes))
model.add(Activation('softmax'))

#sgd = SGD(lr=0.01, decay=1e-6, momentum=0.9, nesterov=True)
#model.compile(loss='categorical_crossentropy', optimizer=sgd,metrics=["accuracy"])
model.compile(loss='categorical_crossentropy', optimizer='rmsprop',metrics=["accuracy"])

# Viewing model_configuration

model.summary()
model.get_config()
model.layers[0].get_config()
model.layers[0].input_shape         
model.layers[0].output_shape            
model.layers[0].get_weights()
np.shape(model.layers[0].get_weights()[0])
model.layers[0].trainable

#%%
# Training
hist = model.fit(X_train, y_train, batch_size=16, nb_epoch=num_epoch, verbose=1, validation_data=(X_test, y_test))

my new code with generator is here, did you see any problem? my dataset is the same as before.

import numpy as np
import matplotlib.pyplot as plt
from keras.preprocessing.image import ImageDataGenerator
from sklearn.utils import shuffle
from sklearn.cross_validation import train_test_split
from keras import backend as K
#K.set_image_dim_ordering('th')

from keras.utils import np_utils
from keras.models import Sequential
from keras.layers.core import Dense, Dropout, Activation, Flatten
from keras.layers.convolutional import Conv2D, MaxPooling2D
from keras.optimizers import SGD,RMSprop,adam


train_datagen = ImageDataGenerator(
        rescale=1./255,
        shear_range=0.2,
        zoom_range=0.2,
        horizontal_flip=True)
#
valid_datagen = ImageDataGenerator(
        rescale=1./255,
        shear_range=0.2,
        zoom_range=0.2,
        horizontal_flip=True)
#
test_datagen = ImageDataGenerator(rescale=1./255)
#
train_generator = train_datagen.flow_from_directory(
    directory=r"E:\databasetest\train",
    target_size=(512, 512),
    color_mode="grayscale",
    batch_size=32,
    class_mode="categorical",
    shuffle=True,
    seed=42
)
#
valid_generator = valid_datagen.flow_from_directory(
   directory=r"E:\databasetest\validation",
    target_size=(512, 512),
    color_mode="grayscale",
    batch_size=32,
    class_mode="categorical",
    shuffle=True,
    seed=42
)
#
test_generator = test_datagen.flow_from_directory(
    directory=r"E:\databasetest\test",
    target_size=(512, 512),
    color_mode="grayscale",
    batch_size=16,
    class_mode=None,
    shuffle=False,
    seed=42
)
#
## neural network model
model = Sequential()
model.add(Conv2D(32, (3,3),border_mode='same', input_shape = (512, 512, 1), activation = 'relu'))
model.add(Activation('relu'))
model.add(Conv2D(32, 3, 3))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.5))

model.add(Conv2D(64, 3, 3))
model.add(Activation('relu'))
#model.add(Convolution2D(64, 3, 3))
#model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.5))

model.add(Flatten())
model.add(Dense(64))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(7))
model.add(Activation('softmax'))

model.summary()

model.compile(loss = 'categorical_crossentropy',
              optimizer = 'rmsprop',
              metrics = ['accuracy'])
STEP_SIZE_TRAIN=train_generator.n//train_generator.batch_size
STEP_SIZE_VALID=valid_generator.n//valid_generator.batch_size
model.fit_generator(generator=train_generator,
                    steps_per_epoch=STEP_SIZE_TRAIN,
                    validation_data=valid_generator,
                    validation_steps=STEP_SIZE_VALID,
                    epochs=10
)

but when I implement it I received this error again:

ResourceExhaustedError: OOM when allocating tensor with shape[32,32,512,512] and type float on /job:localhost/replica:0/task:0/device:GPU:0 by allocator GPU_0_bfc [[Node: conv2d_1/convolution = Conv2D[T=DT_FLOAT, data_format="NCHW", dilations=[1, 1, 1, 1], padding="SAME", strides=[1, 1, 1, 1], use_cudnn_on_gpu=true, _device="/job:localhost/replica:0/task:0/device:GPU:0"](conv2d_1/convolution-0-TransposeNHWCToNCHW-LayoutOptimizer, conv2d_1/kernel/read)]]

1
Simply put the expansion code before shuffling code: img_data= np.expand_dims(img_data, axis=3) should be before x,y = shuffle(img_data,Y, random_state=2).today
when I do it, I see a new error: "ResourceExhaustedError (see above for traceback): OOM when allocating tensor with shape[16,64,253,253] and type float on /job:localhost/replica:0/task:0/device:GPU:0 by allocator GPU_0_bfc" what should I do now? I am a beginner and I do not understand these problems :((((maedeh

1 Answers

0
votes
    for img in img_list:
        input_img=cv2.imread(data_path + '/'+ dataset + '/'+ img )
        input_img=cv2.cvtColor(input_img, cv2.COLOR_BGR2GRAY)
        input_img_resize=cv2.resize(input_img,(512,512))
    --->input_img_resize = np.expand_dims(input_img_resize, axis=-1)
        img_data_list.append(input_img_resize)
        labels_list.append(label)

this will make all your arrays 512x512x1, which should do the trick and ends up zith an array of shape (454, 512, 512, 1). You sure you want to use grayscaled images though?

Another thing is this snippet of code

X_train, X_test, y_train, y_test = train_test_split(x, y, test_size=0.2, `random_state=2)`
img_data= np.expand_dims(img_data, axis=4)**
print (img_data.shape)

You apply another dimension to your img_data, after you've already declared x_train, etc. And in the end you feed x_train, which is not extended, hence the error. If you do it in the beginning, and remove the expanding in the end, then your code should work.

EDIT OOM

I recommend creating a separate question for the OOM problem, so more people see it. Possible problems are the size of the images and the batch size. Reduce the image size to 64 x 64 and change the batch size to 5. If that still raises the error, try also kicking out this dense layer.

model.add(Dense(64))
model.add(Activation('relu'))
model.add(Dropout(0.5))

If these reductions still cause the error then I have the following questions: are you running on GPU/CPU, and which one?

Just to repeat myself: the code is fine, just needs a few changes perhaps.