为什么对于没有定义类别的图像,预测概率如此之高?

时间:2019-04-20 19:14:34

标签: python tensorflow machine-learning keras conv-neural-network

我在这里呆了太久了。我正在尝试创建一个可以检测图像中数字的CNN。为此,我开始使用 The Street View House Numbers (SVHN) Dataset。该数据集带有缩放为32x32位数的预处理图像.10个类别对应10个数字。

我训练了网络,它给出了不错的测试精度,接近0.93。还要根据一组32x32位数的测试集来计算测试准确性。

这一切都很好。但是问题是预测概率总是一个。这是该类之一的输出的样子:

 array([[0.0000000e+00, 0.0000000e+00, 0.0000000e+00, 0.0000000e+00,
        1.0000000e+00, 8.5623318e-24, 0.0000000e+00, 0.0000000e+00,
        0.0000000e+00, 2.4716297e-28]], dtype=float32)

从该示例之一的输出可以看出,该类别之一的类别概率为1。这对于包含所需类别图像的图像很好,但是即使图像中没有数字标记,也可能发生概率为1。例如,以下图像以4的概率预测类1。实际上,以上分布适用于以下图像。

图片:

enter image description here

我无法确定原因。我正在共享创建CNN的代码。

val_split_length = 10623
num_train_samples = 73257
num_test_samples = 26032
total_classes = 10
model_prefix = "10c"

model = keras.Sequential()
# First Conv. Layer
model.add(keras.layers.Conv2D(filters = 96, kernel_size = (11,11), strides = (4,4), padding = "same", input_shape=(227,227,3)))
model.add(keras.layers.Activation("relu"))
model.add(keras.layers.BatchNormalization())
model.add(keras.layers.MaxPooling2D(pool_size = (3,3), strides = (2,2), padding="same"))

# ##More Conv. Layers ###

# First Fully Connected Layer
model.add(keras.layers.Flatten())
model.add(keras.layers.Dense(4096))
model.add(keras.layers.Activation("relu"))
model.add(keras.layers.Dropout(0.5))

## More Fully Connected Layers ###

# Third Fully Connected Layer
model.add(keras.layers.Dense(total_classes))
model.add(keras.layers.Activation("softmax"))



train_optimizer_adam = tf.train.AdamOptimizer(learning_rate=1e-3)
train_optimizer_rmsProp = keras.optimizers.RMSprop(lr=0.0001)

#https://keras.io/optimizers/
model.compile(loss="categorical_crossentropy", optimizer=train_optimizer_rmsProp, metrics=['accuracy'])

batch_size = 128 * 3

data_generator = keras.preprocessing.image.ImageDataGenerator(rescale = 1./255)

# https://keras.io/preprocessing/image/#flow_from_directory
train_generator = data_generator.flow_from_directory(
        'train',
        target_size=(227, 227),
        batch_size=batch_size,
        color_mode='rgb',
        class_mode='categorical',
        #save_to_dir="logs"
)

validation_generator = data_generator.flow_from_directory(
        'validation',
        target_size=(227, 227),
        batch_size=batch_size,
        color_mode='rgb',
        class_mode='categorical')


# https://keras.io/models/model/#fit_generator
history = model.fit_generator(
    train_generator, 
    validation_data = validation_generator, 
    validation_steps = math.ceil(val_split_length / batch_size),
    epochs = 5, 
    steps_per_epoch = math.ceil(num_train_samples / batch_size), 
    use_multiprocessing = True, 
    workers = 8, 
    callbacks = model_callbacks, 
    verbose = 2
)

要从以上模型进行预测,请执行以下操作:

img = cv2.imread("image.png")
img = cv2.resize(img, (227,227))
loaded_model = keras.models.load_model("saved-model-12-0.96.hdf5")
prob = loaded_model.predict_proba(np.expand_dims(img, axis = 0))
print(prob)

为什么我获得图像中任何地方都不存在的类的可能性很高的原因是什么?我知道该模型会预测一些东西,但是为什么概率如此之高?

1 个答案:

答案 0 :(得分:3)

问题是您没有应用模型训练期间使用的预处理管道。具体来说,您必须按1/255.缩放图像像素的值:

img = img.astype('float32') / 255.

在测试阶段遵循与培训阶段相同的预处理流程是非常重要的;否则您的模型可能会感到困惑,并输出错误的预测。