为什么我的CNN训练有素的图像分类器过拟合?

时间:2019-09-24 09:53:59

标签: python keras computer-vision classification data-science

我刚开始使用Computer Vision,在当前任务中,我将图像分为4类。

图像文件总数= 1043

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

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

第2/5集 320/320 [=============================]-1650s 5s / step-损耗:0.1807-acc:0.9446-val_loss :1.2694-val_acc:0.5436

第3/5集 320/320 [==============================]-1603s 5s / step-损失:0.1236-acc:0.9572-val_loss :1.2597-val_acc:0.5546

第4/5集 320/320 [=============================]-1582s 5s / step-损耗:0.1057-acc:0.9671-val_loss :1.3845-val_acc:0.5457

第5/5集 320/320 [==============================]-1580s 5s / step-损耗: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)

任何帮助将不胜感激:)

1 个答案:

答案 0 :(得分:0)

如果您不对数据“全部”使用preprocess_input,则会得到可怕的结果。

看看这些:

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

validation_datagen = ImageDataGenerator()

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

但是,如果将其同时应用于两个竖琴,重新缩放会成问题吗?

好吧...如果trainable=False正确地应用于BatchNormalization层,则意味着这些层存储了均值和方差值,只有当数据在预期范围内时,该值才有效