CNN过度拟合(带输出和代码)

时间:2017-09-07 17:36:13

标签: python deep-learning keras

我有一个数据集,其中包含我要分类的2个类的20000个黑白图像(图像有点像天气预报或股市图表,所以我不能使用预训练网络)。数据集已分为18000个图像  培训和2000图像用于测试目的。我正在使用Keras卷积神经网络进行训练。我有96%的准确率   训练集但是用测试集获得的结果不好(在50个时期后它被卡在82-83%)。我想这可能是因为过度拟合。请 你能建议我解决问题吗?我留下最终输出和代码供你查看。

281/281 [==============================] - 132s - 损失:0.1024 - acc:0.9612 - val_loss :0.5836 - val_acc:0.8210

from keras.layers.normalization import BatchNormalization
from keras.preprocessing.image import ImageDataGenerator
from keras.models import Sequential
from keras.layers import Conv2D, MaxPooling2D, ZeroPadding2D
from keras.layers import Activation, Dropout, Flatten, Dense
from keras import backend as K
from keras.optimizers import SGD, RMSprop, Adam
from keras.callbacks import ModelCheckpoint 


filepath="weights/weights-improvement-{epoch:02d}-{val_acc:.4f}.hdf5"
checkpoint = ModelCheckpoint(filepath, monitor='val_acc', verbose=1, save_best_only=True, mode='max')
callbacks_list = [checkpoint]


img_width, img_height = 100, 1296

train_data_dir = 'dataset/train'
validation_data_dir = 'dataset/validation'
nb_train_samples = 18000
nb_validation_samples = 2000
epochs = 100
batch_size = 64

input_shape = (img_width, img_height, 1)

model = Sequential()

model.add(Conv2D(32, (3, 3), input_shape=input_shape))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))

model.add(ZeroPadding2D((1, 1)))
model.add(Conv2D(32, (3, 3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.1))

model.add(ZeroPadding2D((1, 1)))
model.add(Conv2D(64, (3, 3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.2))

model.add(ZeroPadding2D((1, 1)))
model.add(Conv2D(128, (3, 3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.3))

model.add(ZeroPadding2D((1, 1)))
model.add(Conv2D(256, (3, 3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.4))

model.add(ZeroPadding2D((1, 1)))
model.add(Conv2D(512, (3, 3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.5))

model.add(Flatten())

model.add(Dense(256))
model.add(Activation('relu'))
model.add(BatchNormalization())
model.add(Dropout(0.5))

model.add(Dense(256))
model.add(Activation('relu'))
model.add(BatchNormalization())
model.add(Dropout(0.5))

model.add(Dense(1))
model.add(Activation('sigmoid'))

model.compile(loss='binary_crossentropy',
               optimizer=Adam(lr=0.001),
              metrics=['accuracy'])

model.save('model.h5')

train_datagen = ImageDataGenerator(
    rescale=None,
)

test_datagen = ImageDataGenerator(rescale=None)

train_generator = train_datagen.flow_from_directory(
    train_data_dir, color_mode='grayscale',
    target_size=(img_width, img_height),
    batch_size=batch_size,
    class_mode='binary')

validation_generator = test_datagen.flow_from_directory(
    validation_data_dir, color_mode='grayscale',
    target_size=(img_width, img_height),
    batch_size=batch_size,
    class_mode='binary')

model.fit_generator(
    train_generator,
    steps_per_epoch=nb_train_samples // batch_size,
    epochs=epochs,
    validation_data=validation_generator,
    validation_steps=nb_validation_samples // batch_size,callbacks=callbacks_list)

2 个答案:

答案 0 :(得分:2)

您的网络中有大量参数 - 由于几个大的卷积层和两个大的完全连接的层。这可能导致过度拟合。我建议减少它们的尺寸,并且可能完全摆脱几个层。

答案 1 :(得分:2)

由于您有过度拟合问题,为什么不尝试正规化?您可以将每个图层附加到正则化程序。我通常使用权重正则化器,现在称为核正则化器。您可以在https://keras.io/regularizers/

找到Keras正规化器文档

提高辍学率可能也有帮助,但首先尝试使用正规化。获得更多训练数据也有助于减少过度拟合,但并不总是能够提供更多的训练数据。