模型在训练数据上拟合的比在潜在分布中更接近的现象被称为过拟合(overfitting),用于对抗过拟合的技术称为正则化。在实验中调整模型架构或超参数时会发现:如果有足够多的神经元、层数和训练迭代周期,模型最终可以在训练集上达到完美的精度,此时测试集的准确性却下降了。
训练误差和泛化误差
为了进一步讨论这一现象,我们需要了解训练误差和泛化误差。训练误差(training error)是指,模型在训练数据集上计算得到的误差。泛化误差(generalization error)是指,模型应用在同样从原始样本的分布中抽取的无限多数据样本时,模型误差的期望。
问题是,我们永远不能准确地计算出泛化误差。这是因为无限多的数据样本是一个虚构的对象。在实际中,我们只能通过将模型应用于一个独立的测试集来估计泛化误差,该测试集由随机选取的、未曾在训练集中出现的数据样本构成。
下面的三个思维实验将有助于更好地说明这种情况。假设一个大学生正在努力准备期末考试。一个勤奋的学生会努力做好练习,并利用往年的考试题目来测试自己的能力。尽管如此,在过去的考试题目上取得好成绩并不能保证他会在真正考试时发挥出色。例如,学生可能试图通过死记硬背考题的答案来做准备。他甚至可以完全记住过去考试的答案。另一名学生可能会通过试图理解给出某些答案的原因来做准备。在大多数情况下,后者会考得更好。
统计学习理论
由于泛化是机器学习中的基本问题,许多数学家和理论家毕生致力于研究描述这一现象的形式理论。在同名定理中,格里文科和坎特利推导出了训练误差收敛到泛化误差的速率。在一系列开创性的论文中,Vapnik和Chervonenkis63将这一理论扩展到更一般种类的函数。这项工作为统计学习理论奠定了基础。
在我们目前已探讨、并将在之后继续探讨的监督学习情景中,我们假设训练数据和测试数据都是从相同的分布中独立提取的。这通常被称为独立同分布假设,这意味着对数据进行采样的过程没有进行“记忆”。换句话说,抽取的第2个样本和第3个样本的相关性,并不比抽取的第2个样本和第200万个样本的相关性更强。
当我们训练模型时,我们试图找到一个能够尽可能拟合训练数据的函数。但是如果它执行地“太好了”,而不能对看不见的数据做到很好泛化,就会导致过拟合。这种情况正是我们想要避免或控制的。深度学习中有许多启发式的技术旨在防止过拟合。
模型复杂性
当我们有简单的模型和大量的数据时,我们期望泛化误差与训练误差相近。当我们有更复杂的模型和更少的样本时,我们预计训练误差会下降,但泛化误差会增大。模型复杂性由什么构成是一个复杂的问题。一个模型是否能很好地泛化取决于很多因素。例如,具有更多参数的模型可能被认为更复杂,参数有更大取值范围的模型可能更为复杂。通常对于神经网络,我们认为需要更多训练迭代的模型比较复杂,而需要早停的模型(即较少训练迭代周期)就不那么复杂。
我们很难比较本质上不同大类的模型之间(例如,决策树与神经网络)的复杂性。就目前而言,一条简单的经验法则相当有用:统计学家认为,能够轻松解释任意事实的模型是复杂的,而表达能力有限但仍能很好地解释数据的模型可能更有现实用途。
在哲学上,这与波普尔的科学理论的可证伪性标准密切相关:如果一个理论能拟合数据,且有具体的测试可以用来证明它是错误的,那么它就是好的。这一点很重要,因为所有的统计估计都是事后归纳。也就是说,我们在观察事实之后进行估计,因此容易受到相关谬误的影响。目前,我们将把哲学放在一边,坚持更切实的问题。
模型选择
在机器学习中,我们通常在评估几个候选模型后选择最终的模型。这个过程叫做模型选择。有时,需要进行比较的模型在本质上是完全不同的(比如,决策树与线性模型)。又有时,我们需要比较不同的超参数设置下的同一类模型。
例如,训练多层感知机模型时,我们可能希望比较具有不同数量的隐藏层、不同数量的隐藏单元以及不同的激活函数组合的模型。为了确定候选模型中的最佳模型,我们通常会使用验证集。
验证集
原则上,在我们确定所有的超参数之前,我们不希望用到测试集。如果我们在模型选择过程中使用测试数据,可能会有过拟合测试数据的风险,那就麻烦大了。如果我们过拟合了训练数据,还可以在测试数据上的评估来判断过拟合。但是如果我们过拟合了测试数据,我们又该怎么知道呢?
因此,我们决不能依靠测试数据进行模型选择。然而,我们也不能仅仅依靠训练数据来选择模型,因为我们无法估计训练数据的泛化误差。
在实际应用中,情况变得更加复杂。虽然理想情况下我们只会使用测试数据一次,以评估最好的模型或比较一些模型效果,但现实是测试数据很少在使用一次后被丢弃。我们很少能有充足的数据来对每一轮实验采用全新测试集。
解决此问题的常见做法是将我们的数据分成三份,除了训练和测试数据集之外,还增加一个验证数据集,也叫验证集。但现实是验证数据和测试数据之间的边界模糊得令人担忧。除非另有明确说明,否则在实验中,我们实际上是在使用应该被正确地称为训练数据和验证数据的数据集,并没有真正的测试数据集。
K折交叉验证
当训练数据稀缺时,我们甚至可能无法提供足够的数据来构成一个合适的验证集。这个问题的一个流行的解决方案是采用K折交叉验证。这里,原始训练数据被分成K个不重叠的子集。然后执行K次模型训练和验证,每次在K−1个子集上进行训练,并在剩余的一个子集(在该轮中没有用于训练的子集)上进行验证。最后,通过对K次实验的结果取平均来估计训练和验证误差。