训练 CNN 的结果看似不错,但测试时效果不佳

数据挖掘 深度学习 喀拉斯 卷积
2022-03-13 13:28:29

我有一个图像分类任务,我将 Keras 用于具有 CNN 层的网络,在训练中似乎取得了不错的结果,但在测试中却表现不佳。在训练后,我很快看到准确度和验证准确度提高到以下水平:

4678/4678 [==============================] - 2s 427us/step - loss: 0.0607 - acc: 0.9795 - val_loss: 0.1605 - val_acc: 0.9590

现在我的第一反应是,这可能好得令人难以置信,事实确实如此。在测试模型时,它的性能很差。

Bashar Haddad认为可能存在数据不平衡问题,但是对于以下数据规范,在拆分为 25% 验证之前,我认为这不是我的问题:

(data is being fit consecutively in a for loop)
average number of datapoints in training: 4500
average number of datapoints in testing: 1500
average number of classes: 46 (max 49)

并且大多数类在每个类中都有大量的数据点。

基于,我看到用户发现增加批量大小和降低学习率有帮助,我通过以下方式拟合模型......

varying batch size from 100 -> 500
varying epochs size from 50 -> 250
cnn_model.fit(X_train, y_train,
                        batch_size=500,
                        epochs=50,
                        verbose=1,
                        shuffle=True,
                        validation_data=(X_test, y_test)
            )

变化无常batch_sizeepochs几乎没有影响。

由于准确度和验证准确度都很高,而且在训练时它们之间的差异也很小,我很困惑为什么在测试数据上使用这个模型会导致如此糟糕的性能。

这可能是什么原因?以及可能的解决方案来解决它?

3个回答

您的模型可能只是过拟合。这是神经网络的经典案例。这意味着您的模型在训练数据上非常好,但在测试数据上表现不佳,即它在泛化方面非常糟糕......

您可以监控验证集的性能并使用dropout来规避过度拟合...

[编辑] 正如@Jan van der Vegt 所说,不太可能对验证集进行过度拟合。过去我也发生过类似的事情,结果证明我使用的验证集非常小。我仍然不确定为什么,但我在训练集和验证集上的表现非常相似。一旦我增加了验证集的大小,这种行为就消失了。虽然数据泄漏确实是我的第一个猜测,但我在创建数据集的方式中找不到任何错误。所以我的建议是:确保训练集和验证集之间没有数据泄漏,并确保你的验证分数可以通过拥有足够大的验证大小来信任......

我不认为这是过度拟合的问题。您的验证损失/准确性很好,并且该域不适合目标泄漏。我的第一个倾向是在将测试图像输入网络之前的预处理是不一样的,这意味着你的输入分布不同并且学习的映射不适用。您是否使用训练集统计数据对图像进行预处理?您是否以正确的方式将此预处理管道保存在某处?

另一个问题可能是您的训练/验证拆分未正确完成,验证集中的样本也在您的训练集中,使其成为不正确的验证集。

我有过非常相似的情况。

plt.imshow()当我使用(matplotlib.pyplot.imshow() 为初学者显示图像时-处理”它很好,对于训练和测试也是一样的。

长话短说,我将我的训练数据重新缩放到 [0,1] 但我忘记对我的测试数据做同样的事情(我使用与我的训练数据略有不同的方法加载它),所以我的测试数据保持在 [1,255] 范围内。这导致测试集上的指标非常糟糕。

plt.imshow()重新调整我的数据,以便我看不到图像之间的比例差异。

故事的寓意,如果你用尽了所有可能导致验证集和测试集之间有意义差异的原因(假设 CNN 和图像分类,并且超参数没有可能过度拟合导致验证集数据泄漏),请再次检查,因为你显然没有。训练集、验证集和测试集的分布仍有一些差异。