验证损失和验证准确率均高于训练损失,且ACC和波动

Posted

技术标签:

【中文标题】验证损失和验证准确率均高于训练损失,且ACC和波动【英文标题】:Validation loss and validation accuracy both are higher than training loss and acc and fluctuating 【发布时间】:2020-04-27 02:13:53 【问题描述】:

我正在尝试使用迁移学习来训练我的模型,为此我使用 VGG16 模型,剥离顶层并冻结前 2 层以使用 imagenet 初始权重。为了微调它们,我使用学习率 0.0001、激活 softmax、dropout 0.5、损失分类交叉熵、优化器 SGD、46 类。

我只是无法理解训练时的行为。 train loss 和 acc 都很好(loss 正在减少, acc 正在增加)。 Val loss 正在减少,acc 也在增加,但它们总是高于 train loss 和 acc。

假设它过度拟合,我降低了模型的复杂性,增加了辍学率,向 val 数据添加了更多样本,但似乎没有任何效果。我是新手,所以任何形式的帮助表示赞赏。

26137/26137 [==============================] - 7446s 285ms/step - loss: 1.1200 - accuracy: 0.3810 - val_loss: 3.1219 - val_accuracy: 0.4467
Epoch 2/50
26137/26137 [==============================] - 7435s 284ms/step - loss: 0.9944 - accuracy: 0.4353 - val_loss: 2.9348 - val_accuracy: 0.4694
Epoch 3/50
26137/26137 [==============================] - 7532s 288ms/step - loss: 0.9561 - accuracy: 0.4530 - val_loss: 1.6025 - val_accuracy: 0.4780
Epoch 4/50
26137/26137 [==============================] - 7436s 284ms/step - loss: 0.9343 - accuracy: 0.4631 - val_loss: 1.3032 - val_accuracy: 0.4860
Epoch 5/50
26137/26137 [==============================] - 7358s 282ms/step - loss: 0.9185 - accuracy: 0.4703 - val_loss: 1.4461 - val_accuracy: 0.4847
Epoch 6/50
26137/26137 [==============================] - 7396s 283ms/step - loss: 0.9083 - accuracy: 0.4748 - val_loss: 1.4093 - val_accuracy: 0.4908
Epoch 7/50
26137/26137 [==============================] - 7424s 284ms/step - loss: 0.8993 - accuracy: 0.4789 - val_loss: 1.4617 - val_accuracy: 0.4939
Epoch 8/50
26137/26137 [==============================] - 7433s 284ms/step - loss: 0.8925 - accuracy: 0.4822 - val_loss: 1.4257 - val_accuracy: 0.4978
Epoch 9/50
26137/26137 [==============================] - 7445s 285ms/step - loss: 0.8868 - accuracy: 0.4851 - val_loss: 1.5568 - val_accuracy: 0.4953
Epoch 10/50
26137/26137 [==============================] - 7387s 283ms/step - loss: 0.8816 - accuracy: 0.4874 - val_loss: 1.4534 - val_accuracy: 0.4970
Epoch 11/50
26137/26137 [==============================] - 7374s 282ms/step - loss: 0.8779 - accuracy: 0.4894 - val_loss: 1.4605 - val_accuracy: 0.4912
Epoch 12/50
26137/26137 [==============================] - 7411s 284ms/step - loss: 0.8733 - accuracy: 0.4915 - val_loss: 1.4694 - val_accuracy: 0.5030

【问题讨论】:

您是否观察到验证损失是否在一些时期后上升?如果您的验证损失高于训练损失,则完全没问题,您的模型仍在学习。自然,您不能让验证损失小于您的训练损失(如果模型足够深,它确实会非常接近您的训练损失)。但是,如果您的验证损失增加并且您的训练损失不断减少,那么您就是过拟合了。使用Earlystopping解决过拟合问题。 我更担心 val acc 大于 train acc 而不是 loss ,并且 val loss 有时会波动,有时会上升有时会下降 我仍然怀疑准确性是否是观察过度拟合的好方法。在任何情况下,您都可以使用EarlyStopping keras 回调。 Keras 将监视指标以避免过度拟合,以防提供的指标没有改进。 @Siddhant Tandon 有一个完美的答案! val loss 不断减少,而大于训练损失是绝对可以的,因为模型正在与正则化和 dropout 作斗争并且仍然学习良好......直到 val loss 增加然后是停止它或使用检查点权重保存。 【参考方案1】:

是的,您面临过拟合问题。为了缓解,您可以尝试实施以下步骤

1.Shuffle Data,通过在 VGG16_model.fit 中使用 shuffle=True。代码如下:

history = VGG16_model.fit(x_train, y_train, batch_size=batch_size, epochs=epochs, verbose=1,
                   validation_data=(x_validation, y_validation), shuffle = True)

2.使用Early Stopping。代码如下所示

callback = tf.keras.callbacks.EarlyStopping(monitor='val_loss', patience=15)

3.使用正则化。正则化代码如下(你可以试试 l1 正则化或 l1_l2 正则化):

from tensorflow.keras.regularizers import l2

Regularizer = l2(0.001)

VGG16_model.add(Conv2D(96,11, 11, input_shape = (227,227,3),strides=(4,4), padding='valid', activation='relu', data_format='channels_last', 
                    activity_regularizer=Regularizer, kernel_regularizer=Regularizer))

VGG16_model.add(Dense(units = 2, activation = 'sigmoid', 
                    activity_regularizer=Regularizer, kernel_regularizer=Regularizer))

4.您可以尝试使用BatchNormalization

5. 使用ImageDataGenerator 执行图像数据增强。请参阅this link 了解更多信息。

6.如果像素不是Normalized,将像素值除以255也有帮助

【讨论】:

@Madiha Samad,如果它回答了您的问题,您能否接受并投票赞成。谢谢

以上是关于验证损失和验证准确率均高于训练损失,且ACC和波动的主要内容,如果未能解决你的问题,请参考以下文章

验证损失在 3 个 epoch 后增加,但验证准确度不断增加

图像分类。验证损失在初始训练期间卡住(v1)

验证损失不断减少,而训练损失在 3 个 epoch 后开始增加

文本二进制分类训练期间的波动损失

Keras - 验证损失和准确性停留在 0

CNN分类中验证损失减少,验证准确率下降