CNN 低准确率猫狗数据集

Posted

技术标签:

【中文标题】CNN 低准确率猫狗数据集【英文标题】:CNN low accuracy cats vs dogs dataset 【发布时间】:2020-05-07 13:41:39 【问题描述】:

我有一个火车文件夹,其中包含猫文件夹(里面有 5000 张照片)和狗文件夹(里面有 4000 张照片)。另外,我有一个测试文件夹,其中包含猫文件夹(2500 张图片)和狗文件夹(2000 张图片)。我已经编写了以下代码来应用 CNN 图像分类

代码:

from keras.models import Sequential
from keras.layers import Conv2D,Activation,MaxPooling2D,Dense,Flatten,Dropout
import numpy as np
from keras.preprocessing.image import ImageDataGenerator
from IPython.display import display
import matplotlib.pyplot as plt
from PIL import Image
from sklearn.metrics import classification_report, confusion_matrix
classifier = Sequential()
classifier.add(Conv2D(32,(3,3),input_shape=(64,64,3)))
classifier.add(Activation('relu'))
classifier.add(MaxPooling2D(pool_size =(2,2)))
classifier.add(Conv2D(32,(3,3)))
classifier.add(Activation('relu'))
classifier.add(MaxPooling2D(pool_size =(2,2)))
classifier.add(Conv2D(64,(3,3)))
classifier.add(Activation('relu'))
classifier.add(MaxPooling2D(pool_size =(2,2)))
classifier.add(Flatten())
classifier.add(Dense(64))
classifier.add(Activation('relu'))
classifier.add(Dropout(0.5))
classifier.add(Dense(1))
classifier.add(Activation('sigmoid'))
classifier.summary()
classifier.compile(optimizer ='rmsprop',
                   loss ='binary_crossentropy',
                   metrics =['accuracy'])
train_datagen = ImageDataGenerator(rescale =1./255,
                                   shear_range =0.2,
                                   zoom_range = 0.2,
                                   horizontal_flip =True)
test_datagen = ImageDataGenerator(rescale = 1./255)

batchsize=500
training_set = train_datagen.flow_from_directory('/home/osboxes/Downloads/dogs-vs-cats/train/',
                                                target_size=(64,64),
                                                batch_size= batchsize,
                                                class_mode='binary')

test_set = test_datagen.flow_from_directory('/home/osboxes/Downloads/dogs-vs-cats/test/',
                                           target_size = (64,64),
                                           batch_size = batchsize,
                       shuffle=False,
                                           class_mode ='binary')
history=classifier.fit_generator(training_set,
                        steps_per_epoch =9000/batchsize,
                        epochs = 3,
                        validation_data =test_set,
                        validation_steps = 4500/batchsize)

Y_pred = classifier.predict_generator(test_set, 4500 / batchsize)
y_pred = np.argmax(Y_pred, axis=1)
print('Confusion Matrix')
print(confusion_matrix(test_set.classes, y_pred))
print('Classification Report')
target_names = ['cats', 'dogs']
print(classification_report(test_set.classes, y_pred, target_names=target_names))
print(history.history.keys())
# summarize history for accuracy
plt.plot(history.history['accuracy'])
plt.plot(history.history['val_accuracy'])
plt.title('model accuracy')
plt.ylabel('accuracy')
plt.xlabel('epoch')
plt.legend(['train', 'test'], loc='upper left')
plt.show()
# summarize history for loss
plt.plot(history.history['loss'])
plt.plot(history.history['val_loss'])
plt.title('model loss')
plt.ylabel('loss')
plt.xlabel('epoch')
plt.legend(['train', 'test'], loc='upper left')
plt.show()

得到的混淆矩阵是:

混淆矩阵

[[2500 0]

[2000 0]]

我的问题是:

1- 为什么所有的狗实例都被归类为猫

2-猫和狗训练文件夹之间的样本数可以不同吗?还是测试文件夹?或者它们必须完全相同?

3- 如果我需要添加例如马图片,如何添加多类分类器?

【问题讨论】:

为什么只训练模型三个 epoch? 仅用于速度目的。我要买 20 个或更多吗? 是的,您没有正确训练模型(3 个 epoch 是不够的),这就是模型产生错误预测的原因。 我尝试了 50 个 epoch,得到了相同的混淆矩阵结果 损失是否跨时期减少?此外,批量大小为 500 有点疯狂,尝试 64 或 128 之类的。 【参考方案1】:

1- 因为你输入了classifier.add(Dense(1)),这意味着你只有一个类。既然你有两个,你必须把classifier.add(Dense(2))和你的损失改成loss ='categorical_crossentropy'

2-是的,每个班级的图像数量之间有一点差异是可以的(但应该不会有太大差异)

3- 按我说的改变损失并输入classifier.add(Dense(3))

最好使用 Adam 优化器,并在每个 Activation() 函数之前使用 BatchNormalization()

【讨论】:

不,如果你使用二元交叉熵损失,一个具有 sigmoid 激活的单元可以用于二元分类。 @MatiasValdenegro 你说得对,我以前听说过,但从未尝试过。在 2 类分类中使用二进制有什么好处? 对于有两个类的分类,推荐使用dense = 1的二元分类。作为优化器 Adam 很好。【参考方案2】:
    你必须为test_datagen.flow_from_directory函数设置shuffle=False,否则,它会打乱你的测试数据集和混淆矩阵破坏。你成功了,好的。

    y_pred = np.argmax(Y_pred, axis=1) 替换为y_pred = (y_pred > 0.5).astype(int)

    #y_pred = np.argmax(y_pred, axis=1)  # for 'categorical' class_mode
    y_pred = (y_pred > 0.5).astype(int)  # for 'binary' class_mode
    

【讨论】:

以上是关于CNN 低准确率猫狗数据集的主要内容,如果未能解决你的问题,请参考以下文章

CNN基础二:使用预训练网络提取图像特征

决策树如果数据集不够多,会导致分类准确率低吗

python,tensorflow,CNN实现mnist数据集的训练与验证正确率

验证准确率提高,但验证损失也在增加

利用CNN进行图像分类的流程(猫狗大战为例)

CNN分类中验证损失减少,验证准确率下降