CNN使用predict_classes提供不正确的预测

时间:2018-02-20 05:02:57

标签: keras

我仍然处于keras和CNN的学习模式。我觉得我理解基本点,但我的执行很困难。我创建了一个用于狗/猫图像数据集的Sequential分类器。我使用fit_generator来获取以下内容(此代码):

Epoch 1/5
8000/8000 [==============================] - 1942s 243ms/step - loss: 0.3658 - acc: 0.8299 - val_loss: 0.6998 - val_acc: 0.7785] - ETA: 24:40 - loss: 0.6010 - acc: 0.6705
Epoch 2/5
8000/8000 [==============================] - 1829s 229ms/step - loss: 0.1266 - acc: 0.9522 - val_loss: 0.9218 - val_acc: 0.7731
Epoch 3/5
8000/8000 [==============================] - 1806s 226ms/step - loss: 0.0689 - acc: 0.9759 - val_loss: 1.2006 - val_acc: 0.7813
Epoch 4/5
8000/8000 [==============================] - 1936s 242ms/step - loss: 0.0504 - acc: 0.9830 - val_loss: 1.2396 - val_acc: 0.7748- ETA: 18:07 - loss: 0.0548 - acc: 0.9817
Epoch 5/5
8000/8000 [==============================] - 2259s 282ms/step - loss: 0.0393 - acc: 0.9870 - val_loss: 1.3916 - val_acc: 0.7818

用于产生上述结果的代码:

# Importing the Keras libraries and packages
import os
from keras.models import Sequential, load_model
from keras.layers import Conv2D
from keras.layers import MaxPooling2D
from keras.layers import Flatten
from keras.layers import Dense

from keras.preprocessing import image
from keras.preprocessing.image import ImageDataGenerator

#create classifying sequential neural network
classifier = Sequential()

classifier.add(Conv2D(32, (3, 3), input_shape = (64, 64, 3), activation = 'relu'))
classifier.add(MaxPooling2D(pool_size = (2, 2)))
classifier.add(Flatten())
classifier.add(Dense(units = 128, activation = 'relu')) #ReLU stands for Rectified Linear Unit. It takes a real-valued input and thresholds it at zero (replaces negative values with zero)

#initialise our output layer, which should contain only one node, as it is 
#binary classification. Single node gives us a binary output of either a Cat or Dog.
classifier.add(Dense(units = 1, activation = 'sigmoid')) 

#compile CNN model
classifier.compile(optimizer = 'adam', loss = 'binary_crossentropy', metrics = ['accuracy'])

#CREATE IMAGE DATA GENERATORS---
#perform image augmentations, essentially synthesising training data 
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('training_set', 
                                                 target_size = (64, 64), 
                                                 batch_size = 32, 
                                                 class_mode = 'binary')

#create test set for training, by feeding generated data from images using the test directory
test_set = test_datagen.flow_from_directory('test_set', 
                                            target_size = (64, 64), 
                                            batch_size = 32, 
                                            class_mode = 'binary')


#fit the training set to model        
classifier.fit_generator(training_set, 
                         steps_per_epoch = 8000, 
                         epochs = 5, 
                         validation_data = test_set, 
                         validation_steps = 2000)

#save the model for further use
classifier.save('classifier_v1.h5')

从这里开始,我使用load_model函数来回忆我的分类器并试图预测5张图片的测试集上是狗还是猫。分类器只有1,不管我做什么。

from keras.models import load_model
from keras.preprocessing import image
import numpy as np

classifier = load_model('classifier_v1.h5')
data_path = r'C:\Users\aneja\Documents\Python Scripts\CNN\Cats-Dogs\test_2'
image_list = [x for x in os.listdir(data_path) if '.jpg' in x]

#loop to test through test images
for jpeg in image_list:
    #load a test image
    img = image.load_img(os.path.join(data_path, jpeg), target_size=(64,64))

    #process image to extract numpy arrays
    y = image.img_to_array(img)
    x = np.expand_dims(y, axis=0)

    #predict!   1 = dog   0 = cat
    images = np.vstack([x])
    classes = classifier.predict_classes(images, batch_size=10)
    if classes[0][0]==1:
        print('The {} file is predicted to be a dog'.format(jpeg))
    elif classes[0][0]==0:
        print('The {} file is prediected to be a cat'.format(jpeg))
    else:
        print('Yea, I did something wrong')

当使用predict代替predict_classes时,我也会得到相同的结果。我希望我离解决方案不太远,但我担心我从根本上误解了概念。任何人都可以提供任何帮助,为什么我的分类器似乎总是将该类归类为1?

1 个答案:

答案 0 :(得分:1)

以下是一些建议:

首先,请检查以确保“ steps_per_epoch = 8000”和“ validation_steps = 2000”实际上是正确的值。根据我的经验,错误的数字会严重损害模型的性能。大多数人通过执行以下操作来确保这些值是正确的: generator_train.samples / generator_train.batch_size

第二,增加Conv2D层的数量。通常,对于一个强模型,一层是不够的。如果您发现计算机无法快速训练模型,请使用Google Colaboratory,这是一个免费的基于GPU和云的网站,您可以执行此操作。

第三,增加测试大小。 5张图像不足以让您自信地评估模型的性能。

第四,按照S.Mohsen的说法,如果您发现“预测”给出的结果只是返回“ 1s”,则表明您的模型尚未得到适当的训练,因此请尝试我的前两个建议。

希望这对您有所帮助!