如何在python中使用keras获取CNN的概率/置信度输出?

时间:2019-02-04 10:00:31

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

因此,我是深度学习的新手,我从使用Keras的CNN模型的猫和狗数据集开始。

在我的代码中,我无法获得classifier.predictclassifier.predict_proba的概率作为输出。我只是得到输出为[[0,1]][[1,0]]。我已经尝试了几种图像。

但是我正在寻找[[0.4,0.6]][[0.89,0.11]]

之类的东西

我尝试将损失函数从binary_crossentropy更改为categorical_crossentropy

我尝试将输出层的激活功能从sigmoid更改为softmax

我还尝试将class_mode中的flow_from_directorybinary更改为categorical

我认为数据类型可能会出错,因为输出数组的类型是float32。但是即使那是错误,我也不知道如何更改。

我找不到我要去哪里。请澄清/帮助。谢谢。

  

为什么我需要概率?

     

在另一个项目中,我将图像分割为n个较小的部分。然后,我将在“ n”个零件上分别使用分类器,并找到概率最大的零件。为此,我不会使用猫和狗的数据集。这是用于bin-picking,该数据集也将是二进制输出,即“ YES”或“ NO”。也欢迎对此提出任何建议。谢谢。

Link(用于Github中的代码)。

    #Building the CNN

    from keras.models import Sequential
    from keras.layers import Convolution2D
    from keras.layers import MaxPooling2D
    from keras.layers import Flatten
    from keras.layers import Dense

    #Initialising the CNN

    classifier = Sequential()

    #Step 1 - Convolution
    classifier.add(Convolution2D(filters=32,kernel_size=[3,3],input_shape=(64,64,3),activation='relu'))

    #Step 2 - Pooling
    classifier.add(MaxPooling2D(pool_size=(2,2),strides=2))

    #Adding another Convolutional Layer for better accuracy
    #classifier.add(Convolution2D(filters=32,kernel_size=[3,3],activation='relu'))
    #classifier.add(MaxPooling2D(pool_size=(2,2),strides=2))

    #Step 3 - Flattening
    classifier.add(Flatten()) 

    #Step 4 - Fully Connected Layers
    classifier.add(Dense(units= 64, activation='relu'))
    classifier.add(Dense(units= 2, activation='softmax'))


    #Compiling the CNN
    classifier.compile(optimizer='adam',loss = 'categorical_crossentropy', metrics=['accuracy'])

    #Part 2 - Fitting the CNN to the images
    from keras.preprocessing.image import ImageDataGenerator

    train_datagen=ImageDataGenerator(
            rescale=1./255,
            shear_range=0.2,
            zoom_range=0.2,
            horizontal_flip=True)

    test_datagen=ImageDataGenerator(rescale=1./255)

    training_set = train_datagen.flow_from_directory('dataset/training_set',
                                                     target_size=(64,64),
                                                     batch_size=32,
                                                     class_mode='categorical')

    test_set = test_datagen.flow_from_directory('dataset/test_set',
                                                target_size=(64,64),
                                                batch_size=32,
                                                class_mode='categorical')

    classifier.fit_generator(training_set,
                        steps_per_epoch=250,
                        epochs=3,                       #Just for time being I've kept very few epochs.
                        validation_data=test_set,
                        validation_steps=62)


    #Making new Predictions
    import numpy as np
    from keras.preprocessing import image

    test_image_luna=image.load_img('dataset/single/SkilletLuna.JPG',target_size=(64,64))
    test_image2=image.img_to_array(test_image_luna)
    test_image2=np.expand_dims(test_image2,axis=0)
    luna=classifier.predict_proba(test_image2)

In [11]: luna
    ...: 
Out[11]: array([[0., 1.]], dtype=float32)

3 个答案:

答案 0 :(得分:0)

  

我正在寻找类似[[0.4,0.6]],[[0.89,0.11]]

classifier.predict是您用来获取概率的方法。您可以考虑以下提示再次检查吗?

有两种构建二进制分类器的方法:

  1. 具有一个输出神经元的神经元,具有乙状结肠激活。输出a被解释为1类的概率,因此2类的概率为1-a
  2. 使用 softmax激活
  3. 具有两个输出神经元的NN。然后,将每个神经元解释为一类的概率。

这都是有效的选项,但是由于您正在执行2.您应该使用softmax激活。

  

我尝试将损失函数从binary_crossentropy更改为   categorical_crossentropy。

这应该没有什么区别,基本上是相同的公式。

  

我认为数据类型可能会出错,因为   输出数组是float32。但是即使那是错误,我也不会   知道如何更改它。

这也不是导致错误的原因,因为类型float32适用于概率输出。

答案 1 :(得分:0)

predict()或predict_generator()均可。

import numpy as np
from keras.preprocessing import image

test_image_luna=image.load_img('dataset/single/SkilletLuna.JPG',target_size=(64,64))
test_image2=image.img_to_array(test_image_luna)
test_image2=np.expand_dims(test_image2,axis=0)
luna=classifier.predict(test_image2)

print(luna)

如果您想要“ n”幅图像(或您所需要的图像的“ n”个子集)的预测概率,则可以尝试预测_generator():

from keras.preprocessing.image import ImageDataGenerator

test_datagen=ImageDataGenerator(rescale=1./255)
test_set = test_datagen.flow_from_directory('dataset/test_set',
                                             target_size=(64,64),
                                             batch_size=32,
                                             class_mode='categorical')

predicted_probabilities = classifier.predict_generator(test_set)
print(predicted_probabilities)

使用以下内容以四舍五入到小数点后两位的百分比打印:

print(np.round(luna*100,2))
print(np.round(predicted_probabilities*100,2))

让我知道这是否适合您!

答案 2 :(得分:0)

我认为我发现了错误。您正在使用ImageDataGenerator重新调整训练和测试数据的比例。但是,当测试单个图像时,您没有这样做。 试试这个:

# Making new Predictions
import numpy as np
from keras.preprocessing import image

test_image_luna = image.load_img('D:\\NR\\data\\live2013\\caps.bmp', target_size=(64,64))
test_image2 = image.img_to_array(test_image_luna)/255.
test_image2 = np.expand_dims(test_image2, axis=0)
luna = classifier.predict_proba(test_image2)

高输入值导致非常高的输出值。由于您使用的是softmax激活,因此这些值会导致预测非常接近0和1。