【问题标题】:CNN giving incorrect predictions using predict_classesCNN 使用 predict_classes 给出不正确的预测
【发布时间】:2018-07-30 09:31:56
【问题描述】:

我仍处于 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?

【问题讨论】:

  • 您是否尝试在培训后致电predict? (跳过保存和加载)然后模型预测什么?
  • 这是一个很好的问题,简短的回答是否定的。我尝试的是运行fit_generator,然后在我的控制台中进行预测。以这种方式使用它,我确实相信有正确的分类,但我需要重试。总而言之,如果我可以将classifier 保存并加载到.h5 文件中,这是否重要?真正的困境是,合身需要几个小时才能完成,所以我无法轻易尝试。

标签: keras


【解决方案1】:

以下是一些建议:

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

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

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

第四,脱离 S.Mohsen sh 所说的,如果你发现“predict”给出的只是返回“1s”,那么这意味着你的模型没有经过适当的训练,所以试试我的前两个建议。

希望这有帮助!

【讨论】:

  • 非常感谢,德里克。我几乎放弃了这个冒险,但我会在接下来的几天里查看代码并采纳你的建议。我相信我还会有更多问题......
猜你喜欢
  • 2020-03-30
  • 2021-03-27
  • 2018-06-12
  • 2016-11-18
  • 2018-10-23
  • 2020-03-06
  • 2020-07-05
  • 2020-11-14
  • 1970-01-01
相关资源
最近更新 更多