如何正确使用机器学习中的训练集、验证集和测试集?

转载地址:https://www.jianshu.com/p/45aa52002fc8

1、测试集

只有在同样的测试集上,两个(或以上)模型的对比才有效。

这就如同参加高考,两个人考同样一张卷子,分数才能对比。

甲拿A地区的卷子,考了600分,乙拿B地区的卷子,考了580分。你能不能说,甲比乙成绩高?

不行吧。

为了让大家更易于比较自己的模型效果,许多不同领域的数据集,都已开放了。而且开放的时候,都会给你指明,哪些数据用于训练,哪些用于测试。

以 Yelp 数据为例。

在 AWS 上存储的 fast.ai 公开数据集中,训练集和测试集都已为你准备好。

你不需要自己进行划分。

大家达成共识,做研究、写论文,都用这个测试集来比拼,就可以。

所以,如果你的研究,是靠着比别人的模型效果来说事儿,那就一定先要弄明白对方的测试集是什么。

但是,这个听起来很容易达成的目标,实践中却很容易遇到困难。

因为有的人写论文,喜欢把数据和代码藏着掖着,生怕别人用了去。

他们一般只提一下,是在某个公开数据集上切了一部分出来,作为测试集。

测试数据集不发布,切分方法(包括工具)和随机种子选取办法也不公开。

这是非常不靠谱的行为,纯属自娱自乐。

作为严肃的审稿人,根本就不应该允许这样的研究发表。

因为机器学习研究的数据集不开放,便基本上没有可重复性(Reproducibility)。

如果你没有办法精确重复他的模型训练和测试过程,那么他想汇报多高的准确率,就纯凭个人爱好了。

当然,我们不是活在理想世界的。

你在某一个领域,用机器学习做应用研究的时候,面对这种无法重复已发表论文的情境,该怎么办?

直接用他声称的结果与你的实际运行结果比较,你可能是在追逐海市蜃楼。累到气喘吁吁,甚至怀疑自我的程度,也徒劳无功。

忽视它?

也不行。

审稿人那关你过不去。

人家会说,某某研究跟你用的是一样的数据,准确率已经达到98%,你的才96%,有什么发表的意义呢?

看,左右为难不是?

其实解决办法很简单。

不要考虑对方声称达到了多高准确率。把他提供给你的数据全集,自行切分。之后复现对方的模型,重新跑。

模型架构,一般都是要求汇报的,所以这几乎不是问题。

至于这种复现,越是复杂的模型,我越推荐你用 PyTorch 。

之后把你的模型,和复现的对方模型在同样的测试集上做对比,就可以了。

当然,论文里要写上一句:

由于某篇文章未提供代码与具体数据切分说明,带来可重复性问题,我们不得不独立复现了其模型,并在测试集完全一致的情况下,进行了比对。

这里多说一句,一定要保证你自己的研究,是可重复的。

不要怕公布你的代码和数据。它们不是你的独门暗器,而是支撑你研究的凭据

回看我们前面提到的 Yelp 公开数据的例子。

这时候你会发现一个奇怪的问题——为什么它只有训练集和测试集?

我们一直反复提到的验证集哪里去了?

2、验证

验证集,就如同高考的模拟考试。

不同于高考,模拟考只是你调整自己状态的指示器而已。

状态不够满意,你可以继续调整。

当然,参加过高考的同学都有经验——这种调整的结果(从模拟考到高考),有可能更好,也有可能更糟糕。

回到机器学习上,那就是测试集上检验的,是你最终模型的性能。

什么叫“最终模型”?

就是你参加高考时候的状态。包括你当时的知识储备、情绪心态,以及当天的外部环境(温度、湿度、东西是否带齐)等。

最终模型,只有一个

就如同每年的高考,你只能参加一回

考成什么样儿,就是什么样。

而验证集上跑的,实际上却是一个模型集合,集合的大小,你可能数都数不过来。

因为这里存在着超参数(hyper-parameter)设置的问题。不同超参数组合,就对应着不同的潜在模型。

验证集的存在,是为了从这一堆可能的模型中,帮你表现最好的那个。

注意这里的表现,是指在验证集上的表现。

好比说,有个超参数叫做训练轮数(epochs)。

在同样的训练集上,训练3轮和训练10轮,结果可能是不一样的模型。它们的参数并不相同。

那么到底是训练3轮好,还是10轮好?

或者二者都不好,应该训练6轮?

这种决策,就需要在训练后,在验证集上“是骡子是马牵出来溜溜”。

如果发现训练3轮效果更好,那么就应该丢弃掉训练6轮、10轮的潜在模型,只用训练3轮的结果。

这对应着一种机器学习正则化(Regularization)方式——提早停止训练(early stopping)。

其他的超参数选取,你也可以举一反三。总之就是按照验证集的效果,来选超参数,从而决定最终模型。

下一步,自然就是把它交给测试集,去检验。这个我们前面已经详细讲解过了。

至于这个最终选择模型,在新数据集(测试集)上表现如何,没人能打包票。

所以,回到咱们之前的问题。在《如何用 Python 和深度迁移学习做文本分类?》一文中,我故意用验证集上筛选出的最好模型,在验证集上跑出来分数,当成是测试成绩,这显然是不妥当的。

你不能把同样的题做他个三五遍,然后从中找最高分去跟别人比。

即便你的模拟考,用的是别人的高考真题。两张卷子完全一样,也没有说服力。

所以你看,验证集的目的,不是比拼最终模型效果的。

因此,怎么设定验证集,划分多少数据做验证,其实是每个研究者需要独立作出的决策,不应该强行设定为一致。

这就如同我们不会在高考前去检查每个考生,是否做过一样多的模拟试卷,且试卷内容也要一致。

极端点儿说,即便一个考生没参加过模拟考,可高考成绩突出,你也不能不算他的成绩,对吧?

不过,讲到这里,我们就得要把训练集拿进来,一起说说了。

3、训练

如果测试集是高考试卷,验证集是模拟考试卷,那么训练集呢?

大概包括很多东西,例如作业题、练习题。

另外,我们上高三那时候(噫吁嚱,已经上个世纪的事儿了),每周有“统练”,每月有“月考”。也都可以划定在训练集的范畴。

减负这么多年以后,现在的高中生应该没有那么辛苦了吧?真羡慕他们。

这样一对比,你大概能了解这几个集合之间本应有的关系。

学生平时练题,最希望的,就是考试能碰到原题,这样就可以保证不必动脑,却做出正确答案。

所以,出模拟考卷时,老师尽量要保证不要出现学生平时练过的题目,否则无法正确估量学生目前的复习备考状态,噪声过高容易误事儿。

验证集和训练集,应该是不交叠的。这样选择模型的时候,才可以避免被数据交叠的因素干扰。

每个学校的模拟考,却都恨不得能押中高考的题。这样可以保证本校学生在高考中,可以“见多识广”,取得更高分数。

高考出卷子的老师,就必须尽力保证题目是全新的,以筛选出有能力的学生,而不是为高校选拔一批“见过题目,并且记住了标准答案”的学生。

因此,测试集应该既不同于训练集,又不同于验证集。

换句话说,三个数据集合,最好都没有重叠。

学生应该学会举一反三,学会的是知识和规律。

用知识和规律,去处理新的问题。

我们对机器模型的期许,其实也一样。

在学术论文中,你见到的大部分用于机器学习模型对比的公开数据集(例如 fast.ai 公开数据集中的 Yelp, IMDB, ImageNet 等),都符合这一要求。

然而,例外肯定是有的。

例如我在 INFO 5731 课程里面给学生布置的某期末项目备选项,来源于某学术类数据科学竞赛,目标是社交媒体医学名词归一化。

其中就有数据,既出现在了训练集,又出现在了验证集,甚至测试集里也会有。

面对这种问题,你该怎么办?

你怎么判断自己的模型,究竟是强行记住了答案,还是掌握了文本中的规律?

这个问题,作为思考题留给你。

我希望在知识星球中和热爱学习的你,做进一步讨论。

另外的一个问题,是训练集要不要和别人的完全一致

一般来说,如果你要强调自己的模型优于其他人,那么就要保证是在同样的训练集上训练出来。

回顾深度学习的三大要素:

  • 数据(Data)
  • 架构(Architecture)
  • 损失(Loss)

如果你的训练数据,比别人多得多,那么模型自然见多识广。

对于深度学习而言,如果训练数据丰富,就可以显著避免过拟合(Overfitting)的发生。

GPT-2 模型,就是因为具备了海量 Reddit 数据做训练,才能傲视其他语言模型(Language Model),甚至以安全为理由,拒绝开放模型。

但是这时候,你跟别人横向比较,似乎就不大公平了。

你的架构设计,未必更好。假使对方用同样多的数据训练,结果可能不必你差,甚至会更优。

这就如同一个复读了5年的学生甲,充分利用每一分每一秒,做了比应届生乙多5倍的卷子。结果在高考的时候,甲比乙多考了1分(同一张卷子)。

你能说甲比乙更有学习能力,学习效果更好吗?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值