Как я могу получить вероятность / уверенность как вывод для CNN, использующего керас в python? - PullRequest
0 голосов
/ 04 февраля 2019

Итак, я новичок в области глубокого изучения, и я начал с набора данных о кошках и собаках для модели CNN с использованием Keras.

В моем коде я не могу получить вероятности в качестве выходных данных для обоихclassifier.predict или classifier.predict_proba.Я просто получаю вывод как [[0,1]] или [[1,0]].Я пробовал с несколькими изображениями.

Но я ищу что-то вроде [[0.4,0.6]], [[0.89,0.11]]

Я пытался изменить функцию потерь с binary_crossentropy на categorical_crossentropy.

Я попытался изменить функцию активации выходного слоя с sigmoid на softmax.

Я также попытался изменить class_mode в flow_from_directory с binary to categorical.

Я думаю, что я могу ошибаться с типом данных, так как тип массива вывода float32.Но даже если это ошибка, я не знаю, как ее изменить.

Я не могу найти, где я иду не так.Пожалуйста, уточните / помогите.Спасибо.

Зачем мне вероятности?

В моем другом проекте я буду разбивать изображение на n частей.Затем я использую классификатор по n штукам отдельно и найду одну фигуру с наибольшей вероятностью.Для этого я не буду использовать набор данных о кошках и собаках.Он предназначен для выбора бина, и этот набор данных также будет двоичным выводом как «ДА» или «НЕТ».Любые предложения по этому вопросу также приветствуются.Спасибо.

Ссылка за код в 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 голосов
/ 05 февраля 2019

Сработает и Предикат (), или Предикат_генератор ().

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' подмножествах изображения, как в вашем случае),Вы могли бы попробоватьести вgnast_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)

Используйте следующую команду для печати в процентах, округленных до 2 десятичных знаков:

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

Дайте мне знать, если это работает для вас!

0 голосов
/ 05 февраля 2019

Я думаю, что нашел ошибку.Вы пересчитываете поезд и проверяете данные с помощью 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.

0 голосов
/ 04 февраля 2019

Я ищу что-то вроде, [[0.4,0.6]], [[0.89,0.11]]

classifier.predict - метод, который вы должны использовать, чтобы получить вероятности,Не могли бы вы проверить еще раз, учитывая следующие советы?

Существует два способа построения двоичного классификатора:

  1. NN с один выходной нейрон с сигмовидная активация .Выход a интерпретируется как вероятность для класса 1, поэтому вероятность для класса 2 равна 1-a.
  2. NN с двумя выходными нейронами с использованием активации софтмакс .Каждый нейрон затем интерпретируется как вероятность одного класса.

Оба являются допустимыми параметрами, но, поскольку вы делаете 2., вы должны использовать Softmax Activation.

I 'мы пытались изменить функцию потерь с двоичного_кросцентропа на категориальный_кросентропию.

Это не должно иметь значения, это в основном та же формула.

Я думаю, что я могу ошибаться стип данных, как тип массива вывода float32.Но даже если это ошибка, я не знаю, как ее изменить.

Это также не причина ошибки, так как тип float32 подходит для вероятностных выходов.

...