Conv2d输入参数不匹配

时间:2018-04-13 15:42:09

标签: keras keras-layer keras-2

我将可变大小的图像(每个类别的不同大小139的所有278个图像)输入到我的cnn模型。由于cnn需要固定大小的图像,所以从here我得到的解决方案是使input_shape =(None,Nonen,1)(对于tensorflow后端和灰度)。但是这个解决方案不适用于展平层,所以从他们唯一的解决方案是使用GlobleMaxpooling或Globalaveragepooling。所以从使用这些设备我在keras中制作一个cnn模型,用以下代码训练我的网络:

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)

但是我收到了以下错误:

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

如何解决它。

2 个答案:

答案 0 :(得分:1)

docs for Conv2D中,它表示输入张量必须采用以下格式:

  

(样本,渠道,行,列)

除非您的网络是fully convolutional,否则我认为您不能拥有可变的输入大小。

也许您想要做的是将其保持为固定的输入尺寸,并在将图像输入网络之前将图像调整为该尺寸?

答案 1 :(得分:1)

具有输入数据的数组不能具有可变维度(这是一个numpy限制)。

因此,数组不是具有4维的常规数字数组,而是作为数组数组创建。

由于此限制,您应该单独调整每个图像。

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,....)