为啥我的 CNN 预训练图像分类器过拟合?

Posted

技术标签:

【中文标题】为啥我的 CNN 预训练图像分类器过拟合?【英文标题】:Why is my CNN pre trained image classifier overfitting?为什么我的 CNN 预训练图像分类器过拟合? 【发布时间】:2020-01-24 10:05:46 【问题描述】:

我刚刚开始使用计算机视觉,在当前任务中我将图像分为 4 个类别。

图片文件总数=1043

我正在使用预训练的 InceptionV3 并在我的数据集上对其进行微调。

这是我在时代之后所拥有的: 纪元 1/5 320/320 [===============================] - 1925s 6s/步 - 损失:0.4318 - acc: 0.8526 - val_loss : 1.1202 - val_acc: 0.5557

纪元 2/5 320/320 [===============================] - 1650s 5s/步 - 损失:0.1807 - acc: 0.9446 - val_loss : 1.2694 - val_acc: 0.5436

纪元 3/5 320/320 [===============================] - 1603s 5s/步 - 损失:0.1236 - acc: 0.9572 - val_loss : 1.2597 - val_acc: 0.5546

4/5 纪元 320/320 [===============================] - 1582s 5s/step - loss: 0.1057 - acc: 0.9671 - val_loss : 1.3845 - val_acc: 0.5457

5/5 纪元 320/320 [==============================] - 1580s 5s/步 - 损失:0.0982 - acc: 0.9700 - val_loss : 1.2771 - val_acc: 0.5572 这是一个巨大的差异。请帮助我弄清楚为什么我的模型无法泛化,因为它非常适合火车数据。

我的参考代码:-

from keras.utils import to_categorical
from keras.models import Model
from keras.layers import Dense, GlobalAveragePooling2D, Dropout
from keras.applications.inception_v3 import InceptionV3, preprocess_input

CLASSES = 4

# setup model
base_model = InceptionV3(weights='imagenet', include_top=False)
from sklearn.preprocessing import OneHotEncoder
x = base_model.output
x = GlobalAveragePooling2D(name='avg_pool')(x)
x = Dropout(0.4)(x)
predictions = Dense(CLASSES, activation='softmax')(x)
model = Model(inputs=base_model.input, outputs=predictions)

for layer in base_model.layers:
    layer.trainable = False

model.compile(optimizer='rmsprop',
              loss='categorical_crossentropy',
              metrics=['accuracy'])        

from sklearn.preprocessing import LabelEncoder
encoder = LabelEncoder()
df['Category']= encoder.fit_transform(df['Category'])



from keras.preprocessing.image import ImageDataGenerator

WIDTH = 299
HEIGHT = 299
BATCH_SIZE = 32


train_datagen = ImageDataGenerator(rescale=1./255,preprocessing_function=preprocess_input)



validation_datagen = ImageDataGenerator(rescale=1./255)


df['Category'] =df['Category'].astype(str)
#dfval['Category'] = dfval['Category'].astype(str)




from sklearn.utils import shuffle
df = shuffle(df)

from sklearn.model_selection import train_test_split

dftrain,dftest = train_test_split(df, test_size = 0.2, random_state = 0)

train_generator = train_datagen.flow_from_dataframe(dftrain,target_size=(HEIGHT, WIDTH),batch_size=BATCH_SIZE,class_mode='categorical', x_col='Path', y_col='Category')

validation_generator = validation_datagen.flow_from_dataframe(dftest,target_size=(HEIGHT, WIDTH),batch_size=BATCH_SIZE,class_mode='categorical', x_col='Path', y_col='Category')



EPOCHS = 5
BATCH_SIZE = 32
STEPS_PER_EPOCH = 320
VALIDATION_STEPS = 64

MODEL_FILE = 'filename.model'

history = model.fit_generator(
    train_generator,
    epochs=EPOCHS,
    steps_per_epoch=STEPS_PER_EPOCH,
    validation_data=validation_generator,
    validation_steps=VALIDATION_STEPS)

任何帮助将不胜感激:)

【问题讨论】:

如果不能查看您的数据,很难说。它看起来像什么? Inception 是一个非常深的神经网络,在处理大量数据时效果最好,这种网络的图像数量(即 1043)非常少,因此它是过拟合的。尝试增加图片数量 @JosephBudin 图片是文档的扫描副本。 @techytushar 我已经在扩充图像了。 @JosephBudin 结果没有增强:- Epoch 1/5 320/320 [=========================== ===] - 3497s 11s/step - loss: 0.3839 - acc: 0.8761 - val_loss: 1.4405 - val_acc: 0.4658 【参考方案1】:

如果您不在“所有”数据中使用preprocess_input,您将得到糟糕的结果。

看看这些:

train_datagen = ImageDataGenerator(
    preprocessing_function=preprocess_input, 
    ...)

validation_datagen = ImageDataGenerator()

现在,我注意到您正在使用rescale。由于您从初始代码中导入了正确的 preprocess_input 函数,我真的认为您不应该使用这种重新调整。 preprocess_input 函数应该进行所有必要的预处理。 (并非所有模型都使用归一化输入进行训练)

但是,如果您将其应用于两个 bataset,重新缩放会成为问题吗?

嗯...如果trainable=False 正确应用于BatchNormalization 层,这意味着这些层已经存储了平均值和变化值,只有在数据在预期范围内时才能正常工作。

【讨论】:

非常正确的丹尼尔,我不知道我是怎么错过的!添加了相同的。会让你知道模型的表现。谢谢:) 在验证生成器中使用“preprocess_input”时,验证准确率从 48% 下降到 12%,令人惊讶 也更新了代码和验证准确性。请看一看。模型仍然过拟合。 :// @dataguy 我相信问题在于使用rescale。请参阅答案中的详细信息。 删除的“重新缩放”模型仍然过拟合。如果我必须根据上面的徽标对文档进行分类,那么如果我使用对象检测进行分类呢?

以上是关于为啥我的 CNN 预训练图像分类器过拟合?的主要内容,如果未能解决你的问题,请参考以下文章

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

Keras Resnet-50 图像分类过拟合

这是过拟合的情况吗? CNN图像分类器

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

图像序列的分类(固定数量)

训练CNN模型图像分类期间的tensorflow NaN损失