如何在这个模型中避免过拟合?

3

我为一个图像分类问题创建了这个模型。我遇到的问题是验证准确率总是比训练准确率低 5-8%,且验证损失远高于训练损失。以下是一个 epoch 的示例: 损失率: 0.2232,准确率: 0.9245,验证损失率: 0.4131,验证准确率: 0.8700

model = Sequential()

model.add(Conv2D(32, 3, 3, border_mode='same', input_shape=(150, 
150, 3), activation='relu'))
model.add(Conv2D(32, 3, 3, border_mode='same', activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))

model.add(Conv2D(64, 3, 3, border_mode='same', activation='relu'))
model.add(Conv2D(64, 3, 3, border_mode='same', activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))

model.add(Conv2D(128, 3, 3, border_mode='same', 
activation='relu'))
model.add(Conv2D(128, 3, 3, border_mode='same', 
activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))

model.add(Conv2D(256, 3, 3, border_mode='same', 
activation='relu'))
model.add(Conv2D(256, 3, 3, border_mode='same', 
activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))

model.add(Flatten())
model.add(Dense(256, activation='relu'))
model.add(Dropout(0.5))

model.add(Dense(256, activation='relu'))
model.add(Dropout(0.5))

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

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

# this is the augmentation configuration we will use for training
train_datagen = ImageDataGenerator(
    rescale=1. / 255,
    shear_range=0.1,
    zoom_range=0.1,
    horizontal_flip=True)

# this is the augmentation configuration we will use for testing:
# only rescaling
test_datagen = ImageDataGenerator(rescale=1. / 255)

我尝试使用Hyperas进行贝叶斯超参数优化,但它推荐的模型超参数并没有真正适合我。我应该如何更改我的模型以防止过拟合?由于将来用于实际情况的数据不多,我没有使用太多数据来训练和验证模型。非常感谢您的任何建议。


你有多少数据,记录? - Dean Van Greunen
1
你可以尝试使用较小的批处理大小,例如10。还可以尝试不同的优化器,如Adagrad。 - Chris Farr
1
这并不是一个真正的编程问题。 - Dr. Snoopy
嗨 @DeanVanGreunen 我有两个类。每个类别有2000张图像用于训练数据,每个类别有400张图像用于验证数据。 - Jaime Miranda
嗨@ChrisFarr,谢谢。我会尝试的。 - Jaime Miranda
2个回答

4

过拟合是一回事,训练和验证误差是另一回事。

你的训练分数比验证分数好,并不意味着你正在过拟合。当你的验证分数达到最高点后并开始随着训练变得越来越糟时,才说明你正在过拟合。

如果你想要更好的验证分数-更好的模型泛化,你可以做以下几件事:

  • 增加丢弃率(你的丢弃率看起来已经足够好了,但可以尝试提高一下,看看会发生什么),

  • 使用更多的数据进行训练(根据上面所说,这是不可能的)

  • 尝试更重的数据增强

  • 尝试预训练网络

  • 尝试集成学习

  • 尝试测试时间增强(tta)

  • 尝试任何其他的训练策略,如余弦退火、混合生成器或其他生成器(不是 Keras), 如 albumentations


1
感谢您的回答。据我理解,当验证损失高于训练损失时,这是过拟合的迹象,而相反则是欠拟合的迹象。 - Jaime Miranda
如果您的验证分数在训练过程中不断提高,即使训练分数优于验证分数,也不会出现过拟合。 - Ioannis Nasios
验证损失一直在波动,有时更好,有时更差。我有一个绘制了训练和验证损失的图表,但我不知道如何在这里分享它。 - Jaime Miranda

2
你在测试阶段有关闭DropOut层吗?
由于DropOut层仅用于训练阶段以防止过拟合,在测试阶段不使用。这就是为什么Tf.Estimator现在很流行,因为你可以用is_training=True/False更容易地关闭DropOut。
你可以使用tf.keras.backend.set_learning_phase(0)来关闭。请确保你正在使用tensorflow.keras.layers中的Conv2D、MaxPooling2D、Dense、Dropout、Input、Flatten。tf.keras和keras之间有所不同,tf.keras更好。
如果你已经关闭了DropOut,下面是我的一些预防过拟合技巧: - 进行错误分析。你可以参考Andrew教授最好的材料:https://www.coursera.org/learn/machine-learning-projects?specialization=deep-learning - 检查测试和训练集的分布,数据增强(翻转、旋转等) - 增加InputShape以获取更多特征。目前最好的技术之一是使用复合比例缩放方法:https://arxiv.org/pdf/1905.11946.pdf
希望这能帮到你!愉快的编程!

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接