Datawhale AI x 魔搭 夏令营第五期 深度学习(入门)方向 task03笔记

模型偏差

模型偏差可能会影响模型训练。举个例子,假设模型过于简单,一个有未知参数的函数代θ1 得到一个函数 fθfθ1(x),同理可得到另一个函数 fθfθ2(x),把所有的函数集合起来得到一个函数的集合。但是该函数的集合太小了,没有包含任何一个函数,可以让损失变低的函数不在模型可以描述的范围内。在这种情况下,就算找出了一个 θ∗,虽然它是这些蓝色的函数里面最好的一个,但损失还是不够低。这种情况就是想要在大海里面捞针(一个损失低的函数),结果针根本就不在海里。

这个时候重新设计一个模型,给模型更大的灵活性。以第一章的预测未来观看人数为例,可以增加输入的特征,本来输入的特征只有前一天的信息,假设要预测接下来的观看人数,用前一天的信息不够多,用 56 天前的信息,模型的灵活性就比较大了。也可以用深度学习,增加更多的灵活性。所以如果模型的灵活性不够大,可以增加更多特征,可以设一个更大的模型,可以用深度学习来增加模型的灵活性,这是第一个可以的解法。但是并不是训练的时候,损失大就代表一定是模型偏差,可能会遇到另外一个问题:优化做得不好。

优化问题

一般只会用到梯度下降进行优化,这种优化的方法很多的问题。比如可能会卡在局部最小值的地方,无法找到一个真的可以让损失很低的参数,如图 2.3(a) 所示。如图 2.3(b) 所示蓝色部分是模型可以表示的函数所形成的集合,可以把 θ 代入不同的数值,形成不同的函数,把所有的函数通通集合在一起,得到这个蓝色的集合。这个蓝色的集合里面,确实包含了一些函数,这些函数它的损失是低的。但问题是梯度下降这一个算法无法找出损失低的函数,梯度下降是解一个优化的问题,找到 θ∗ 就结束了。但 θ∗ 的损失不够低。这个模型里面存在着某一个函数的损失是够低的,梯度下降没有给这一个函数。这就像是想大海捞针,针确实在海里,但是无法把针捞起来。训练数据的损失不够低的时候,到底是模型偏差,还是优化的问题呢。找不到一个损失低的函数,到底是因为模型的灵活性不够,海里面没有针。还是模型的灵活性已经够了,只是优化梯度下降不给力,它没办法把针捞出来 到底是哪一个。到底模型已经够大了,还是它不够大,怎么判断这件事呢?

一个建议判断的方法,通过比较不同的模型来判断模型现在到底够不够大。举个例子,这一个实验是从残差网络的论文“Deep Residual Learning for Image Recognition”[1] 里面节录出来的。这篇论文在测试集上测试两个网络,一个网络有 20 层,一个网络有 56 层。图 2.4(a)横轴指的是训练的过程,就是参数更新的过程,随着参数的更新,损失会越来越低,但是结果20 层的损失比较低,56 层的损失还比较高。残差网络是比较早期的论文,2015 年的论文。很多人看到这张图认为这个代表过拟合,深度学习不奏效,56 层太深了不奏效,根本就不需要这么深。但 这个不是过拟合,并不是所有的结果不好,都叫做过拟合。在训练集上,20 层的网络损失其实是比较低的,56 层的网络损失是比较高的,如图 2.4(b) 所示,这代表 56 层的网络的优化没有做好,它的优化不给力。

过拟合

造成原因

为什么会有过拟合这样的情况呢?举一个极端的例子,这是训练集。假设根据这些训练集,某一个很废的机器学习的方法找出了一个一无是处的函数。这个一无是处的函数,只要输入 x 有出现在训练集里面,就把它对应的 y 当做输出。如果 x 没有出现在训练集里面,就输出一个随机的值。这个函数啥事也没有干,其是一个一无是处的函数,但它在训练数据上的损失是 0。把训练数据通通丢进这个函数里面,它的输出跟训练集的标签是一模一样的,所以在训练数据上面,这个函数的损失可是 0 呢,可是在测试数据上面,它的损失会变得很大,因为它其实什么都没有预测,这是一个比较极端的例子,在一般的情况下,也有可能发生类似的事情。如图 2.6 所示,举例来说,假设输入的特征为 x,输出为 y,x 和 y 都是一维的。x 和 y之间的关系是 2 次的曲线,曲线用虚线来表示,因为通常没有办法,直接观察到这条曲线。我们真正可以观察到的是训练集,训练集可以想像成从这条曲线上面,随机采样出来的几个点。模型的能力非常的强,其灵活性很大,只给它这 3 个点。在这 3 个点上面,要让损失低,所以模型的这个曲线会通过这 3 个点,但是其它没有训练集做为限制的地方,因为它的灵活性很大,它灵活性很大,所以模型可以变成各式各样的函数,没有给它数据做为训练,可以产生各式各样奇怪的结果。

如果再丢进测试数据,测试数据和训练数据,当然不会一模一样,它们可能是从同一个分布采样出来的,测试数据是橙色的点,训练数据是蓝色的点。用蓝色的点,找出一个函数以后,测试在橘色的点上,不一定会好。如果模型它的自由度很大的话,它可以产生非常奇怪的曲线,导致训练集上的结果好,但是测试集上的损失很大。

解决方法

两个可能的方向:第一个方向是往往是最有效的方向,即增加训练集。因此如果训练集,蓝色的点变多了,虽然模型它的灵活性可能很大,但是因为点非常多,它就可以限制住,它看起来的形状还是会很像,产生这些数据背后的 2 次曲线,如图 2.7 所示。可以做数据增强(data   augmentation,),这个方法并不算是使用了额外的数据。另外一个解法是给模型一些限制,让模型不要有过大的灵活性。假设 x 跟 y 背后的关系其实就是一条 2 次曲线,只是该 2 次曲线里面的参数是未知的。如图 2.8 所示,要用多限制的模型才会好取决于对这个问题的理解。因为这种模型是自己设计的,设计出不同的模型,结果不同。假设模型是 2 次曲线,在选择函数的时候有很大的限制,因为 2 次曲线要就是这样子,来来去去就是几个形状而已。所以当训练集有限的时候,来来去去只能够选几个函数。所以虽然说只给了 3 个点,但是因为能选择的函数有限,可能就会正好选到跟真正的分布比较接近的函数,在测试集上得到比较好的结果。

交叉验证

交叉验证是一种统计分析方法,常用于评估机器学习模型的泛化能力。它通过将数据集分割成多个小子集,将其中的一部分作为训练集来训练模型,而另一部分则作为测试集来评估模型的性能。最常见的交叉验证技术包括k折交叉验证,其中数据被分为k个子集,模型分别以k-1个子集作为训练数据,剩下的一个子集作为测试数据,这个过程重复k次,每次选择不同的测试数据集,最终的模型性能是这k次评估结果的平均值。这种方法可以有效地利用有限的数据资源,并有助于减少过拟合的风险。比较合理选择模型的方法是把训练的数据分成两半,一部分称为训练集(training set),一部分是验证集(validation set)。比如 90% 的数据作为训练集,有 10% 的数据作为验证集。在训练集上训练出来的模型会使用验证集来衡量它们的分数,根据验证集上面的分数去挑选结果,再把这个结果上传到 Kaggle 上面得到的公开分数。在挑分数的时候,是用验证集来挑模型,所以公开测试集分数就可以反映私人测试集的分数。但假设这个循环做太多次,根据公开测试集上的结果调整模型太多次,就又有可能在公开测试集上面过拟合,在私人测试集上面得到差的结果。

其实最好的做法,就是用验证损失,最小的直接挑就好了,不要管公开测试集的结果。在实现上,不太可能这么做,因为公开数据集的结果对模型的选择,可能还是会有些影响的。理想上就用验证集挑就好,有过比较好的基线(baseline)算法以后,就不要再去动它了,就可以避免在测试集上面过拟合。但是这边会有一个问题,如果随机分验证集,可能会分得不好,分到很奇怪的验证集,会导致结果很差,如果有这个担心的话,可以用 k 折交叉验证(k-foldcross validation),如图 2.11 所示。k 折交叉验证就是先把训练集切成 k 等份。在这个例子,训练集被切成 3 等份,切完以后,拿其中一份当作验证集,另外两份当训练集,这件事情要重复 3 次。即第一份第 2 份当训练,第 3 份当验证;第一份第 3 份当训练,第 2 份当验证;第一份当验证,第 2 份第 3 份当训练。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值