在 CNN 上修复过度拟合的可能方法是什么?

数据挖掘 机器学习 深度学习 喀拉斯 美国有线电视新闻网 过拟合
2021-09-27 08:47:13

目前我正在尝试制作一个允许对面部图像进行年龄检测的 cnn。我的数据集具有以下形状,其中图像是灰度的。

(50000, 120, 120) - training 
(2983, 120, 120) - testing

我的模型目前如下所示 - 我一直在测试/尝试不同的方法。

    model = Sequential()
    model.add(Conv2D(64, kernel_size=3, use_bias=False,
                     input_shape=(size, size, 1)))
    model.add(BatchNormalization())
    model.add(Activation("relu"))

    model.add(Conv2D(32, kernel_size=3, use_bias=False))
    model.add(BatchNormalization())
    model.add(Activation("relu"))

    model.add(MaxPooling2D(pool_size=(2, 2)))
    model.add(Dropout(0.25))
    model.add(Flatten())

    model.add(Dense(128, use_bias=False))
    model.add(BatchNormalization())
    model.add(Activation("relu"))

    model.add(Dropout(0.5))
    model.add(Dense(10, activation='softmax'))


    #TODO: Add in a lower learning rate - 0.001
    adam = optimizers.adam(lr=0.01)
    model.compile(optimizer=adam, loss='categorical_crossentropy',
                  metrics=['accuracy'])
    model.fit(x_train, y_train, validation_data=(x_test, y_test),
              epochs=number_of_epochs, verbose=1)

在仅 10 个 epoch 运行我的数据后,我开始看到不错的值,但在运行结束时,我的结果如下,这让我担心我的模型肯定过度拟合。

How many epochs: 10
Train on 50000 samples, validate on 2939 samples
Epoch 1/10
50000/50000 [==============================] - 144s 3ms/step - loss: 1.7640 - acc: 0.3625 - val_loss: 1.6128 - val_acc: 0.4100
Epoch 2/10
50000/50000 [==============================] - 141s 3ms/step - loss: 1.5815 - acc: 0.4059 - val_loss: 1.5682 - val_acc: 0.4059
Epoch 3/10
50000/50000 [==============================] - 141s 3ms/step - loss: 1.5026 - acc: 0.4264 - val_loss: 1.6673 - val_acc: 0.4158
Epoch 4/10
50000/50000 [==============================] - 141s 3ms/step - loss: 1.3996 - acc: 0.4641 - val_loss: 1.5618 - val_acc: 0.4209
Epoch 5/10
50000/50000 [==============================] - 141s 3ms/step - loss: 1.2478 - acc: 0.5226 - val_loss: 1.6530 - val_acc: 0.4066
Epoch 6/10
50000/50000 [==============================] - 141s 3ms/step - loss: 1.0619 - acc: 0.5954 - val_loss: 1.6661 - val_acc: 0.4086
Epoch 7/10
50000/50000 [==============================] - 141s 3ms/step - loss: 0.8695 - acc: 0.6750 - val_loss: 1.7392 - val_acc: 0.3770
Epoch 8/10
50000/50000 [==============================] - 141s 3ms/step - loss: 0.7054 - acc: 0.7368 - val_loss: 1.8634 - val_acc: 0.3743
Epoch 9/10
50000/50000 [==============================] - 141s 3ms/step - loss: 0.5876 - acc: 0.7848 - val_loss: 1.8785 - val_acc: 0.3767
Epoch 10/10
50000/50000 [==============================] - 141s 3ms/step - loss: 0.5012 - acc: 0.8194 - val_loss: 2.2673 - val_acc: 0.3981
Model Saved

我认为这个问题可能与我为每个输出类拥有的图像数量有关,但除此之外我有点卡在前进中。我的理解/实施有问题吗?任何建议或批评都将不胜感激,这对我来说更像是一个学习项目。

2个回答

为了处理过拟合,你需要在训练过程中使用正则化:

  1. 权重正则化- 您必须做的第一件事(几乎总是)是对模型的权重使用正则化。L1 或 L2 正则化通过添加另一个称为正则化项的项来更新一般损失函数。结果,权重值会降低,因为它假设具有较小权重的神经网络会导致更简单的模型。因此,它也会减少过拟合。如果您不确定自己需要什么,请使用 L2。

    Keras - 正则化器的使用

  2. Dropout - 在密集层之后添加 dropout 层(顺便说一下,在卷积层之后使用 dropout 也有好处,它有助于遮挡)。只要确保不要在最后的密集层(与类数大小相同的层)使用它。

  3. 数据增强——减少过度拟合的最简单方法是增加训练数据的大小。使用数据增强可能会将您的训练集扩展到“无穷大”。Keras 的数据增强非常简单易用:

    Keras 图像预处理

如果您实施这 3 个步骤,您将看到显着的改进(甚至可能在第一个步骤之后)。

进一步的修正和改进(与过拟合无关):

  • 你的批量归一化层应该在非线性激活之后,或者更准确地说,它需要在下一个卷积层之前。
  • 添加一个或 2 个额外的密集层(仅当结果不够好时)。

尝试在密集层之后使用 dropout,而不是在 maxpooling 层之后。密集层之前的任何东西都可以被视为分类层的输入。所以保留它们,否则它在某种程度上意味着你正在丢失适当的信息。您还应该知道,您不应该在最后一层之后使用 dropout。

您还可以添加另一个密集层,两个隐藏的密集层,用于分类。看来您的数据不容易学习。