简体   繁体   English

使用keras ImageDataGenerator时,如何在测试阶段对图像应用归一化?

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

I'm trying to predict a new image using trained model. 我正在尝试使用经过训练的模型来预测新图像。 My accuracy is 95%. 我的准确率是95%。 But the predict_classes always return the first label [0] whatever I input. 但是无论我输入什么内容,predict_classes始终返回第一个标签[0]。 I guess one of the reason is I use featurewise_center=True and samplewise_center=True in ImageDataGenerator . 我猜原因之一是我在ImageDataGenerator使用featurewise_center=Truesamplewise_center=True 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: ImageDataGenerator代码:

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): 预测代码(我使用100 * 100 * 3图像来训练模型):

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: 更新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). 但是,即使我提供了用于训练模型的图像(并获得了95%的准确度),该模型仍然可以预测相同的类。 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)

You need to use the standardize() method of ImageDataGenerator instance. 您需要使用ImageDataGenerator实例的standardize()方法。 From Keras documentation : Keras文档中

standardize 规范

 standardize(x) 

Applies the normalization configuration to a batch of inputs. 将规范化配置应用于一批输入。

Arguments 参数

  • x: Batch of inputs to be normalized. x:待标准化的输入批次。

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 (ie remove img = img/255. ). 请注意,它也会应用重新缩放,因此您无需自己进行缩放(即,删除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: 此外,请记住,由于已设置featurewise_ceneter=True ,因此在将其用于训练之前,需要使用generator的fit()方法:

train_datagen.fit(training_data)

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

Not a complete answer but some information: 不是完整的答案,而是一些信息:

From this link that is referenced in keras docs: 从keras文档中引用的此链接

# this is the augmentation configuration we will use for training
train_datagen = ImageDataGenerator(
    rescale=1. / 255,
    shear_range=0.2,
    zoom_range=0.2,
    horizontal_flip=True)

# this is the augmentation configuration we will use for testing:
# only rescaling
test_datagen = ImageDataGenerator(rescale=1. / 255)

train_generator = train_datagen.flow_from_directory(
    train_data_dir,
    target_size=(img_width, img_height),
    batch_size=batch_size,
    class_mode='binary')

validation_generator = test_datagen.flow_from_directory(
    validation_data_dir,
    target_size=(img_width, img_height),
    batch_size=batch_size,
    class_mode='binary')

I think you should do this way for training. 我认为您应该采用这种方式进行培训。 Then for test I think using train_datagen.standardize is true. 然后为了测试,我认为使用train_datagen.standardize是正确的。

I think it's the problem that you used cv2 to import your images, because when you use cv2.imread , the channels are not "r,g,b" but "b,g,r". 我认为这是您使用cv2导入图像的问题,因为使用cv2.imread ,通道不是“ r,g,b”而是“ b,g,r”。

for example, 例如,

import cv2
from tensorflow.keras.preprocessing import image

bgr = cv2.imread('r.jpg')
rgb = np.array(image.load_img('r.jpg'))
print(bgr[1,1,:],rgb[1,1,:])

result: 结果:

[ 83 113   0] [  0 114  83]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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