雷锋网 AI 研习社按,本文作者 dawnbreaker,首发于知乎,雷锋网 AI 研习社获其授权转载。
我从 2017 年年初开始接触 Kaggle。曾翻阅知乎上很多关于 Kaggle 的回答和文章,然而逐渐发现大部分文章中提到的经验和技巧是针对传统 machine learning 类比赛的,对计算机视觉类的比赛并不适用。此刻已是 2018 年 6 月,我也参加过了多次比赛,或多或少有了一些自己的观点和感想。因此我写这一篇文章希望对现存文章进行一定程度的补充,以供刚刚接触 Kaggle 计算机视觉(CV)类比赛的同学参考。尽管此文会充斥个人观点和猜测,我会尽量提供论据并淡化感情色彩。这是我在知乎的第一篇文章,希望大家能够多多鼓励和批评。
一、我的成绩
第一次 The Nature Conservancy Fisheries Monitoring
排名: 16th of 2,293 ⋅ Top 1% ⋅ 角色:队长。另一个队员叫孙鹏,是同一实验室的同学
第二次 Carvana Image Masking Challenge
排名: 12th of 735 ⋅ Top 2% ⋅ 角色:前期单刷,后来基本上由女朋友完成。
第三次 Cdiscount’s Image Classification Challenge
排名: 15th of 627 ⋅ Top 3% ⋅ 角色:基本是单刷。偶尔和女友以及朋友讨论一下。
第四次 Statoil/C-CORE Iceberg Classifier Challenge
排名: 28th of 3,343 ⋅ Top 1% ⋅ 角色:打酱油。队长是孙鹏。
第五次 Google Landmark Recognition Challenge
排名: 9th of 483 ⋅ Top 2% ⋅ 担任角色:单刷
并列第五次 Google Landmark Retrieval Challenge
排名: 22th of 218 ⋅ Top 11% ⋅ 角色:单刷。基本上只用 landmark recognition 比赛的代码跑了一下,没有进行调参等尝试,完全是投机取巧。
这六次比赛皆为计算机视觉类的任务。我还曾试图参加 TensorFlow Speech Recognition Challenge 这个语音识别类的比赛,最终因为自己过于外行和精力不足知难而退。
以上就是我的全部比赛经历。
二、Kaggle上的两个世界
Kaggle 的比赛任务大致都是根据已知信息,对测试集里的数据进行某种预测。按照主流方法是否涉及到 deep learning 来分,大概有两种比赛:
A. 一种比赛比较适合传统的 machine learning 方法,要想取得好成绩,可能要在 feature engineering 和 ensemble 方面大做文章。但基本用不上 deep learning,因此有没有好的 GPU 无关紧要。这类比赛的例子有房价预测等:
House Prices: Advanced Regression Techniques
Zillow Prize: Zillow’s Home Value Prediction (Zestimate)
Two Sigma Financial Modeling Challenge
Sberbank Russian Housing Market
Instacart Market Basket Analysis
Web Traffic Time Series Forecasting
Mercedes-Benz Greener Manufacturing
B. 另一种比赛现阶段主流的解决方案是各种深度神经网络,主要以计算机视觉类为主,任务包括 image/video classification, object detection, image masking。偶尔也有语音识别类任务。迄今为止我参加过的比赛都是这一种。参加此类比赛对硬件有一定程度的要求。比如说有一个台式机和一块或多块 Titan X/1080ti 会对模型的迭代帮助很大。但用笔记本 GPU 甚至完全不用 GPU 并且排名靠前的人也是有的:
例1:我的同学孙鹏,用笔记本上的 980M。
例2:一个叫 Eric 的 Kaggler,用 5 个无 GPU 的电脑跑 PyTorch,Google Landmark Recognition Challenge 中获得 28th/483 排名。参见 I enjoyed this competition: Feedback from a newbie!
例3:一个 ID 为 ImageRecog 的 Kaggler,声称用笔记本打比赛,在 Google Landmark Retrieval Challenge 中赢得季军。(不确定后期有没上更强大的硬件。)
但总归会痛苦很多。
很多 Kagglers 对这两类比赛之一表现出了明显的偏好。如砍手豪因为缺少用来训练神经网络的硬件,而倾向于参加 A 类比赛(参见:《零基础自学两月后三月三次轻松进入kaggle比赛top20小结》)。而我自己迄今参加的都是 B 类的比赛,原因是自己习惯于处理计算机视觉类的任务,而对传统 machine learning 任务尤其是时序预测方面了解比较少,不想进去垫底。如此一来 Kaggle 上仿佛存在着两个不同的世界。A、B 类比赛都很投入地去参加的人当然也是存在的,只是据我所见大部分人都倾向于参加其中一类。
我在此强调这两类比赛的区别,一个重要原因是,我发现迄今为止知乎上大部分的 Kaggle 入门指南大都是针对 A 类比赛的。例:
参加 Kaggle 竞赛是怎样一种体验? - Naiyan Wang 的回答 - 知乎
参加 Kaggle 竞赛是怎样一种体验? - Alex Hsu 的回答 - 知乎
零基础自学两月后三月三次轻松进入 Kaggle 比赛top20
B类比赛的文章/回答则少得多,例:
参加 Kaggle 竞赛是怎样一种体验? - AI 研习社的回答 - 知乎
Kaggle 的比赛在 Machine Learning 领域中属于什么地位? - 幻云羽音的回答 - 知乎
我希望本文可以对关注 B 类比赛的 Kaggler 提供一些参考。
三、靠套路而豪无创新究竟能得到怎样的成绩?
有人说 Kaggle 比赛全靠套路。这句话隐含的意味是要想在 Kaggle 上获得好成绩,靠的是套路而不是智慧和灵感,或者靠的不是真正的技术。如果去杠的话,我们也可以说发 paper 也是靠套路。但我想,即使真的是靠套路,也未必是一件完全的坏事,套路中也能体现高下之分,套路中也能体现出能力的强弱吧。很多 Kaggler 的成绩都是比较稳定的。比如 bestfitting 连续在 6 个比赛中得了 Top 3。比如 Fangzhou Liao 四次参加比赛全部都是冠军。而我大部分时间都进不去 Top10,也从未出过 Top30,大概是因为我总也没参透 Top10 选手的套路,而排名 30+ 的参赛者总也没参透我的套路吧。
那么靠套路而豪无创新究竟能得到怎样的成绩?我来试图给出一个下界出来:
1. 在Carvana Image Masking Challenge 中我的第一个 baseline 模型是 Unet,而且图省事用的是 pytorch-CycleGAN-and-pix2pix 中的 Unet。为了赶快跑出个结果我把图片从大约 1000x700 缩小成了 256x256 大小。没有经过任何调参的第一次提交结果是(Private Leaderboard) Dice coefficent = 0.985517,比赛结束时这个成绩可以排到 top 72%。把图片大小改成 768x512 之后,未经任何其他修改,成绩是 coefficent = 0.995050,比赛结束时可以排到 top 53%。
2. 在 Cdiscount’s Image Classification Challenge 中我的第一个 baseline 模型是 Pytorch 的 Resnet101,第一次提交的成绩是 Accuracy = 0.71929,比赛结束时这个成绩可以排进 Top 12%。
3. 在 Google Landmark Recognition Challenge 中我的第一个 baseline 模型是 ResNet50,第一次提交的成绩是 GAP = 0.115。我后来在讨论区把这个模型的训练公开了,即便如此,这个成绩在比赛结束时居然也可以排到 Top 14%。我的第二个 baseline 模型 DELF 成绩是 GAP = 0.203,比赛结束时可以排进 top 4%!
4. 在 Google Landmark Retrieval Challenge 中我套用了 Recognition 中使用的 DELF 代码,第一个模型即是最后一个模型,没有调优过程,排名 11%.
5. The Nature Conservancy Fisheries Monitoring 是个 two-stage 比赛,两个 stage 用的测试集不同,并且 stage 1 的成绩已被主办方清空所以我无法判断我们第一个 baseline 模型可以在最终的 leaderboard 上排第几。
6. Statoil/C-CORE Iceberg Classifier Challenge 这个比赛我是打酱油的,前期的实验细节我手头暂时缺失。
以上经验表明,只要选择了与任务相对应的 state-of-art 模型,在代码无 bug,没有实验设置错误的情况下,排进 Top 50% 甚至 Top 15% 难度很小。那么另外的 50%~85% 的参赛者出了什么问题呢?我猜可能原因有如下几种:
1. 根本不知道 state-of-art 模型是什么,也不知道怎么检索或者没有检索的意识。
例:想强行套用mnist分类的方法来解决 image retrieval 问题。
2. 不想离开心理舒适区,而选择自己相对比较熟悉或容易上手的工具、库和模型。
譬如说因为喜欢用 Keras 或者 Keras 刚入门而只用网上找得到源码的基于 Keras 的模型。
3. 或多或少知道 state-of-art 模型的存在,但硬件条件有限,而选择对计算资源要求不高的模型。
例:因为硬盘小或网速慢而下载缩小几倍的图片代替原图来进行训练的。
4. 代码有 bug,debug 苦手。
5. 实验设置有问题。比如存在逻辑错误或者参数有严重问题。
四、参加比赛有什么好处
至于说为什么有 50%~85% 之多,如果说不是向来如此,也许是最近几年 Kaggle 更火了,入门者也更多了吧。我去年(2017)在国内已经发现很多人在求职简历里写 Kaggle 比赛经历。至于 Kaggle 比赛经历对求职有多大好处我还不能确定。值得一提的是,我在参加第一次比赛感觉坚持不下去的时候,是看了 @lau phunter 的帖子坚持下去的:
2017-8-22 更新:两年过去了大家参加 Kaggle 热情高涨标准也水涨船高,以下标准请浮动一级。
原答案:
获奖的都是有真本事的人,在上面练几个题目得个好名次,十分能证明你对数据科学这个领域的实践和理解。我现在招人的时候几乎是这个标准:
写上参加过 Kaggle 比赛,我会看简历。
得过一次 10%,我会给电话面试。
得过 2 次或者以上 10%,我会给 on site 面试。
得过一次前 10,我们会谈笑风生。
楼主加油。
虽然水涨船高,总归有人认可是好事。
我想从一个平常人的角度来讨论 Kaggle 比赛能给我们带来什么。我先来举几个不适合平常人的角度:
1. 一个网上经常被讨论的话题,就是“paper 重要还是比赛成绩重要”。我想,能考虑这个问题的人并不适用那种很极端的情况:例如 ILSVRC(Imagenet) 如果能得第一自然也能把方法发到顶会上去。——ILSVRC 能得冠军的人根本不会疑惑这种问题吧。
2. “如果进了前几名还可以获得奖金。”如果不是 Grandmaster 的级别(例:Vladimir Iglovikov 一年内获得奖金 $28k),平常人的收益风险比恐怕还不如去搬砖。
而平常人真正容易面对的情况是,发顶会 paper 被拒或者根本写不出来,参加比赛成绩不算拔尖或者被吊打。我认为一个人如果花时间可以换来顶会一作,那么不参加 Kaggle 也没有什么遗憾。
Kaggle 常年都有各种比赛,有整理好的数据集,有各种 kernel 和帖子教你怎样下载和使用数据集,甚至会给出一些 baseline 代码。获胜者也会分享他们的 solution。这些特点对于那些想要尝试一些曾经没做过计算机视觉任务的人来说是十分新手友好的。这里的新手指代的不一定是计算机视觉方面完全的新手,比如说如果你本来只熟悉物体识别,想尝试一下语义分割,那么 Kaggle 也可能很适合你。
Kaggle 还有一大特色就是实时的 leaderboard,非常残酷。如果你什么都不做,你的比赛名次只会下降。这会造成一种心理的刺激,给你压力/动力让你改善模型——当然这也是一种精神折磨。
我还有一个感想是:Kaggle 比赛给了每个 AI 爱好者被考验的免费机会。可以让一些喜欢空想和嘴炮的人检查一下自己是不是如同想象的那般厉害。但这个感想的诡异之处在于,由于我上文中提到的,只要正常跑通一个 ResNet101 就可能进 Top 15%,而或许有人觉得 Top 15% 很了不起,这样一些喜欢空想和嘴炮的人参加 Kaggle 之后或许真的觉得自己很厉害了。So paradoxical……!
还有就是会认识很多志同道合的网友,这一点不展开讨论了。
五、陷阱和一些技巧
1. 每场比赛会有多少人参与?
计算机视觉类比赛用到的数据通常是图片和视频,无论是空间占用还是计算量都比较大,大到很多人不得不因为硬件资源,或处理大规模数据的经验和能力问题,而不愿意参与数据集较大的比赛。这导致了一场比赛的参与人数和数据量强相关。小数据集的例子如 2018 Data Science Bowl 训练集只有 80M 左右,参与队数高达 3634,Statoil/C-CORE Iceberg Classifier Challenge 训练集只有 43M,参与队数高达 3343。数据集比较大的如 Cdiscount’s Image Classification Challenge 训练集 60G,参与队数为 627。而 Google Landmark Recognition Challenge 的训练集要 170G 左右,参与队数为 483。
另一个决定参与人数的主要因素是任务的复杂程度和生僻程度。纯分类任务比较受欢迎,其次是语义分割等任务。这些比较受欢迎的任务特点是门槛比较低,网上找得到大量现成的代码和模型(如 VGG、ResNet、Unet、SegNet),会调库无需深入了解原理甚至可能不用调参就能跑出像模像样的结果。(因为诸如图片分类等任务门槛特别低,以至于被某些人当做 AI 从业者的黑点。对此类黑点的态度不在本文的讨论范围。)Google Landmark Recognition Challenge 和 Google Landmark Retrieval Challenge 数据集大小几乎一样,因为 retrieval 问题的门槛相对比较高,后者的参与队伍数不到前者的一半。而 NIPS 2017: Targeted Adversarial Attack 这个对抗攻击任务,只有 65 队参加。
硬件条件好,经验丰富,能力强的人不太在乎如上两点因素,并且排名靠前经常霸榜的人大都是这样的人,因此一个人的期望排名和参与总队伍数并非是线性关系。——譬如说,我在两千队参与的比赛中得了第 16,那么同样的水平和发挥,我在六七百队参与比赛中就能进前 10 吗?没那么容易,事实证明我在六七百队参与的比赛中依然是第十几名。当然这里没有考虑到运气成分,只是个粗略的例子。
由于我抱以上述观点,显而易见我个人看重绝对排名胜于 Top 百分比。但会有很多人偏好于追求一个漂亮的 Top 百分比。我的建议是,想要 Top 百分比好看,或者目标是铜牌和银牌的同学应该多参加人多的比赛。人再多,Top 10% 都保证有铜牌,Top 5% 都保证有银牌;而人多的情况下进 Top 10% 甚至 Top 5% 的几率也大。(金牌的规则不一样,队伍总数 1000+ 的情况下金牌数只有 10+0.2%*队伍总数。参见 Kaggle Progression System)
2. Public Leaderboard 陷阱
数据集小的比赛虽然门槛低,却并不真的简单容易。较小的样本量会导致验证集和测试集的样本分布差异较大。加上由于计算量小,模型迭代(这里指更新换代,不是训练一个 iteration)速度快,很容易导致一种后果:overfit 到验证集上,这种后果导致的常见悲惨结局是比赛结束的时候发现 Public leaderboard 成绩还不错,但是 Private Leaderboard 上的排名一落千丈(通常 Public Leaderboard 会被当成是某种意义上的验证集)。例如 Statoil/C-CORE Iceberg Classifier Challenge 的两个 leaderboard 上有很多人有一百多甚至两百多的排名变化,相比较而言,数据量大了的三个数量级的 Cdiscount’s Image Classification Challenge 绝大部分人排名都没有变化,少数有 1~2 名的浮动。
对此我只有一句空洞的建议:合理的 evaluation 策略至关重要。Kaggle 排名第一位的 bestfitting(真名 Shubin Dai,中国人)称:
A good CV is half of success. I won’t go to the next step if I can’t find a good way to evaluate my model.
———链接:Profiling Top Kagglers: Bestfitting, Currently #1 in the World
这些大佬们每次在比赛结束公布 Private Leaderboard 的时候排名都比较稳定,不太容易下降很多。可见看似是取决于运气的排名大震荡,在大佬手里是有办法控制的。这大概就是真功夫吧。
3. 马甲和私享代码
在数据集小的比赛中,由于迭代速度比较快,每天提交的次数又有限制(大部分比赛是 5 次),所以经常会有人注册小号来提交结果。在数据集较大的比赛中,后期也偶有这样的现象。有的人在排名比较好的时候会私下里把代码分享给别人(比如同学),以求一人得道鸡犬升天……。我在比赛中见过几次别人注册马甲或私享代码。譬如说一夜之间就冒出了一堆三无账号,成绩还都差不多。或者在成绩对参数极其敏感的任务中一次提交就飞进 Top5%,一发入魂。一人多号和私享代码是违背比赛精神的,也是 Kaggle 明令禁止的,并且也是 Kaggle 会探测和封杀的。可悲的是,经常会有中国人这样做。为什么我这么确定?因为有些账号的 ID 用的是拼音,或者地址选了 China。真是又坏又蠢,作弊本已可耻,却还要披着中国人的形象。大概是觉得自己聪明,占了便宜却无人知晓吧……然而最终这些账号都被主办方踢出了比赛或者删号处理。
4. 刷全站排名
全站排名取决于你在过往比赛中取得的总积分,积分公式如下图:
截图来源:Improved Kaggle Rankings(图侵删)
积分是随着时间呈指数衰减的。这意味着,如果要刷高自己的排名最高纪录,那么参加几次间隔很久的比赛,不如参加几次间隔很短的比赛。
另外参加任何的比赛都不会减分,所以片面地追求全站排名不太在乎提高自身水平的,可以考虑在海量的比赛中打酱油。这是一个病态无聊但可行的策略。
5. 更多的 supervision
在绝大部分的比赛当中,在训练集上做额外的标记都是不违反规则的,只要在规定的时间(有些比赛是 deadline 的两周以前)以前上传到讨论区和其他参赛者分享。譬如说,在鱼类识别的任务中,你可以用 bounding box 标记出鱼的位置。在海狮计数的任务中你可以用 mask 来标记出每一个属于海狮的像素。这些额外的标记通常都能帮助训练出更好的模型。但开销也不小。另外要注意的是,在测试集上做标记是明令禁止的作弊行为。
六、其它
1.参加计算机视觉类的比赛需要多少 GPU
一两块 Titan X, 1080 或 1080Ti 就够了。一块 980 也勉强可以。四块以上的 GPU 当然更好,但 GPU 多了其实很难充分利用到。运算速度快到一定程度,人脑 debug、分析问题、想 idea 的时间就成了主要的速度瓶颈。如果不怎么分析问题,不怎么想 idea,走无脑穷举试错的路线,以图速度或图省事,很容易走偏。高手们会根据自己的经验和直觉来快速尝试不同的模型,所以驾驭得了更多 GPU。如果你有“只要给我更多的 GPU 我肯定能大幅提高排名”这样的自信,不妨试试 aws 上的 spot instance,如果确实如此,那就可以攒钱或求赞助来入手 GPU 了。
诚然,小数据集的比赛对 GPU 要求很低,甚至 750M 这样的 GPU 也可以用。但是因为迭代速度太快,以及 leaderboard 每天都有大浮动,这样的比赛参加起来特别费肝……
2. 什么样的排名算是一个好的排名
Jeremy Howard 在 2017 年年初或 2016 年年末(记不清了)的 fast.ai 的教学视频里(出处懒得求证了)说:排进 Top 50%,说明你的模型还 OK;排进 Top 10%,说明你是这个领域的专家;排进 Top 1说明你是世界上最顶尖的专家。他的这段话过于乐观了。很多时候排名看起来还可以,只是因为真正的(诉诸纯洁:P)专家们和大佬们大多没有时间参加 Kaggle 而已。但这么想似乎也是有失公允的,因为菜鸟和外行们也大都没有参加 Kaggle。所以谁知道呢……?