我跨行学了半年计算机视觉,Solo拿下Kaggle银牌2%

QQ截图20210105114838.png


编者说
这是我们分享比赛优胜者个人经历的第一期,将比赛经验分享给需要的群体,为他们提供有价值的参考。他山之石,可以攻玉,这是我们做这个系列的初衷。
 

个人介绍

⼤家好,我是⼩曾,本科机械专业,研究⽣是⻋辆⼯程专业。
19年决定⾃⼰转⾏计算机视觉,在19年暑假起个人Solo参加了⼏场⽐赛,主要是图像分类的APTOS 2019 Blindness Detection(眼球病变严重程度的诊断),多标签语义分割的Severstal: Steel Defect Detection(钢铁缺陷检测)和Understanding Clouds from Satellite Images(浅云组织的语义分割)。分别获得了银牌(top2%)、铜牌(top5%)和铜 牌(top7%)。
先说为什么转行吧。
我从大四保研后就开始进实验室工作(搬砖)了。在我决定转行前一年,我主要参与了三个方向完全不搭边的项目,每个项目都是从零开始,我的老师也不算特别push,也没有对我pua。但是从学生的角度讲,我确实无法在实验室学到整体系统的东西,也无法培养自己的核心竞争力,为自己未来考虑,所以决定自己学点东西。
pexels-photo-4577841.jpeg

QQ截图20210105115016.png


比赛经历

对我来说,印象深刻的比赛是我参加的第一场比赛APTOS 2019 Blindness Detection(眼球病变严重程度的诊断)。这场比赛是我成绩最好的一次,同时也是用时最久的一次比赛。
这场比赛是0-4类的五分类问题,策略是集成差异性⼤的多个模型预测结果。由于计算资源有限和交叉验证,所以在多折训练集上分别⽤不同的backbone训练,然后做投票。
由于评价指标⼆次加权卡帕系数计算比较复杂,并且标签可以看做连续值回归,⼤家发现⽤MSE损失进⾏优化的结果普遍用分类损失来优化的结果⾼1-2%,所以绝⼤部分⼈都将⽐赛作为回归任务处理。在分析了评价指标后,我设计了⼀个损失函数,分类的⽅法也可以达到⽤回归处理的性能。
此外,通过查阅⽂献找到了⼀种预处理⽅法,所以在预处理前和预处理后的图⽚上分类和回归的⽅式训练多个模型,最后集成的效果很不错。 
分享一下我的比赛思路吧,主要有三点:
⼀是“数据 决定了模型算法的天花板。我当时纯⼿⼯地从⼏万张⽐赛数据集和额外数据集图⽚中筛选出3000多张完全看不清眼球的图⽚,去掉它们后训练的模型在测试集上有明显的提⾼;
⼆是集成尽可能差异性⼤的多个模型的预测结果模型集成是⽐赛中常⽤的⼿段,所以我训练了多个不同backbone的模型来做集成,涨点很快。
最后,⼀定要做好本地交叉验证不要过于相信公开榜的成绩,私榜成绩好才是王道。 
当然,这场比赛也留下不少遗憾。
pexels-photo-590141.jpeg

比赛中受客观条件的限制很大。实验室不是做深度学习的,没有计算资源,所有实验都只好在Kaggle给的GPU上进⾏,没有充足的资源对比赛成绩会有一定的影响。由于Kaggle⽤的UTC时间,为了尽快地迭代实验和尽量多地提交结果,自己经常会卡着点在半夜和清晨跑实验和提交结果。
比赛中遇到最⼤的问题,就是计算资源不⾜。这导致很多实验都没法跑,经常等了⼏个⼩时后去看kaggle notebook的运⾏结果。最后发现代码错误或者存储超出等原因运⾏中断,浪费了时间和GPU额度,还没有得到想要的结果,现在想起来确实有点惨。
⽐赛结束复盘时,发现我对于图像预处理的认知存在⼀些偏差。经过预处理后的图像在⾁眼感官上确实会好很多,但是有可能会破坏原图真实类别间互相关联的特征。赛后琢磨⼤佬们的解决⽅案时发现他们很多都没有使⽤太强的预处理,仅仅只⽤了裁剪或根本不做预处理。 
pexels-photo-5326922.jpeg

说到这,我认为比赛中给我很大帮助的是比赛中的对手由于是⼀个⼈参加⽐赛,不认识相关的朋友,也没有⾜够的时间和资源做很多实验,所以经常会逛讨论区,基本上所有帖⼦我都看 过。主要看⼤家的观点、比赛中的想法和他们做过的⼀些对⽐实验的结果,从他们⾝上可以学到很多常⽤⽅法和⼀些新的思路,以及⼀些虽然没有试过但是可能会有⽤的技巧。我觉得Kaggle的讨论区总体氛围⾮常好,尤其对新⼈来说很友好。此外,在Notebooks区还有各种EDA和 Baseline的代码做参考,我认为这些给了我很⼤的帮助。 

比赛经验

回顾去年参加的比赛,我也得出了一些比赛心得和比赛技巧,想在这里分享给大家。
1.个人打比赛的话,我认为劣势比优势更多
劣势就是个⼈的思维始终是狭隘的。个⼈想要获得⼀个⽐较好的名次,需要付出更多的时间和精⼒。如果是多⼈合作,⼤家可以分配并⾏完成很多⼯作,查⽂献代码、做EDA、对⽐试验,可以极快地加速⽐赛进度。并且通过互相讨论可以查漏补缺、快速成⻓,我⾮常希望能组队⽐赛。
优势的话,可能就是⾃由⼀些,可以按⾃⼰的想法尝试不同的⽅案,也更能锻炼个⼈的分析、判 断、代码能⼒。 
2.比赛中有一些上分技巧
在分类⽐赛中mixup是个普遍有⽤的技巧,TTA、SWA、Ensemble等基本都能提分。除此之外,合适的数据增强、学习率策略、优化器、损失函数都是很重要的部分,就 需要花时间去尝试了,为了简单起,⼀般我会选SGD+Nesterov+OneCycleLR的组合。
3.比赛新手的准备
对新手来说,如果想打比赛⾄少要熟悉python和⼀⻔炼丹框架,确保有⾜够的时间,同时对⽐赛⽹站的规则要有基本的了解,避免踩雷。
在比赛类型选择上,新手尽量选择参加⼈数多,Disscusion和Notebooks帖⼦代码多的⽐赛。参加⼈数多代表了这个⽐赛的数据集⾄少是GPU 友好的,⼈多代表了想法会更多,值得学习的东西也更容易出现。 如果是研究⽣,最好选择研究⽅向和⽐赛任务是契合的。
4.比赛有几个点需要注意:
第⼀,克服畏惧⼼理,我⼀个没显卡、没⼈带的⼈都敢上,⼤家莽就完了;第⼆,如果以学习为主的话,建议不⽤刻意追求名次,可以先学习整个⼯作流程,独⾃掌握从 处理分析数据、搭建baseline、调参、推理、后处理、结果优化到bad case分析等的完整流程;第三,多交流多提问多尝试,⾄少在Kaggle上,⼤多数⼈都是⾮常友好的。 
5.最后补充一下,参加几场比赛下来,从中最大的收获:⼀定要做好本地交叉验证,不要迷信排⾏榜,过拟合太难顶了。