【问题标题】:CNN Model can't predict images outside the dataset (FaceMask Detection)CNN 模型无法预测数据集外的图像(FaceMask Detection)
【发布时间】:2021-04-24 02:24:31
【问题描述】:

我想知道为什么我的 cnn 模型无法预测数据集之外的图像???

我的模型的 val_accuracy 为 98.6%val_loss 为 0.05

我使用数据集中的 827 个 test_images 测试了我的模型,其中 816 个是正确的。 但是当我对在数据集之外下载的图像进行测试时,我的模型无法正确预测。

这是我的 CNN 模型(带有 kaggle 笔记本的代码):

# import the necessary packages
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras.applications import MobileNetV2, EfficientNetB6
from tensorflow.keras.layers import AveragePooling2D
from tensorflow.keras.layers import Dropout
from tensorflow.keras.layers import Flatten
from tensorflow.keras.layers import Dense
from tensorflow.keras.layers import Input
from tensorflow.keras.models import Model
from tensorflow.keras.optimizers import Adam
from tensorflow.keras.applications.mobilenet_v2 import preprocess_input
from tensorflow.keras.preprocessing.image import img_to_array
from tensorflow.keras.preprocessing.image import load_img
from tensorflow.keras.utils import to_categorical
# from sklearn.preprocessing import LabelBinarizer
from sklearn.preprocessing import OneHotEncoder
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report
import matplotlib.pyplot as plt
import numpy as np
import os
import keras as k
from keras.optimizers import SGD, Adam, Adagrad, RMSprop
from keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras import datasets, layers, models
from keras.models import load_model, Model
from keras.regularizers import L2, L1, L1L2
import pickle
from IPython.display import FileLink

dir = "D:\Prototype 2\dataset"

data = []
labels = []

categories = ["with_mask", "without_mask"]

 for category in categories:
     print(category)
     path = os.path.join(dir, category)
     for img in os.listdir(path):
        img_path = os.path.join(path, img)
        image = load_img(img_path, target_size=(224, 224))
        image = img_to_array(image)
        image = image / 255.0

        data.append(image)
        labels.append(category)

one_encode = OneHotEncoder(sparse=False)
labels = np.reshape(labels, (len(labels), 1))
labels = one_encode.fit_transform(labels)

data = np.array(data)
labels = np.array(labels)


(train_images, test_images, train_labels, test_labels) = train_test_split(data, labels, test_size=0.20, stratify=labels, random_state=42)


datagen = ImageDataGenerator(
    rotation_range=20,
    zoom_range=0.15,
    width_shift_range=0.2,
    height_shift_range=0.2,
    shear_range=0.15,
    horizontal_flip=True,
    fill_mode="nearest")
datagen.fit(train_images)

reg=None
breg=L2(0.01)
num_filters=100
ac='relu'
adm=Adam(lr=0.0001,decay=0, beta_1=0.9, beta_2=0.999, epsilon=1e-08)
sgd = SGD(learning_rate=0.0001, momentum=0, decay=0)
rms = RMSprop(lr= 0.0001, epsilon=1e-08)
opt=adm
drop_dense=0.5
drop_conv=0

model = models.Sequential()

model.add(layers.Conv2D(num_filters, (3, 3), activation=ac,input_shape=(224, 224, 3)))
model.add(layers.BatchNormalization())
model.add(layers.Conv2D(num_filters, (3, 3), activation=ac))
model.add(layers.BatchNormalization())
model.add(layers.MaxPool2D(pool_size= (2,2)))
model.add(layers.Dropout(0.5))


model.add(layers.Conv2D(2*num_filters, (3, 3), activation=ac))
model.add(layers.BatchNormalization())
model.add(layers.Conv2D(2*num_filters, (3, 3), activation=ac))
model.add(layers.BatchNormalization())
model.add(layers.MaxPool2D(pool_size= (2,2)))
model.add(layers.Dropout(0.5))


model.add(layers.Flatten())
model.add(layers.Dropout(0.5))

model.add(layers.Dense(256, activation=ac, kernel_regularizer=reg))
model.add(layers.BatchNormalization())
model.add(layers.Dense(2, activation='sigmoid'))


model.summary()
model.compile(loss='binary_crossentropy', metrics=['accuracy'],optimizer=adm)
history=model.fit_generator(datagen.flow(train_images, train_labels, batch_size=32),
                    steps_per_epoch = len(train_images) / 32, epochs=100, validation_data=(test_images, test_labels))


loss, accuracy = model.evaluate(test_images, test_labels)
print("Accuracy is : ", accuracy * 100)


# plot loss
plt.subplot(211)
plt.title('Cross Entropy Loss')
plt.plot(history.history['loss'], color='blue', label='train')
plt.plot(history.history['val_loss'], color='orange', label='test')
# plot accuracy
plt.subplot(212)
plt.title('Classification Accuracy')
plt.plot(history.history['accuracy'], color='blue', label='train')
plt.plot(history.history['val_accuracy'], color='orange', label='test')
# save plot to file
# filename = sys.argv[0].split('/')[-1]
plt.savefig("plot.png")
FileLink(r'plot.png')



model.save("Mask_model.h5") # serialize weights to HDF5


FileLink(r'Mask_model.h5')

这是我对 test_images(拆分数据集)的预测:

path_data = '../input/dataaaa/data2.pkl' #list of all images in array that i saved with pickle
path_label = '../input/lablee/lable.pkl' #list of all labels that i saved with pickle (with_mask and without mask)

open_file_data = open(path_data, "rb")
data = pickle.load(open_file_data)
open_file_data.close()

open_file_label = open(path_label, "rb")
labels = pickle.load(open_file_label)
open_file_label.close()

one_encode = OneHotEncoder(sparse=False)
labels = np.reshape(labels, (len(labels), 1))
labels = one_encode.fit_transform(labels)

data = np.array(data)
labels = np.array(labels)


(train_images, test_images, train_labels, test_labels) = train_test_split(data, labels, test_size=0.20, stratify=labels, random_state=42)

correct = 0

for i in range (test_images.shape[0]):
    if y_test[i] == y_pred[i]:
        print("Actual : " , y_test[i] , "Predict : ", y_pred[i])
        correct+= 1
print("Total Test Data : ", test_images.shape[0])

print("Correct : ", correct)

这是输出:

Total Test Data : 827
Correct :  816

使用我下载的图像进行测试:

img = load_img('../input/testt2/mask.jpg') #mask image
img = img.resize((224,224))
img_array = img_to_array(img)
img = img_array / 255.0 #normalize
img = np.expand_dims(img, 0) #adding to 4d

model = load_model("../input/modell/Mask_modeladamownpreprocesbatchnormalize.h5")
pred = model.predict(img)
y_pred = [np.argmax(element) for element in pred]
print(y_pred)

输出:

# [0] is a mask image, [1] is a no mask image
[1] 

【问题讨论】:

  • 训练中有多少张图片?
  • 我认为面具的颜色很重要。例如,如果您的数据集仅包含黑色或白色蒙版,我认为您将无法预测黄色蒙版。这被认为是 ML 中的偏见。
  • 您能告诉我们训练图像数据集、测试图像数据集以及您用于测试的图像在两者之外的属性吗?
  • @AmitKanderi 我有 3306 个训练图像
  • @ZimingShan 我混合了我的数据集,但我的数据集大部分来自 github 上的 mr.Balaji Srinivasan github.com/balajisrinivas/Face-Mask-Detection 和 kaggle kaggle.com/andrewmvd/face-mask-detection

标签: python tensorflow neural-network artificial-intelligence conv-neural-network


【解决方案1】:

此问题通常是由于提供给 model.fit 的训练图像的性质与您尝试预测的图像之间存在一些差异。确保以下内容 预测图像形状应与训练图像形状相同 像素值应该相同地缩放 颜色顺序 rgb 必须是相同的顺序或两者都是灰度 您似乎有足够大小的数据集。有时问题可能在于您的训练集的性质和您尝试预测的图像存在显着不同的概率分布。要做的一件事是获取一些训练图像并将它们用作预测的输入,如果它们没有得到正确预测,那么问题如上所述。这是训练管道与预测管道的不同之处

【讨论】:

    猜你喜欢
    • 2018-12-13
    • 2018-10-23
    • 2020-05-14
    • 1970-01-01
    • 2020-09-10
    • 2018-09-24
    • 2021-06-27
    • 2019-03-28
    • 1970-01-01
    相关资源
    最近更新 更多