Keras CNN + Google Colab всегда предсказывает класс 1 (высокая тренировка + точность проверки) - PullRequest
0 голосов
/ 28 февраля 2019

Привет! Я использую приведенный ниже код для обучения классификатора в Керасе, но при тестировании новых изображений я всегда получаю прогнозируемый класс как 1, хотя мой проверочный тест показывает точность выше 80%.Пожалуйста, предложите, что я делаю не так.

Код:

classifier=Sequential()

#--------------- 2. Convolution --------------------------
classifier.add(Conv2D(input_shape=(64,64,3),filters=32,kernel_size=(3,3),strides=(1,1),activation='relu'))
#--------------- 3. Max Pooling --------------------------
classifier.add(MaxPool2D(pool_size=(2,2)))
classifier.add(BatchNormalization())
#--------------- 4. Convolution --------------------------
classifier.add(Conv2D(filters=64,kernel_size=(3,3),strides=(1,1),activation='relu'))
#--------------- 5. Max Pooling --------------------------
classifier.add(MaxPool2D(pool_size=(2,2)))
classifier.add(BatchNormalization())
#--------------- 4. Convolution --------------------------
classifier.add(Conv2D(filters=128,kernel_size=(3,3),strides=(1,1),activation='relu'))
#--------------- 5. Max Pooling --------------------------
classifier.add(MaxPool2D(pool_size=(2,2)))
classifier.add(BatchNormalization())
#--------------- 4. Convolution --------------------------
classifier.add(Conv2D(filters=256,kernel_size=(3,3),strides=(1,1),activation='relu'))
#--------------- 5. Max Pooling --------------------------
classifier.add(MaxPool2D(pool_size=(2,2)))
classifier.add(BatchNormalization())
#--------------- 6. Flattening ---------------------------
classifier.add(Flatten())

#--------------- 7. Full Connection ----------------------
classifier.add(Dense(units=128,activation='relu',kernel_initializer='uniform'))
classifier.add(Dropout(0.6))
classifier.add(Dense(units=96,activation='relu',kernel_initializer='uniform'))
classifier.add(Dropout(0.4))
classifier.add(Dense(units=64,activation='relu',kernel_initializer='uniform'))
classifier.add(Dropout(0.2))
classifier.add(Dense(units=1,activation='sigmoid',kernel_initializer='uniform'))

#--------8. Deal with the weights and Loss function --------
classifier.compile(optimizer='adam',loss='binary_crossentropy', metrics=['accuracy'])

#-------- 9. Fitting CNN with 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=128,
        class_mode='binary')

test_set = test_datagen.flow_from_directory(
        'dataset/test_set',
        target_size=(64,64),
        batch_size=128,
        class_mode='binary',
        shuffle=False)
filepath="bestcatvsdogmodel.h5"
save_best_model=ModelCheckpoint(filepath, monitor='val_acc', verbose=1, save_best_only=True, mode='max')
ReduceLR=ReduceLROnPlateau(monitor='val_acc', factor=0.6, patience=5, verbose=2,cooldown=1, min_delta=0.0020, min_lr=0.)
classifier.fit_generator(
        training_set,
        steps_per_epoch=7928/128,
        epochs=10,
        validation_data=test_set,
        validation_steps=2000/128,
        callbacks=[ReduceLR,save_best_model])
import numpy as np
from skimage.io import imread
from skimage.transform import resize
class_labels={v:k for k,v in training_set.class_indices.items()}
img_d=imread('dog.jpg')
img_c=imread('cat.jpg')
img_d=resize(img_d,(64,64))
img_c=resize(img_c,(64,64))
img_dog=np.expand_dims(img_d,axis=0)
img_cat=np.expand_dims(img_c,axis=0)
if(np.max(img_dog)>1):
    img_dog=img_dog/255.0
if(np.max(img_cat)>1):
    img_cat=img_cat/255.0
prediction_cat = classifier.predict_classes(img_cat)
print("Cat Prediction: "+str(prediction_cat))
prediction_dog = classifier.predict_classes(img_dog)
print("Dog Prediction: "+str(prediction_dog))

Результаты:

enter image description here

Пожалуйста, сообщите, если вы видите какую-либо ошибку вкод

1 Ответ

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

Вы делаете

prediction_cat = classifier.predict_classes(img_cat)
print("Cat Prediction: "+str(prediction_cat))
prediction_dog = classifier.predict_classes(img_dog)
print("Dog Prediction: "+str(prediction_dog))

В вашей модели я вижу, что последний слой имеет 1 узел, активированный с помощью sigmoid.Такая модель при прогнозировании вызова дает выходную вероятность в диапазоне от 0 до 1.

Вы вызываете predict_classes для модели.То, что он в основном делает, это что-то вроде np.argmax(model.predict(test)).Таким образом, в вашем случае, поскольку модель дает только вектор 1D, выходной сигнал всегда будет 1.

Чтобы ваша модель получала выходной сигнал правильно, вы должны использовать model.predict(), как показано ниже.

prediction_cat = classifier.predict(img_cat)
print("Cat Prediction: "+str(prediction_cat))
prediction_dog = classifier.predict(img_dog)
print("Dog Prediction: "+str(prediction_dog))

Затем вы получите что-то вроде этого

Cat Prediction: 0.05
Dog Prediction: 0.98

. Вы можете использовать порог, чтобы отобразить прогнозируемые вероятности для меток классов.Обычно используемым порогом является 0.5, но рекомендуется выбирать пороговое значение на основе f1-score.Поскольку ваш набор данных сбалансирован, вам не нужно беспокоиться об этом.Вы можете сделать прогноз и отобразить метку класса, как показано ниже.Предполагая, что вы закодировали cat как 0 и dog как 1

# suppose test contains image to predict
threshold = 0.5
pred = model.predict(test)
if pred > threshold:
    print('Dog')
else:
    print('Cat')
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...