How to apply normalization to images in testing phase when using keras ImageDataGenerator?

Gamuza picture Gamuza · Nov 7, 2018 · Viewed 8.8k times · Source

I'm trying to predict a new image using trained model. My accuracy is 95%. But the predict_classes always return the first label [0] whatever I input. I guess one of the reason is I use featurewise_center=True and samplewise_center=True in ImageDataGenerator. I think I should do the same thing on my input image. But I can't find what did these function do to the image.

Any suggestion will be appreciated.

ImageDataGenerator code:

train_datagen = ImageDataGenerator(
samplewise_center=True,
rescale=1. / 255,
shear_range=30,
zoom_range=30,
rotation_range=20,
width_shift_range=0.2,
height_shift_range=0.2)

test_datagen = ImageDataGenerator(
samplewise_center=True,
rescale=1. / 255,
shear_range=30,
zoom_range=30,
rotation_range=20,
width_shift_range=0.2,
height_shift_range=0.2,
horizontal_flip=True)

Prediction code (I use 100*100*3 image to train the model):

model = load_model('CNN_model.h5')
img = cv2.imread('train/defect/6.png')
img = cv2.resize(img,(100,100))
img = np.reshape(img,[1,100,100,3])
img = img/255.

classes = model.predict_classes(img)

print (classes)

updated 11/14:

I change my code to predict image like below. But the model still predict the same class even if I feed the image which I have used to train my model(and got 95% accuarcy). Is there anything I missed?

model = load_model('CNN_model.h5')
img = cv2.imread('train/defect/6.png')
img = cv2.resize(img,(100,100))
img = np.reshape(img,[1,100,100,3])
img = np.array(img, dtype=np.float64) 
img = train_datagen.standardize(img)

classes = model.predict_classes(img)
print(classes)

Answer

today picture today · Nov 7, 2018

You need to use the standardize() method of ImageDataGenerator instance. From Keras documentation:

standardize

standardize(x)

Applies the normalization configuration to a batch of inputs.

Arguments

  • x: Batch of inputs to be normalized.

Returns

The inputs, normalized.

So it would be like this:

img = cv2.imread('train/defect/6.png')
img = cv2.resize(img,(100,100))
img = np.reshape(img,[1,100,100,3])
img = train_datagen.standardize(img)

classes = model.predict_classes(img)

Note that it would apply the rescaling as well so there is no need to do it yourself (i.e. remove img = img/255.).

Further, keep in mind that since you have set featurewise_ceneter=True you need to use fit() method of generator before using it for training:

train_datagen.fit(training_data)

# then use fit_generator method
model.fit_generator(train_datagen, ...)