Я учусь кодировать 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))