Keras Sequential模型中的验证数据有什么用途?

100

我的问题很简单,就是在Sequential模型中,传递给model.fit的验证数据是什么

另外,它是否会影响模型的训练(通常会使用验证集来选择模型的超参数,但我认为这在此处并不会发生)?

我指的是可以像这样传递验证集的内容:

# Create model
model = Sequential()
# Add layers
model.add(...)

# Train model (use 10% of training set as validation set)
history = model.fit(X_train, Y_train, validation_split=0.1)

# Train model (use validation data as validation set)
history = model.fit(X_train, Y_train, validation_data=(X_test, Y_test))

我进行了调查,发现keras.models.Sequential.fit调用keras.models.training.fit,后者创建变量如val_accval_loss(可以从回调中访问)。 keras.models.training.fit还调用keras.models.training._fit_loop,将验证数据添加到callbacks.validation_data中,并调用keras.models.training._test_loop,将验证数据按批次循环处理在模型的self.test_function上。该函数的结果用于填充日志的值,也就是回调可访问的值。

看到这一切,我觉得传递给model.fit的验证集在训练过程中没有用于验证任何东西,它的唯一用途是为了获得有关训练模型在每个时期中如何执行的完全独立的数据。因此,使用相同的验证集和测试集应该没问题,对吗?

有人能否确认model.fit中的验证集除了被读取回调之外是否还有其他目的?

4个回答

109
如果您想要构建一个稳健的模型,那么您需要遵循特定的三组数据切割协议:一组用于训练,一组用于验证,另外一组则是最终评估 - 也就是测试集。

这个思路是基于您使用训练数据进行训练,然后通过验证数据得到指标(如准确率、损失等)来调整您的模型。

您的模型“看不见”验证集,也没有经过验证集的任何训练,但是您作为架构师和超参数的大师会根据这些数据来调整模型。因此,它间接地影响了您的模型,因为它直接影响了您的设计决策。您会通过这种方式使您的模型更好地适应验证数据并有可能产生倾斜。

这正是您只在没有使用过您的模型或者您本人使用过的数据上进行模型最终得分评估的原因 - 这就是第三组数据,即测试集。

只有这样的流程才能保证您对模型质量和其推广能力的观察是不受影响的,而且可以将学到的知识泛化到完全看不见的数据上。


5
好的,我已经明白了,但正如你所说的那样。基本上,因为我们可以通过验证准确性和损失来了解模型的情况,我们需要一个不同的测试集来验证我们所学到的知识。例如,如果我有三个模型,在相同的训练数据中对它们进行训练,我会得到每个模型的验证准确性,我会选择“最佳模型”,然后在不同的测试集中测试所选择的模型,以获得模型的准确性。如果我用验证集来做这个,结果会有偏差。 - danidc
当我们想在Keras中使用train_on_batch()处理大型数据集时,有什么相同的验证解决方法? - afruzan
1
当使用 "model.fit(X_train, Y_train, validation_data=(X_test, Y_test))" 时,是否仍然需要使用 ".predict()" 或 ".evaluate()"(使用 X_test、Y_test 或其他集合)? - Ben
1
@Ben 是的。 "另一个" 集被称为测试集。这对于无偏估计是必要的。如果你能够做到,那么总是很好的(或者至少不会有害)。你可以查看我的回答获取更多细节。 - hafiz031
@Guido Mocha 对于验证集来说,它必须反映出真实世界的数据,即来自模型将被使用的同一实际领域的数据。因此,如果您确信验证集将涵盖它,那么无论是小批量/批量/随机梯度下降,您都可以放心地进行。同样,验证集不需要非常大。如果您可以确保它几乎涵盖了您感兴趣的所有情况,那么验证集可以更小。在将数据分成训练集和验证集之前对所有数据进行洗牌有助于均匀分布。 - hafiz031
1
感谢您清晰的解释。今天,一位高级数据科学家当面告诉我,如果不设置第三组测试数据,将导致过度拟合,使我的结果无效。根据您在这里的解释,潜在的偏差并非无效,二者有所不同。我非常需要这个理智的检查,并进一步得出结论,如果我承诺在最终看到新的“测试”数据时不再进一步修改超参数,那么我甚至不会有潜在的偏差? - J B

32

这个YouTube视频介绍了什么是验证集、为什么有用以及如何在Keras中实现验证集: 在Keras中创建验证集

使用验证集,您基本上是从训练集中取出一部分样本,或者创建一个全新的数据集,并将此集合中的样本保留不参与训练。

在每个epoch期间,模型将在训练集中的样本上进行训练,但不会对验证集中的样本进行训练。相反,模型只会对验证集中的每个样本进行验证

这样做的目的是让您能够判断您的模型能否进行泛化。也就是说,您的模型在训练时未曾接触的数据上表现如何。

拥有一个验证集还可以很好地说明您的模型是否过度拟合。这可以通过比较您训练样本的accloss与验证样本的val_accval_loss来解释。例如,如果您的acc很高,但您的val_acc远远落后,则说明您的模型正在过度拟合。


当我们想在Keras中使用train_on_batch()处理大型数据集时,有什么相同的验证解决方法? - afruzan

14

我认为对于训练集、验证集和测试集的总体讨论将有所帮助:

  • 训练集:模型训练时使用的数据集。这是唯一在反向传播期间更新权重的数据集。
  • 验证集(开发集):我们希望模型表现良好的数据集。在训练过程中,我们调整超参数以使模型在开发集上表现良好(但不要将开发集用于训练,它仅用于观察性能,从而决定如何更改超参数,并在更改超参数后继续在训练集上进行训练)。开发集仅用于调整超参数,使模型适合在未知数据上表现良好(这里考虑开发集作为未知数据集的代表,因为它不直接用于训练,此外,超参数就像调整旋钮来改变训练方式),开发集上不进行反向传播,因此不能从中直接学习。
  • 测试集:我们仅用它作为无偏估计,与开发集类似,测试集上不进行训练。与验证集(开发集)唯一的区别是我们甚至不对超参数进行调整,只是查看我们的模型学习到了多少泛化知识。虽然像测试集一样,开发集也不直接用于训练,但是我们反复调整超参数以针对开发集时,模型间接地从开发集中学习模式,开发集也就不再对模型未知。因此,我们需要另一个全新的开发集副本,其甚至不用于超参数调整,并将这个全新的开发集副本称为测试集。根据测试集的定义,它应该对模型是“未知”的。但如果我们无法管理这样一个全新且未见过的测试集,有时我们会把开发集称为测试集。
  • 总结:

    • 训练集:用于训练。
    • 验证集/开发集:用于调整超参数。
    • 测试集:用于无偏估计。

    再次提及一些实际问题:

    • 训练数据可以从任何地方收集。如果你收集的所有数据不都来自将要使用模型的相同领域,那也没关系。例如,如果真实领域是用智能手机相机拍摄的照片,则不必仅使用智能手机照片来制作数据集。可以包括来自互联网、高端或低端相机或其他任何来源的数据。
    • 对于开发集和测试集,必须反映模型将实际使用的真实领域数据,并包含所有可能的情况以进行更好的估计。
    • 开发集和测试集不需要太大。只需确保它几乎涵盖了可能在真实数据中出现的所有情况或情形。在确保这一点后,尽可能提供更多的数据来构建训练集。

    最佳答案..我曾经认为超参数和参数是一样的..你的回答让我去谷歌了解它.. 对于像我这样的人,这就是你的答案 https://datascience.stackexchange.com/questions/14187/what-is-the-difference-between-model-hyperparameters-and-model-parameters - Lakshay Dulani
    这个超参数调整是自动完成的还是需要手动完成?权重会通过反向传播自动更新,我想知道超参数调整是否由另一个算法完成。 - VansFannel
    1
    @VansFannel,超参数是我们用来控制学习过程的变量。如果自动完成,则无法控制训练过程。如果您不想调整它们,可以始终为它们选择默认值。在大多数情况下,这是可以的,但有时特别是对于新案例,如果您没有先前处理该数据的经验,建议手动调整它们。 - hafiz031
    @hafiz031 那么,我必须手动完成它。检查验证损失和准确性,并尝试其他参数,直到我获得更好的结果,对吗? - VansFannel
    1
    @VansFannel 是的,如果您不知道选择哪个值或者不确定模型的行为方式,那么建议使用默认值。如果默认值满足您的需求,那么就可以了。否则逐渐更改它们并观察其行为。不要一次更改多个超参数,否则您将无法知道谁实际上对某个变化负责。所以一个一个地更改它们。您可以使用学习率调度程序逐渐降低学习率。您还可以尝试在超参数上进行网格搜索。 - hafiz031
    1
    @VansFannel 在这种情况下,网格搜索可以帮助您。它将从您那里获取超参数的可能输入,并尝试它们所有。最后,它会告诉您在该特定数据上训练该特定模型的最有前途的配置。它在Scikit-Learn中可用。请参阅此处以了解更多详细信息:https://scikit-learn.org/stable/modules/generated/sklearn.model_selection.GridSearchCV.html - hafiz031

    5

    基本上,在验证集中,模型会尝试进行预测,但它不会更新权重(这意味着它不会从中学习),因此您可以清楚地了解模型在训练数据中如何找到模式并将其应用于新数据的能力。


    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接