这是明显的过拟合吗?

数据挖掘 机器学习 神经网络 过拟合
2021-09-30 19:36:49

准确性与时代

橙色曲线是训练准确度,蓝色是验证准确度。这是明显的过度拟合还是我应该让它运行更多的时期?

使用自定义数据集(具有 70 个特征的一维数据),我训练了一个 2 层 MLP。网络架构:[70-200-200-4]。我只能达到约 50+% 的准确度。关于我可以采取哪些步骤来提高准确性的任何建议?(获取更多数据不是一种选择)

提前致谢!

3个回答

当训练准确率增加而验证准确率保持不变或降低时,模型很可能是过拟合的,或者可能是饱和的。

您可以尝试以下方法来提高准确性:

您可以采取一些方法来确定如何以及是否可以提高准确性。此处简要概述的一些选项是将网络结果与基线估计器进行比较、诊断错误分类、应用降维和网络架构故障排除。

在对数据了解不多的情况下,我认为您可以尝试通过将网络性能与决策树或支持向量机等基线估计器进行比较来确定是否甚至可以提高网络的准确性。使用决策树的好处是,诸如ID3之类的算法使用信息增益来进行拆分,这可能会让您对数据有一些直觉,以及是否有可能在投入时间之前提高准确性。如果您还没有,您可以进行一些探索性分析以了解数据/类的噪声程度。

仔细查看您的网络所犯的错误也可能很有用。混淆矩阵或分类报告可以帮助您诊断您的网络是否在(例如)某个特定类别或决策边界的特定区域中挣扎。如果您的课程不平衡,您可以考虑重新加权您的训练示例和方法,例如 Benji 提到的 SMOTE 等。

有了 70 个特征,网络可能会从一些降维中受益。如果您将PCA应用于数据,您可以确定需要多少个组件来解释数据中合理数量的方差,或者它是否更复杂。如果将转换后的数据而不是原始数据作为输入,您的网络可能会做出更好的响应(关于该主题,您是否对数据进行了预处理?)。

最后,更广泛的架构搜索可能会产生更好的结果——我假设您可能已经这样做了,但是您是否尝试过增加每一层中的单元或删除第二个隐藏层?您也可以尝试使用不同的激活函数或不同的学习率计划。Bengio 的“基于梯度的深度架构训练的实用建议”值得一读(这篇文章主要针对更深层次的网络,但第 3.1、3.2 和 4 节的元素是相关的)。

这个答案只是简单地触及了每个领域,但我希望你能找到一些可靠的线索。

很难确定这是否实际上是过度拟合,因为您的验证准确度尚未开始下降。过拟合的特点是一组模型参数在训练集上表现非常好,但不能泛化到数据的不同子集。

我假设您正在使用基于这些图的 Keras。为了避免在训练时过度拟合,您可以仅在模型在您的验证集上变得更好时保存权重,并忽略那些没有更好或更差的权重。这将确保在训练课程结束时,您拥有将最佳推广到验证集的权重保存到文件中,然后可以将其加载到模型中。

在 Keras 中只保存最好的权重集

使用将在 epoch 之间运行的回调

name = 'my_model'

if not os.path.exists('weights//'+name):
    os.makedirs('weights//'+name)

# Save the weights using a checkpoint.
filepath='weights//' + name + '//weights-improvement-{epoch:02d}-{val_acc:.2f}.hdf5'
checkpoint = ModelCheckpoint(filepath, monitor='val_acc', verbose=1, save_best_only=True, mode='max')
callbacks_list = [checkpoint]

epochs = 100
# Fit the model weights.
history = model.fit_generator(generator=training_generator,
                              steps_per_epoch=training_generator.num_batches,
                              epochs=epochs,
                              verbose=1,
                              callbacks=callbacks_list,
                              validation_data=validation_generator,
                              validation_steps=validation_generator.num_batches)

加载你最好的一组重量

然后,当训练完成后,您可以使用检索最佳权重集

weight_filename = '...'
model.load_weights('weights//' + name + weight_filename)