验证数据(Validation Data)
引言
在优化章节中,我们使用超参数调优来选择能够带来更好结果的超参数,但还有一个问题需要澄清:我们不应该使用测试数据集来检查不同的超参数。如果这样做,我们实际上是在将模型手动优化到测试数据集上,从而使模型偏向于对这些数据过拟合,而测试数据集本应仅用于最终检查模型是否训练和泛化得当。换句话说,如果我们调整网络的参数以适配测试数据,那么本质上就是在测试数据上优化网络,这是一种过拟合测试数据的方式。
因此,使用测试数据集进行超参数调优是一个错误。测试数据集应仅作为未见过的数据,不应该以任何方式影响模型(超参数调优正是这样的一种影响),测试数据集的唯一用途是评估性能。
超参数调优可以通过另一个被称为验证数据集的数据集来完成。测试数据集需要包含真实的样本外数据,但对于验证数据集,我们在选择数据时有更多的自由。如果我们有大量的训练数据,并且可以分出一部分用于验证,那么我们可以将其视为样本外数据,类似于测试数据集。现在,我们可以使用这个新的验证数据集来寻找最佳参数,并在最后使用测试数据集来测试模型,看是否真的调整了模型,还是只是让模型对验证数据过拟合。
在某些情况下,我们可能会面临数据不足的问题,无法从训练数据中再创建一个新的数据集。在这些情况下,我们有两个选择:
第一个选择是临时将训练数据分成一个较小的训练数据集和验证数据集,用于超参数调优。之后,使用最终确定的超参数集在所有训练数据上训练模型。由于我们是根据从训练数据中分出的一部分验证数据来调整模型的,所以允许这样做。需要记住的是,我们仍然保留一个测试数据集,用于在训练后检查模型的性能。
第二种选择是在数据不足时使用一种称为交叉验证 的过程。交叉验证主要用于训练数据集很小,无法分出数据用于验证的情况。其工作原理是将训练数据集分成若干部分,例如5份。然后,我们在前4份数据上训练模型,在最后一份数据上验证。到目前为止,这与前面描述的情况类似------我们也只是使用了训练数据集,并且可以在未用于训练的数据上验证。然而,交叉验证的不同之处在于我们随后会交换样本。例如,如果我们有5份数据,可以称为A、B、C、D和E。我们可能首先在A、B、C和D上训练,在E上验证;接着在A、B、C和E上训练,在D上验证。我们会一直这样进行,直到每一组样本都被用作验证集。通过这种方式,我们不会丢失任何训练数据。我们使用未在每次迭代中用于训练的数据进行验证,并且相比仅仅临时划分训练数据集,可以在更多数据上进行验证。这种验证方法通常被称为k折交叉验证,其中k表示划分的部分数,在此例中为5。以下是交叉验证的两个步骤示例:
代码可视化:https://nnfs.io/lho
在使用验证数据集和交叉验证时,通常会针对不同的超参数设置进行循环,在代码中多次运行训练,每次运行应用不同的设置,然后审查结果以选择最佳的超参数集。通常,我们不应该对所有可能的设置组合进行全面循环检查,除非训练速度非常快。更好的方法是先尝试一些我们认为可能效果不错的设置,从这些设置中选择最优的组合,再对这些设置进行微调,生成下一组设置列表,然后在新的一组设置上训练模型。我们可以根据需要重复这一过程多次。
本章的章节代码、更多资源和勘误表:https://nnfs.io/ch12