首页 > 解决方案 > 模型在训练和验证中获得 97% 的准确率,但在使用自定义预测时会出错

问题描述

我使用 CNN 模型来训练图像分类,它在测试和验证中获得了很高的准确率(98% 和 97%),但是当使用我的图像进行预测时总是出错,这是我的代码:

BATCH_SIZE = 30
IMG_HEIGHT = 256
IMG_WIDTH = 256
STEPS_PER_EPOCH = np.ceil(image_count/BATCH_SIZE)

train_data_gen = image_generator.flow_from_directory(directory=str(data_dir),
                                                     batch_size=BATCH_SIZE,
                                                     shuffle=True,
                                                     target_size=(IMG_HEIGHT, IMG_WIDTH),
                                                     classes = list(CLASS_NAMES))

这是为数据集和数据论证做准备:

imgDataGen=ImageDataGenerator(
    validation_split=0.2,
    rescale=1/255,
    horizontal_flip=True,
    zoom_range=0.3,
    rotation_range=15.,
    width_shift_range=0.1,
    height_shift_range=0.1,
)

准备数据:

train_dataset = imgDataGen.flow_from_directory(
    directory=str(data_dir),
    target_size = (IMG_HEIGHT, IMG_WIDTH), 
    classes = list(CLASS_NAMES),
    batch_size = BATCH_SIZE,
    subset = 'training'
)

val_dataset = imgDataGen.flow_from_directory(
    directory=str(data_dir),
    target_size = (IMG_HEIGHT, IMG_WIDTH), 
    classes = list(CLASS_NAMES),
    batch_size =BATCH_SIZE,
    subset = 'validation'
)

该模型

model = Sequential()
model.add(Conv2D(32, (3, 3), activation='relu', kernel_initializer='he_uniform', padding='same', input_shape=(256, 256, 3)))
model.add(MaxPooling2D((2, 2)))
model.add(Conv2D(64, (3, 3), activation='relu', kernel_initializer='he_uniform', padding='same'))
model.add(MaxPooling2D((2, 2)))
model.add(Conv2D(128, (3, 3), activation='relu', kernel_initializer='he_uniform', padding='same'))
model.add(MaxPooling2D((2, 2)))
model.add(Flatten())
model.add(Dense(128, activation='relu', kernel_initializer='he_uniform'))
model.add(Dense(6, activation='sigmoid'))

遵守:

model.compile(loss='binary_crossentropy',
              optimizer=keras.optimizers.SGD(learning_rate=0.001,momentum=0.9),
              metrics=['acc'])

火车

history = model.fit_generator(
    train_dataset, 
    validation_data = val_dataset,
    workers=10,
    epochs=20,
)

它在测试中获得了 98% 的准确率,在验证中获得了 97%的准确率

但是当我尝试使用我的代码进行预测时

def prepare(filepath):
    IMG_SIZE=256
    img_array=cv2.imread(filepath)
    new_array= cv2.resize(img_array,(IMG_SIZE,IMG_SIZE))
    return new_array.reshape(1,IMG_SIZE,IMG_SIZE,3)
model=tf.keras.models.load_model('trained-model.h5',compile=False)

#np.set_printoptions(formatter={'float_kind':'{:f}'.format})
predict=model.predict([prepare('cat.jpg')])
pred_name = CATEGORIES[np.argmax(predict)]
print(pred_name)

它出错了,猫图像它适用于狗,狗适用于猫,但有时它会正确,只是我认为 98% 比这更准确,如果我尝试 5 个猫的图像,它会失败 3 或 4 个图像

所以是因为数据集还是因为代码?请帮忙,谢谢

标签: pythontensorflowkeras

解决方案


所以在你的第二个代码块中你有这个:

rescale=1/255

这是为了将您的图像标准化为范围 [0;1]。因此,每个图像在通过网络之前都会重新缩放(/标准化)。但是在你没有添加规范化的图像上测试它的 las 代码块中。尝试将其添加到您的“准备”功能中:

def prepare(filepath):
    IMG_SIZE = 256
    img_array = cv2.imread(filepath)

    # add this:
    img_array = image_array / 255

    new_array = cv2.resize(img_array,(IMG_SIZE,IMG_SIZE))
    return new_array.reshape(1,IMG_SIZE,IMG_SIZE,3)

推荐阅读