Auto Byte
专注未来出行及智能汽车科技
微信扫一扫获取更多资讯
Science AI
关注人工智能与其他前沿技术、基础学科的交叉研究与融合发展
微信扫一扫获取更多资讯
强势入驻Kaggle,却什么奖牌都没拿到怎么办?Notebooks Grandmaster第一名:我也很苦恼
参与 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,论坛上也有许多不错的想法,但同时它也存在很多问题:因此,如果你想使用现成的代码和想法,请确保先进行检查和验证。不断寻找新的 idea,并进行尝试
参加 Kaggle 竞赛最酷的体验之一是,参赛者会不断追求新的 SOTA 结果。而为了获得最佳成绩,参赛者必须尝试新事物。所以他们需要阅读大量 arxiv 论文,搜寻好的博客文章等等。但值得注意的是,仅仅阅读查找新方法远远不够,还必须进行尝试。虽然有时为一些新的 idea 编写代码非常困难,但这是学习新事物的绝佳方式。最后,即使一些 idea 不 work,你依然积累了有用的经验。避免过度调参
过度调参是一种常见的误区(我自己也栽过几次)。有些人认为调参能帮助他们取得好成绩,这种观点有一定的道理,但并非完全正确。在 tabular 竞赛中,有必要执行两次调参,分别在竞赛的开始和结束阶段。调参在竞赛的初始阶段很重要,因为梯度提升以及必须针对不同的问题对其他模型进行调参。不同的目标和深度、叶节点的数量以及其他参数在不同问题中会导致不同的分数。但当你发现一些好的参数之后,修复它们并在竞赛临近结束的时候再 touch。此外,当你添加一些新特性或尝试新 idea 时,保持超参数不变,这样你就可以对实验结果进行比较。当你穷尽所有的 idea 时,你可以再次进行超参数调优,以小幅提升分数。在涉及深度学习时,情况则有些许不同。这时,超参数空间很大:你可以对架构、损失、数据增强、预/后处理以及其他参数进行调整。这样一来,你就不得不花费大量时间进行优化。最后,需要牢记的一点是,好的 idea 比调参更能提升分数。