【问题标题】:keras - get probability per each classkeras - 获得每个班级的概率
【发布时间】:2018-06-21 09:01:55
【问题描述】:

我正在尝试从 keras 模型中获取每个类别的概率。请在下面找到示例 keras 模型:

width = 80
height = 80
model = Sequential()
model.add(Conv2D(32, (3, 3), input_shape=( width, height, 3)))
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())  # this converts our 3D feature maps to 1D feature vectors
model.add(Dense(64))
model.add(Activation('relu'))
#model.add(Dropout(0.5))
model.add(Dense(2))
model.add(Activation('softmax'))

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

但是,在训练模型之后,我加载了要预测的图像:

img = image.load_img('Test2.jpg', target_size=(80, 80))
x = image.img_to_array(img)
x = np.expand_dims(x, axis=0)
images = np.vstack([x])
classes = model.predict_proba(images, batch_size=1)
print(classes)

[[ 0.  1.]]

我仍然得到类标签,而不是概率。任何提示我做错了什么?

编辑 这就是模型的训练方式:

train_datagen = ImageDataGenerator(
        rotation_range=40,
        width_shift_range=0.2,
        height_shift_range=0.2,
        shear_range=0.2,
        zoom_range=0.2,
        horizontal_flip=True,
        fill_mode='nearest')

# this is the augmentation configuration we will use for testing:
# only rescaling
test_datagen = ImageDataGenerator(
        rotation_range=40,
        width_shift_range=0.2,
        height_shift_range=0.2,
        shear_range=0.2,
        zoom_range=0.2,
        horizontal_flip=True,
        fill_mode='nearest')


train_generator = train_datagen.flow_from_directory(
        '.\\train',  # this is the target directory
        target_size=(width, height),  # all images will be resized to 150x150
        batch_size=batch_size,
        class_mode='binary',
        shuffle=True)  # since we use binary_crossentropy loss, we need binary labels

# this is a similar generator, for validation data
validation_generator = test_datagen.flow_from_directory(
        '.\\validate',
        target_size=(width, height),
        batch_size=batch_size,
        class_mode='binary',
        shuffle=True)

model.fit_generator(
        train_generator,
        steps_per_epoch=4000,
        epochs=2,
        validation_data=validation_generator,
        validation_steps=1600)

【问题讨论】:

  • 您是否标准化了您的训练数据?您是否相应地对输入图像进行了标准化?
  • 0 和 1 也是有效概率。
  • 大家好,感谢您的及时反应。我用训练模型/加载样本的代码更新了问题。我认为我没有在任何地方进行标准化,还是我错了? (keras新手)。在我看来,任何一个课程的概率都那么高,对吗?但是会尝试不同的样本并让您知道。

标签: python deep-learning keras


【解决方案1】:

问题是您在ImageDataGenerator 中使用'sparse_categorical_crossentropy' 损失和class_mode='binary'

你有两种可能:

  1. 将损失更改为'categorical_crossentropy'并设置class_mode='categorical'
  2. 保持损失不变,但设置class_mode='sparse'

两者都可以。

请参阅this answer 了解两种损失之间的差异(在 Tensorflow 中,但也适用于 Keras)。简短的版本是稀疏损失期望标签是整数类(例如 1、2、3...),而普通损失需要 one-hot 编码向量(例如[0, 1, 0, 0])。

干杯

编辑:正如@Simeon Kredatus 指出的,这是一个标准化问题。 这可以通过在训练集和测试集的ImageDataGenerator 构造函数中设置适当的标志来轻松解决,即samplewise_center=Truesamplewise_std_normalization=True
更新答案,以便人们可以看到解决方案。一般来说,请记住垃圾进垃圾出原则。

【讨论】:

  • 您好,谢谢您的回复。现在我收到以下错误:检查目标时出错:预期 activation_5 的形状为 (None, 2) 但数组的形状为 (8, 1)。这可能与训练/验证生成器的 class_mode 有关吗?
  • 是的,很抱歉,我没有检查 ImageDataGenerator 的工作原理。您可以使用 'categorical_crossentropy' 和 class_mode='categorical' 或 'sparse_categorical_crossentropy' 和 class_mode='sparse'。我将编辑答案以匹配此新信息:)
  • 上述解决方案中的任何一个仍然给我这样的数组:[[1. 0.]] -> 是否真的有可能各个类的概率为 1 或 0?
  • 这是可能的,当然,除非你有完美的数据集,否则真的很奇怪。您可以尝试在训练之前运行相同的预测并发布模型的输出吗?另外数据集是如何构建的?
  • 嘿,总结一下 - 在每个 ImageDataGenerator 实例中,我必须包含规范化 - “samplewise_center=True, samplewise_std_normalization=True” - 我必须将它包含在每个 ImageDataGenerator 实例的构造函数中ImageDataGenerator 对象。事情是没有对数据进行标准化,它往往会误认为学习过程(是的,现在很明显:))。所以正确的答案是两个折叠:你回答了第一部分,@Marcin Mozejko 也有一点:)。如果您愿意,可以更新您的答案,将其视为正确答案。
猜你喜欢
  • 2018-10-08
  • 1970-01-01
  • 2019-10-25
  • 2019-11-10
  • 1970-01-01
  • 2020-03-05
  • 2023-04-10
  • 2018-04-12
  • 1970-01-01
相关资源
最近更新 更多