【第十二章】改进神经网络学习方式-过拟合与正则化

本文围绕神经网络过拟合问题展开,通过实验展示了过拟合现象,如网络在训练数据上表现良好但在测试数据上准确率停滞。介绍了检测过拟合的早期停止策略,以及增加训练数据量和正则化等减少过拟合的方法,着重阐述了L2正则化技术及其作用原理和效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

诺贝尔奖获得者、物理学家恩里科·费米曾被问及对一位同事提出的数学模型作为重要未解物理问题的解决方案的看法。该模型与实验结果非常吻合,但费米持怀疑态度。他询问该模型中有多少自由参数可供设置。答案是“四个”。费米回答道:“我记得我的朋友约翰尼·冯·诺伊曼曾经说过,用四个参数我可以拟合一只大象,用五个我可以让它摇摆象鼻。”

当然,重点是,具有大量自由参数的模型可以描述各种各样的现象。即使这样的模型与现有数据非常吻合,也不代表它是一个好模型。这可能只意味着模型中有足够的自由度,可以描述几乎任何给定大小的数据集,而不捕捉到底层现象的任何真正见解。当这种情况发生时,模型将在现有数据上表现良好,但将无法推广到新情况。一个模型的真正测试是其在以前未曝光的情况下进行预测的能力。

费米和冯·诺伊曼对具有四个参数的模型持怀疑态度。我们用于分类MNIST数字的30个隐藏神经元网络几乎有24,000个参数!这是相当多的参数。我们的100个隐藏神经元网络有近80,000个参数,而最先进的深度神经网络有时包含数百万甚至数十亿个参数。我们应该相信这些结果吗?

让我们通过构建一个情境,使我们的网络在推广到新情况时表现不佳,来清晰地阐明这个问题。我们将使用我们的30个隐藏神经元网络,其具有23,860个参数。但我们不会使用所有50,000个MNIST训练图像来训练网络。相反,我们只会使用前1,000个训练图像。使用这个受限制的数据集将使泛化问题更加明显。我们将以与之前类似的方式进行训练,使用交叉熵损失函数,学习率为η=0.5,迷你批次大小为10。然而,我们将进行400个时期的训练,比之前的数量稍多一些,因为我们没有使用太多的训练示例。让我们使用network2来观察损失函数的变化方式:

>>> import mnist_loader 
>>> training_data, validation_data, test_data = \
... mnist_loader.load_data_wrapper()
>>> import network2 
>>> net = network2.Network([784, 30, 10], cost=network2.CrossEntropyCost) 
>>> net.large_weight_initializer()
>>> net.SGD(training_data[:1000], 400, 10, 0.5, evaluation_data=test_data,
... monitor_evaluation_accuracy=True, monitor_training_cost=True)

利用这些结果,我们可以绘制网络学习过程中成本变化的方式。
在这里插入图片描述
这看起来令人鼓舞,显示了成本的平滑下降,正如我们所预期的那样。请注意,我只显示了训练时期200到399。这让我们可以清晰地观察到学习的后期阶段,正如我们将看到的,这正是有趣的地方。

现在让我们看一下随着时间推移测试数据的分类准确率如何变化:
在这里插入图片描述
再次,我进行了相当大幅度的放大。在前200个时期(未显示)中,准确率上升到了接近82%。然后学习逐渐减缓。最后,大约在第280个时期,分类准确率几乎停止提高。后来的时期仅仅是在第280个时期的准确率值附近出现了小的随机波动。与之前的图形形成鲜明对比,其中与训练数据相关的成本继续平稳下降。如果我们只看这个成本,似乎我们的模型仍在变得“更好”。但测试准确率结果显示,这种改善是一种幻觉。就像费米不喜欢的模型一样,我们的网络在第280个时期之后学到的内容不再推广到测试数据。因此,这是无用的学习。我们说网络在第280个时期之后过度拟合或过度训练。

你可能会想知道这里的问题是否在于我看的是训练数据上的成本,而不是测试数据上的分类准确率。换句话说,也许问题在于我们在进行苹果和橙子的比较。如果我们将训练数据上的成本与测试数据上的成本进行比较,从而比较类似的指标,会发生什么情况?或者我们可以比较训练数据和测试数据上的分类准确率?事实上,无论我们如何进行比较,基本上都会出现相同的现象。然而,细节确实会发生变化。例如,让我们看看测试数据上的成本:
在这里插入图片描述
我们可以看到,测试数据上的成本在大约第15个时期开始改善,但在那之后实际上开始恶化,尽管训练数据上的成本仍在继续改善。这是我们的模型过拟合的另一个迹象。然而,这也带来了一个谜题,即我们应该将第15个时期或第280个时期视为过拟合开始主导学习的时刻?从实际的角度来看,我们真正关心的是在测试数据上提高分类准确率,而测试数据上的成本只是分类准确率的代理。因此,将第280个时期视为我们神经网络中过拟合开始主导学习的时刻是最合理的。

过拟合的另一个迹象可能在训练数据上的分类准确率中看到:
在这里插入图片描述
准确率一直上升到100%。也就是说,我们的网络正确分类了所有1,000个训练图像!与此同时,我们的测试准确率仅达到了82.27%。因此,我们的网络确实在学习训练集的特异性,而不仅仅是普遍地识别数字。我们的网络几乎就像是仅仅在记忆训练集,而没有足够深入地理解数字以推广到测试集一样。

过拟合是神经网络中的一个主要问题。在现代网络中,这一点尤为明显,因为它们通常具有非常庞大的权重和偏置数。为了有效地训练,我们需要一种检测过拟合的方法,以便我们不会过度训练。我们还希望有一些减少过拟合影响的技术。

检测过拟合的明显方法是使用上述方法,跟踪网络训练时测试数据上的准确率。如果我们发现测试数据上的准确率不再提高,那么我们应该停止训练。当然,严格来说,这未必一定是过拟合的迹象。可能是测试数据和训练数据上的准确率同时停止提高。尽管如此,采用这种策略将防止过拟合。

事实上,我们将采用这种策略的一种变体。回想一下,当我们加载MNIST数据时,我们加载了三个数据集:

>>> import mnist_loader 
>>> training_data, validation_data, test_data = \
... mnist_loader.load_data_wrapper()

到目前为止,我们一直在使用训练数据和测试数据,而忽略了验证数据。验证数据包含了10,000张数字图像,这些图像与MNIST训练集中的50,000张图像和MNIST测试集中的10,000张图像不同。我们将使用验证数据而不是测试数据来防止过拟合。为此,我们将采用与上述测试数据相同的策略。也就是说,我们将在每个时期结束时计算验证数据上的分类准确率。一旦验证数据上的分类准确率饱和,我们就停止训练。这种策略称为早期停止。当然,在实践中,我们不会立即知道准确率何时饱和。相反,我们会继续训练,直到我们有信心准确率已经饱和。确定何时停止需要一些判断。在我之前的图表中,我确定了第280个时期是准确率饱和的时刻。这可能过于悲观了。神经网络有时在训练过程中会暂时停滞,然后继续改善。我不会感到惊讶,即使在第400个时期之后仍然可能发生更多的学习,尽管进一步改善的幅度可能很小。因此,可以采用更积极或更保守的早期停止策略。

为什么要使用验证数据来防止过拟合,而不是使用测试数据?实际上,这是更一般策略的一部分,即使用验证数据来评估不同的超参数试验选择,如训练的时期数、学习率、最佳网络架构等。我们使用这些评估来找到并设置好的超参数值。实际上,尽管直到现在我还没有提到过,但部分超参数选择是如何在本书前面确定的。(后面会更详细解释这一点。)

当然,这并不能解答为什么我们使用验证数据来防止过拟合,而不是使用测试数据的问题。相反,它将其替换为一个更一般的问题,即为什么我们使用验证数据而不是测试数据来设置好的超参数?为了理解为什么,考虑到在设置超参数时,我们可能会尝试许多不同的超参数选择。如果我们基于测试数据的评估来设置超参数,可能会导致我们过度拟合超参数到测试数据上。也就是说,我们可能会找到适应测试数据特定特性的超参数,但网络的性能可能不会推广到其他数据集上。我们通过使用验证数据来确定超参数来防范这种情况。然后,一旦我们得到了想要的超参数,我们会使用测试数据进行最终的准确度评估。这使我们有信心,我们在测试数据上的结果是神经网络泛化能力的真实衡量标准。换句话说,你可以将验证数据看作是一种帮助我们学习好超参数的训练数据。这种寻找好超参数的方法有时被称为留出法,因为验证数据被保持或“留出”于训练数据之外。

实际上,在评估测试数据性能后,我们可能会改变主意,想尝试另一种方法——也许是不同的网络架构——这将涉及找到新的超参数集。如果我们这样做,难道我们不会过度拟合到测试数据上吗?我们是否需要一个潜在无限的数据集循环,以便我们能够确信我们的结果将会推广?全面解决这个问题是一个深奥而困难的问题。但就我们的实际目的而言,我们不会过多担心这个问题。相反,我们将继续前进,使用基本的留出法,根据前面描述的训练数据、验证数据和测试数据。

到目前为止,我们一直在研究当我们只使用1,000个训练图像时的过拟合情况。当我们使用全部50,000个图像的完整训练集时会发生什么?我们将保持所有其他参数不变(30个隐藏神经元,学习率0.5,迷你批次大小为10),但是使用所有50,000个图像进行30个时期的训练。下面是显示训练数据和测试数据分类准确率结果的图表。请注意,我在这里使用了测试数据,而不是验证数据,以便与前面的图表结果进行直接比较。

在这里插入图片描述
正如你所看到的,测试数据和训练数据的准确率仍然比我们使用1,000个训练示例时要接近得多。特别是,训练数据上的最佳分类准确率为97.86%,仅比测试数据上的95.33%高出2.53%。这与我们之前的17.73%的差距相比要小得多!过拟合仍在进行,但已经大大减少。我们的网络从训练数据到测试数据的泛化能力大大提高。通常,减少过拟合的最佳方法之一是增加训练数据的大小。即使是非常大的网络,如果有足够的训练数据,也很难出现过拟合。不幸的是,训练数据可能成本高或难以获取,因此这并不总是一个实际的选择。

正则化(Regularization)

增加训练数据量是减少过拟合的一种方法。我们还能采取其他方法来减少过拟合的程度吗?一种可能的方法是减少网络的大小。然而,大型网络可能比小型网络更强大,因此这只是我们不情愿采纳的一个选择。

幸运的是,还有其他技术可以在网络大小和训练数据固定的情况下减少过拟合。这些技术被称为正则化技术。在本节中,我将描述其中最常用的正则化技术之一,有时称为权重衰减或L2正则化的技术。L2正则化的思想是在成本函数中添加一个额外项,称为正则化项。下面是经过正则化的交叉熵:
C = − 1 n ∑ x j [ y j ln ⁡ a j L + ( 1 − y j ) ln ⁡ ( 1 − a j L ) ] + λ 2 n ∑ w w 2 . (85) C = -\frac{1}{n} \sum_{xj} \left[ y_j \ln a^L_j+(1-y_j) \ln (1-a^L_j)\right] + \frac{\lambda}{2n} \sum_w w^2. \tag{85} C=n1xj[yjlnajL+(1yj)ln(1ajL)]+2nλww2.(85)

第一个项只是交叉熵的常规表达式。但我们添加了第二项,即网络中所有权重的平方和。这由一个因子λ/2n进行缩放,其中λ>0被称为正则化参数,n通常是我们的训练集的大小。我将稍后讨论如何选择λ。值得注意的是,正则化项不包括偏置。我也会在下面回来讨论这一点。

当然,也可以对其他成本函数进行正则化,比如二次成本。可以用类似的方式进行:
C = 1 2 n ∑ x ∥ y − a

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值