参与 Kaggle 竞赛却没有拿到奖牌,我应该怎么办?
机器之心报道,参与:泽南、魔王、杜伟。
很多参与 Kaggle 竞赛的人都希望能够通过构建具有竞争力的算法来提升自己的水平,但对于绝大多数参与 Kaggle 竞赛的同学来说,在一番努力之后没有拿到任何奖牌显然是大概率事件。
在这之后应该怎么办呢?
参加 Kaggle 竞赛屡屡败北后,Kaggle 社区 Notebooks Grandmaster 第一名 Andrew Lukyanenko 总结了自己的经验:
孟加拉语是全球使用人数第五的语言。Kaggle 上有一个孟加拉语识别挑战赛。这种语言拥有 49 个字母和 18 个变音符号,这意味着它存在很多种字位(书写语言的最小单元)。
在「Bengali.AI Handwritten Grapheme Classification」挑战中,参赛者需要使用机器学习方法来预测这些字位的三个独立部分——字位根、元音变音符号和辅音变音符号。
看起来有点超纲了?这样一个可能有些小众的比赛,吸引了超过两千支队伍参赛。起初我只是单枪匹马前来参加,但很快就找到了四个志同道合的网友组成了团队。我们在这场比赛中花费了大量时间和资源……最终却只名列第 254 位,没有获得任何奖牌。
「社会的毒打」让我沮丧了很长一段时间。
失败后我究竟做了些什么?在这之后,我对自己所做的事情进行了反思,阅读了高阶团队的解决方案,并吸取了一些经验教训。本文中有很多可以分享的东西,它们适用于所有数据竞赛类型,大致可以分成几类话题:思维方法和一般方式、代码实践、需要提前准备的东西。
工欲善其事,必先利其器:软件环境
正如大多数机器学习实践,训练模型是 Kaggle 竞赛的主要部分。Kaggle Notebook 看起来很美好,但是它给的 GPU 算力远远不够,只有每周 30 个小时。按照目前的经验看,想要好成绩都要将算法运行在自己的机器或者其他云服务上。
首先我们需要设置工作环境,这项工作用 pip、conda 等方法就可以实现。你最好在 Kaggle 上检查各个库的版本,并在自己的环境中安装同样的版本——不同版本的组件可能意味着不同的 API 或逻辑。
硬件设备
另一个重要的因素当然是硬件本身。如果我们有大量数据要处理(如这项 Kaggle 竞赛),那么在单显卡上训练单个模型就得花费一天甚至更长时间。并且,运行实验通常要比训练最终模型花费的时间更多。所以我们需要尝试不同的硬件。
我的 Windows PC 上配置有双路英伟达 Geforce GTX 1080TI,但这显然不够。我在 Google Cloud 上多次租用 GPU,但忒贵了,所以我开始尝试新的方法。
最近我听说了 Hostkey(一家高级网络服务提供商),你可以租用他们的服务器。以下是 Hostkey 的 promo program:
We offer free GPU servers to the winners of grants at large competition venues for their use in further competitions, for training or for personal projects related to data science.
但作为交换,参赛者必须在社交媒体上分享他们的反馈和经验。
最开始,我得到了一台配备 4 路 1080ti 的服务器。所以设置环境没遇到什么问题,并很快开始训练模型。在单个 GPU 上的训练取得了非常好的进展,于是我开始逐渐增加 GPU 数量。结果证明,2、3 个 GPU 也能运行良好,但使用 4 个 GPU 时却失败了。技术支持很快给出反馈,并在几天内查明了问题所在。原来服务器本身存在一些问题,处理器无法跟上 4 路 1080ti 的全功率运行。
所以,我改用了另一台配备双路 2080ti 的服务器。但由于电源供应不够强大,刚开始的时候遇到一个小问题。然后工程师增加了一个电源,问题也就迎刃而解了。此后,我在这台服务器上运行了很多模型,结果都很不错。所以接下来我还会选择租用 Hostkey 的服务器。
设计运转良好的工作流程
优秀的工作流程至关重要。这里的「流程」(pipeline)指的是用来准备训练数据、训练和推断的代码。这里你可以使用一些高级的框架,但从头开始自己写代码也是不错的选择。使用高级框架的主要优势在于可以快速改变,并确保基础层面正常运转,这样你就可以专心于高级功能了。
在竞赛中,我先使用 Catalyst 的 Jupyter API,但由于出现问题便很快停止了。过了一段时间后,我决定听从队友的建议转向 Catalyst 中的 Config API。这个 API 更适合我,但需要很长时间才能适应。
对此,我得到的经验是:选择一个方法(特定的框架或工作流程)并坚持下去可能是更好的做法。
无法直视的代码
很多人说 Kaggle 竞赛参与者写的代码惨不忍睹……事实经常如此,其主要原因是对快速迭代的需求,因此相对于写更好的代码,尝试新想法是更加实用的做法。不过我并不认同这一说法。
有时候,稍微进行代码优化会产生非常大的影响。大家可以看一下上面的截图,代码优化可以让推断速度提升 30 倍。训练过程也变得更快,因此把事情做好非常重要。
但是……
不要盲目相信论坛或 kernel 中的代码和想法
Kaggle 是个很不错的平台,拥有大量可用的优秀 notebook,还有可以找到酷炫想法的论坛。然而,事实并不尽然。
这里当然有很多高质量的 notebook,论坛上也有许多不错的想法,但同时它也存在很多问题:
- 一些 notebook 中的代码和代码实践存在错误,还有验证问题、想法的错误实现等问题;
- 论坛中的一些想法存在误导性。这并不代表提出想法的人带有恶意,而是因为很多想法本身并不 work,只有和别的想法结合才能取得效果,有些需要性能足够好的模型等等。
因此,如果你想使用现成的代码和想法,请确保先进行检查和验证。
不断寻找新的 idea,并进行尝试
参加 Kaggle 竞赛最酷的体验之一是,参赛者会不断追求新的 SOTA 结果。而为了获得最佳成绩,参赛者必须尝试新事物。所以他们需要阅读大量 arxiv 论文,搜寻好的博客文章等等。
但值得注意的是,仅仅阅读查找新方法远远不够,还必须进行尝试。虽然有时为一些新的 idea 编写代码非常困难,但这是学习新事物的绝佳方式。最后,即使一些 idea 不 work,你依然积累了有用的经验。
避免过度调参
过度调参是一种常见的误区(我自己也栽过几次)。有些人认为调参能帮助他们取得好成绩,这种观点有一定的道理,但并非完全正确。
在 tabular 竞赛中,有必要执行两次调参,分别在竞赛的开始和结束阶段。
调参在竞赛的初始阶段很重要,因为梯度提升以及必须针对不同的问题对其他模型进行调参。不同的目标和深度、叶节点的数量以及其他参数在不同问题中会导致不同的分数。但当你发现一些好的参数之后,修复它们并在竞赛临近结束的时候再 touch。此外,当你添加一些新特性或尝试新 idea 时,保持超参数不变,这样你就可以对实验结果进行比较。
当你穷尽所有的 idea 时,你可以再次进行超参数调优,以小幅提升分数。
在涉及深度学习时,情况则有些许不同。这时,超参数空间很大:你可以对架构、损失、数据增强、预/后处理以及其他参数进行调整。这样一来,你就不得不花费大量时间进行优化。
最后,需要牢记的一点是,好的 idea 比调参更能提升分数。
来源:oschina
链接:https://my.oschina.net/u/4365362/blog/3234187