88

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

而且,它是否会影响模型的训练方式(例如,通常使用验证集来选择模型中的超参数,但我认为这不会发生在这里)?

我说的是可以像这样传递的验证集:

# 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_losskeras.models.training.fitkeras.models.training._fit_loopcallbacks.validation_datakeras.models.training._test_loopself.test_function

看到这一切后,我觉得传递给的验证集model.fit在训练期间并没有用来验证任何东西,它唯一的用途是获得关于训练模型在每个 epoch 对于一个完全独立的集合的表现的反馈。因此,使用相同的验证和测试集是没问题的,对吧?

除了从回调中读取之外,任何人都可以确认 model.fit 中的验证集是否还有其他目标?

4

4 回答 4

87

如果你想建立一个实体模型,你必须遵循将数据分成三组的特定协议:一组用于训练,一组用于验证,一组用于最终评估,即测试集

这个想法是你在训练数据上进行训练,并使用你从验证集中获得的指标结果(准确性、损失等)来调整你的模型。

您的模型没有“看到”您的验证集,也没有以任何方式对其进行培训,但是您作为超参数的架构师和大师根据这些数据调整模型。因此,它间接影响您的模型,因为它直接影响您的设计决策。你推动你的模型与验证数据一起工作,这可能会带来倾斜。

正是因为这个原因,你只评估你的模型和你自己都没有使用过的数据的模型的最终分数——这就是第三组数据,你的测试集。

只有这个过程才能确保您对模型的质量和概括在完全看不见的数据上学到的知识的能力有一个不受影响的看法。

于 2017-09-19T19:33:50.637 回答
30

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

使用验证集,您实际上是从训练集中取出一小部分样本,或者一起创建一个全新的集,并从训练中保留该集中的样本。

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

这样做的目的是让您能够判断模型的泛化程度。意思是,您的模型对训练时看不到的数据的预测能力如何。

拥有一个验证集还可以很好地了解您的模型是否过度拟合。这可以通过比较训练样本和验证样本的acc和来解释。例如,如果你的值很高,但远远落后,这很好地表明你的模型过度拟合。lossval_accval_lossaccval_acc

于 2017-09-20T00:12:24.293 回答
12

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

  • 训练集:用于训练模型的数据集。这是在反向传播期间更新权重的唯一数据集。
  • 验证集(开发集):我们希望模型在其上表现良好的数据集。在训练过程中,我们调整超参数,使模型在 dev-set 上表现良好(但不要使用 dev-set 进行训练,它仅用于查看性能,以便我们决定如何更改超-parameters 并且在更改超参数后,我们继续在训练集上进行训练)。Dev-set 仅用于调整超参数以使模型有资格在未知数据上正常工作(这里 dev-set 被认为是未知数据集的代表,因为它不直接用于训练并且另外表示超-参数就像调整旋钮以改变训练方式)并且在开发集上不会发生反向传播,因此不会直接从中学习。
  • 测试集:我们只是将它用于无偏估计。与开发集一样,在测试集上不会进行任何训练。与验证集(开发集)的唯一区别是我们甚至不在这里调整超参数,而只是看看我们的模型如何学会泛化。尽管与测试集一样,开发集并不直接用于训练,但随着我们反复调整针对开发集的超参数,我们的模型间接地从开发集学习模式,并且开发集不再未知到模型。因此我们需要另一个新的开发集副本它甚至不用于超参数调整,我们将这个新的开发集副本称为测试集。根据测试集的定义,模型应该是“未知的”。但是如果我们不能像这样管理一个新的和看不见的测试集,那么有时我们会将开发集称为测试集。

总结:

  • Train-Set:用于训练。
  • Validation-Set / Dev-Set:用于调整超参数。
  • 测试集:用于无偏估计。

这里还有一些实际问题:

  • 对于培训,您可以从任何地方收集数据。如果您收集的所有数据不是来自将使用模型的同一域,那也没关系。例如,如果真实领域是智能手机相机拍摄的照片,则无需仅使用智能手机照片进行数据集。您可能包含来自互联网、高端或低端相机或任何地方的数据。
  • 对于开发集和测试集,有必要反映实际使用模型的真实域数据。它还应该包含所有可能的情况,以便更好地估计。
  • 开发集和测试集不需要那么大。只要确保它几乎涵盖了真实数据中可能出现的所有情况或情况。在确保它尝试提供尽可能多的数据来构建训练集之后。
于 2020-03-16T03:38:21.547 回答
5

所以基本上在验证集中,模型会尝试预测但它不会更新它的权重(这意味着它不会从中学习)所以你会清楚地知道你的模型在多大程度上可以找到模型中的模式训练数据并将其应用于新数据。

于 2021-04-15T16:38:02.817 回答