避免30多个小时的无用功……
获得的魔法般的顿悟也就比瞎猜强了一点。 结果出来之后,我花了30多个小时,复盘数据,试图找出哪里出了问题,整个人精疲力竭。预测中肯定那儿除了问题,可能是文件传错了。 然而,这30个小时也不过是白费功夫。我花了九牛二虎之力更正结果,但预测结果值仍然很低。 到底是哪里出问题了?答案是:数据泄露。数据泄露是个很简单的概念,但我就直直地走进了它的陷阱。在模型训练中,我的编程没有任何问题,模型也正确依照测试数据进行了训练,问题出现在了不易发现的地方。 简而言之,当模型遇到不该遇到的情况时,就会发生数据泄漏。在比赛中,我已经在多个会话中训练了模型,也就是说,我将从上一个会话中加载模型权重,训练模型并保存最佳性能的权重。由于计算时间限制,训练在多个会话中进行。 但是,在每个会话中,我都会重新运行整个代码,包括将数据随机分为训练和验证集的代码,因此每次培训的训练集并不相同。为避免这种情况,可以设置一个种子来划分训练/验证组,而这是我(非常)没有提前采取的措施。 尽管每次的训练数据都不同,但模型的权重(它所了解的信息)却被传递了下来。因此,经过足够的培训后,该模型已被暴露给整个数据集。 学习模型本身具有惰性,所以该模型会放弃学习,转而对数据进行记忆,这对没有感情的网络来说非常简单,也就导致这种现象发生过很多次。因此,面对从未见过的数据时,这个模型就无能为力了。 由于该模型已经在之前的训练中见过验证数据,所以才能得到近乎完美的0.9968,让我误以为这就是模型本身的能力。如果回忆一下模型早期的性能,想一想为什么验证分数会高于训练分数,就会明白这其实是一个相当奇怪且罕见的现象。 所以,大家在接下来的每一个实践中都要牢记这重要的一课:如果结果太过完美,让人不敢相信,那十有八九这个结果有问题。(这个方法在鉴别数据泄露中尤其重要。) 这是一种数据泄露,其他类型的泄露包括:
在事情太过完美的时候三思是个好习惯,但也要注意其中微妙的细节。比如说,分数增加的幅度很大,但不一定是很奇怪的现象;而当模型对测试数据进行预测时,其性能又很差劲。 实际上,最好的办法是注意以任何方式分割数据的目的,以便将它们分为训练/验证/测试集,并尽早进行。此外,设置种子是强有力的保障。 从更开放的角度上讲,数据泄漏可能是有益的。如果模型看到了不应该看到的数据,但是看到的数据有助于提升其概括能力,帮助学习,那么数据泄漏是有好处的。
例如,Kaggle的排名系统。该系统由一个公共排行榜和一个私人排行榜组成。在比赛结束之前,用户可以访问所有训练内容和部分测试内容(在该系统中可访问25% (编辑:淮南站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |