Распознавание изображений Python Keras получить точные вероятности (не [[0.]] или [[1.]]) - PullRequest
0 голосов
/ 13 сентября 2018

Я учусь кодировать CNN с помощью keras.Учебник, которому я следую, основан на этом учебнике , и все работает довольно хорошо.

Но я немного поигрался с этим CNN, попытался оптимизировать его и попытаться найти его предел,Похоже, что когда я представляю фотографию чего-то, что не является кошкой или собакой, скажем, стулом, CNN все еще говорит мне, что картина - собака.

Поскольку модель обучена только на собаках иизображения кошек, это может только сказать мне, если изображение - собака или кошка.Таким образом, я решил использовать model.predict_proba, чтобы получить точную вероятность, поэтому я хотел, чтобы модель сказала мне, в случае изображения стула, «есть вероятность 7%, что это собака».Но модель дает мне [[0.]], другими словами, модель на 100% уверена, что стул - это собака.

Затем я начал модифицировать CNN и поместил 2 выходных нейрона в полностью связанные слои, для того, чтобы иметь вероятность того, что это кошка, и вероятность того, что это собака.Я использовал class_mode='categorical' вместо class_mode='binary' при подготовке данных, чтобы убедиться, что он работает с 2 выходными нейронами, и я не использовал softmax, чтобы убедиться, что у меня нет probaDog + probaCat = 1, потому чтоЕсли входные данные представляют собой изображение чего-то другого, кроме собаки или кошки, я не хочу получать ложные вероятности ... То, что я хотел видеть, когда я набрал model.predict_proba("iamge_path"), было что-то вроде [[0.213 0.639]].Затем я захотел определить некоторые условия и использовать их следующим образом:

if result[0][0] < 0.5 AND result[0][1] < 0.5:
    print("This is neither a dog nor a cat!")
elif result[0][0] > result[0][1] + 0.5:
    print("This is a dog!")
elif result[0][1] > result[0][0] + 0.5:
    print("This is a cat!")
else:
    print("This is neither a dog nor a cat!")

Но вместо этого я получаю каждый ответ [[0. 1.]] или [[1. 0.]].

.Тренировка моего CNN только на 1 эпоху.Я представил 13 снимков кота этой CNN, и он сказал мне 7 раз, что это были собаки.Но он был на 100% уверен, что это были собаки ...

Итак, как нам получить истинную вероятность?

Вот мой код CNN:

model = Sequential()

model.add(Convolution2D(filters=32, kernel_size=3, strides=1, input_shape=(128, 128, 3), activation = "relu"))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Convolution2D(filters=32, kernel_size=3, strides=1, activation = "relu"))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Convolution2D(filters=32, kernel_size=3, strides=1, activation = "relu"))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Convolution2D(filters=32, kernel_size=3, strides=1, activation = "relu"))
model.add(MaxPooling2D(pool_size=(2,2)))

model.add(Flatten())

model.add(Dense(units=128, activation="relu"))
model.add(Dropout(rate=0.2))
model.add(Dense(units=128, activation="relu"))
model.add(Dropout(rate=0.2))
model.add(Dense(units=128, activation="relu"))
model.add(Dropout(rate=0.2))
model.add(Dense(units=2, activation="sigmoid")) # 2 neurones de sorties

model.compile(optimizer = "adam", loss = "binary_crossentropy", metrics = ["accuracy"])

Вот мой код подготовки данных:

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

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

Код обучения:

model.fit_generator(
                        training_set,
                        steps_per_epoch=250, 
                        epochs=50,
                        validation_data=test_set,
                        validation_steps=63)

код для тестирования на одном изображении:

test_image = image.load_img(image_path, target_size=(128, 128)) 
test_image = image.img_to_array(test_image) 
test_image = np.expand_dims(test_image, axis = 0) 
result = model.predict(test_image)
print(model.predict_proba(test_image))
...