验证损失达到最小值然后增加
Posted
技术标签:
【中文标题】验证损失达到最小值然后增加【英文标题】:Validation loss hitting minimum then increasing 【发布时间】:2021-04-07 21:20:18 【问题描述】:可以看出,在 epoch 60 左右,我的验证损失开始增加,而我的验证准确度保持不变。似乎在那个时候它开始过度拟合,但如果只是记住我的训练数据,训练损失不会继续减少到接近零吗?我的模型似乎也很小,无法过度拟合(我正在尝试对 FFT 数据进行分类)。是不是我公然做错了什么?
这是我的模型:
model = Sequential()
model.add(Conv1D(filters = 32, kernel_size = 3, activation = 'relu', input_shape = (size, 1)))
model.add(Dropout(dropout))
model.add(GlobalMaxPooling1D())
model.add(Dropout(dropout))
model.add(Dense(64, activation='relu'))
model.add(Dense(1, activation='sigmoid')) #Output layer
我的训练数据形状:
x: (1038, 2206)
y: (1038, 1)
我的参数:
EPOCHS = 300
LR = 1e-3
辍学 = 0.5
BATCH_SIZE = 128
顺便说一句,我的验证准确率约为 98%,但是当我在相同的验证数据上测试我的模型时,我得到了不正确的输出。我不认为我的验证数据制作不正确,因为我制作它的方式与我的训练数据完全相同。
【问题讨论】:
你的数据集大小是多少? @Andrey 抱歉,我输入了我的验证数据形状。我有 1038 个样本,包含 2206 个值(每批将是 (128,2206))。 使用过拟合,如果你的训练损失足够低,那么它将保持在一般范围内,而验证损失会增加。损失也很难变为零,即使是训练损失。我相信你对你过度拟合的最初假设是正确的。 所以我唯一的选择是扩大我的数据或缩小我的网络? @AaronJones 不,您还可以评估您当前的数据集,看看是否有更好的方法可以分割您的数据集。也许您的验证数据集中有一些数据与您的训练数据集有很大的不同,可能会导致这种增加。我也不会让你的模型更小,而只是重新评估它的架构。 【参考方案1】:您的损失图看起来是经典的过度拟合,考虑到模型的简单性,这很奇怪。我要改变的模型中的一件事是你有
model.add(Dropout(dropout))
model.add(GlobalMaxPooling1D())
model.add(Dropout(dropout))
全局最大池没有激活函数,所以我认为不需要第二个 dropout 层。实际上,辍学率为 0.5,我也很惊讶你的模型火车 就像它一样。您提到创建验证集,所以我假设您选择了验证数据。通常最好使用 sklearn 的 train_test_split 函数通过从完整数据集中随机选择来创建验证数据。有了 dropout 的数量,您的模型可能无法达到 100% 的训练准确度。我会尝试的一件事是使用 Keras 回调 ReduceLROnPlateau 使用可调整的学习率。设置它来监控验证损失。如果损失未能减少“耐心”的时期数,则学习率将减少一个“因子”,其中因子的值小于 1.0。文档位于here.以下是我对代码的推荐。
lr_adjust= tf.keras.callbacks.ReduceLROnPlateau(
monitor="val_loss", factor=0.5, patience=2,verbose=1,mode="auto")
现在在 model.fit 添加 callbacks=[lr_adjust] 您不显示您的 model.compile 代码,但您可以尝试使用不同的优化器来查看它是否有效果。我推荐亚当优化器。我怀疑正在发生的是,您的测试集的概率分布与您的训练和验证集的概率分布显着不同。鉴于您在测试数据是“现实生活数据”时综合创建了后者,这使得概率分布不同的情况很可能发生。
【讨论】:
我选择我的验证数据是为了测试它是否适用于真实数据。我的训练数据是“合成的”(即生成的),而验证数据是您在现实生活中得到的数据。 我也喜欢这个答案,它扩展了学习率和 dropout 层对训练的影响。以上是关于验证损失达到最小值然后增加的主要内容,如果未能解决你的问题,请参考以下文章