简体   繁体   中英

ValueError: Error when checking : expected conv2d_1_input to have shape (28, 28, 1) but got array with shape (58000, 28, 28)

I have successfully built a binary classifier and I am using it to predict some data. All the data are MNIST grayscale digits of size(28,28) and I have 58000 images. My code looks like:

from keras.preprocessing.image import ImageDataGenerator, array_to_img, img_to_array, load_img
from keras.models import Sequential
from keras.layers import Conv2D, MaxPooling2D
from keras.layers import Activation, Dropout, Flatten, Dense
from keras import backend as K
import tensorflow
import glob
from PIL import Image
import numpy as np

img_width, img_height = 28, 28#all MNIST images are of size (28*28)

train_data_dir = '/Binary Classifier/data/train'#train directory generated by train_cla
validation_data_dir = '/Binary Classifier/data/val'#validation directory generated by val_cla
train_samples = 40000
validation_samples = 10000
epochs = 2
batch_size = 512

if K.image_data_format() == 'channels_first':
    input_shape = (1, img_width, img_height)
else:
    input_shape = (img_width, img_height, 1)

#build a sequential model to train data
model = Sequential()
model.add(Conv2D(32, (3, 3), input_shape=input_shape))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))

model.add(Conv2D(32, (3, 3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))

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

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

model.compile(loss='binary_crossentropy',
              optimizer='rmsprop',
              metrics=['accuracy'])

train_datagen = ImageDataGenerator(#train data generator
    rescale=1. / 255,
    shear_range=0.2,
    zoom_range=0.2,
    horizontal_flip=True)

val_datagen = ImageDataGenerator(rescale=1. / 255)#validation data generator

train_generator = train_datagen.flow_from_directory(#train generator
    train_data_dir,
    target_size=(img_width, img_height),
    batch_size=batch_size,
    class_mode='binary',color_mode = 'grayscale')

validation_generator = val_datagen.flow_from_directory(#validation generator
    validation_data_dir,
    target_size=(img_width, img_height),
    batch_size=batch_size,
    class_mode='binary',color_mode = 'grayscale')

model.fit_generator(#fit the generator to train and validate the model
    train_generator,
    steps_per_epoch=train_samples // batch_size,
    epochs=epochs,
    validation_data=validation_generator,
    validation_steps=validation_samples // batch_size)

filelist = glob.glob('/Binary Classifier/data/image_data/*.png')
x = np.array([np.array(Image.open(fname)) for fname in filelist])
ones=model.predict(x)

I got an error at ones=model.predict(x):

ValueError: Error when checking : expected conv2d_1_input to have 4 dimensions, but got array with shape (58000, 28, 28)

To fix this, I add:

x = np.expand_dims(x, axis=0)

before the execution of the last line. But now I received another error:

ValueError: Error when checking : expected conv2d_1_input to have shape (28, 28, 1) but got array with shape (58000, 28, 28)

I have two confusions:

  1. Why doesn't np.expand_dims() change my array dimension as it should?
  2. Why does model.predict() sometimes ask for a 4D input but sometimes 3D((28,28,1) in my case)? What does the function actually look for?

Thanks in advance!

Reshape your images from (28, 28) to (28, 28, 1) before stacking them up. So you get a final array of shape (5800, 28, 28, 1).

Or maybe you should do

x = np.expand_dims(x, axis=3)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM