目标检测类算法比赛的经验总结

AI算法与图像处理

共 8707字,需浏览 18分钟

 ·

2021-01-22 10:37


参赛经历

阿里天池:“数字人体”视觉挑战赛 - 宫颈癌风险智能检测诊断 [1]

 Info  2019.10.24 - 2019.11.21,目标检测,21/2358


Kesci:2020年全国水下机器人(湛江)大赛 - 水下目标检测算法赛 [2]

 Info  2020.2.28 - 2020.4.11,目标检测,31/1.3k


阿里天池:天池新品实验室 - 淘宝直播商品识别 [3]

 Info  2020.2.12 - 2020.5.23,检索匹配,已弃赛


我将按照以下目录结果进行内容的总结:
一、数据研究
二、数据准备
三、参数调节
四、模型验证
五、模型融合
六、题外话

一、数据研究
获取数据后的第一件事是了解并探索数据,这个步骤在数据分析领域叫做探索性数据分析EDA(Exploratory Data Analysis)。而在CV领域也需要这步,关于目标检测,我会从给定数据的具体内容来进行以下研究:
1. 图像:
a. 宽高频次图:
决定图片预处理方式。例如:像宫颈癌病理图属于高分辨率图片,那后续就得切小图准备合适的数据。
 了解数据采样方式。例如:在水下检测赛里,就发现虽然有5种不同的宽高搭配,但它们的宽高比就两种:1.22和1.78,说明其水下拍摄采样的设备可能就有两种画幅宽高比,只是画幅大小可能比较多变,导致出现宽高比相同下但分辨率不同的图片。
b. 可视化:了解数据真实质量,采样环境等。

2. 类别标签
a. 类别频次图:是否存在类别不平衡问题,如果类别严重不平衡,可能需要做额外的数据增广操作,最好研究下类别不平衡的原因,有可能是重复图片或者标注问题导致的,例如Kaggle上的鲸鱼尾巴分类大赛,它数据集中存在很多重复的图片,而且同一张图片存在多类别标注。

3. 标注框:
a. 宽高散点图:在训练尺度设置下,判断模型感受野是否设置合理 [4]。在训练模型前,图片往往要被Resize到给定的训练尺度(或多尺度),那么在绘制散点图前,要先将原标注框Resize到最大的给定尺度下,去绘制它Resize后的标注框宽高分布图。之后选取Backbone模型时,应考虑模型感受野尽量大于多数标注框的长边。
b. 各类下宽高比频次图:是否个别类别存在极端宽高比情况,极端宽高比需要对锚点框相关默认设置(即Anchor Ratio 和 Anchor Scale)进行调整。
c. 各类下框面积大小频次图了解数据大/中/小目标的情况,尤其注意小目标,其次是大目标。小目标难检测。而在高分辨率上的过大目标可能需要合适的手段进行切分,例如宫颈癌切片里的Candida异常细胞(大多数目标的宽/高大于1000)。
以上只是一些基本需要做的数据研究操作,但事实上,数据的处理还要基于数据的特殊性做额外的补充研究。这块数据研究的一些内容可以参考下郑烨选手在天池上的分享 [5]

二、 数据准备
数据研究完后,就需要准备数据,简单来说就是数据预处理和数据集划分。
1. 数据处理:
a. 线下数据增强:这块内容与“三、参数调节 – 1. 训练前 – 数据增强”重复,这里不做阐述。
b. 训练和测试集统一化:有时候训练集和测试集存在分布不统一,例如:采样方式/地点不一致,标注人员/方式不一致。可能的话,尽可能保证它们的一致性,比如在水下目标检测里,训练集和测试集是在不同的水下深度拍摄的,那么图像色调就可能会不统一,如果你对训练集做去雾或一些后处理操作的话,需要考虑是否对测试集也得提前做相同的数据处理操作。另外,在Kaggle X光肺炎检测比赛 [6] 中,训练集是由唯一的专家标记,而测试集是由三名独立的放射医师标记,这种情况下,使用他们标记的交集用于标签真值可能可以更好地统一训练和测试集的标签分布。

2. 数据集划分
a. 传统划分法:传统方法就是直接按比例划分,例如原数据80%划为训练集,20%划为测试集。
b. 分层抽样法式划分:按照规定的比例从各类下抽取一定的样本,优点是抽取的样本考虑到了类别。在该划分的测试集上,后续验证会有更全面且客观的结果。
c. Domain划分法:按照规定比例从各Domain下抽取一定的样本。该方法是我在参加水下目标检测比赛中,听郑烨选手提到的一个划分方法,当时水下图像集是在不同年份、不同水下地点和不同设备拍摄的几段视频中截图标注得到的。因此可以考虑针对不同年份/不同拍摄视频段/设备,划分好Domain后,再从这些Domain下抽取一定比例的样本。
d. K折划分法:在 [6] 中,参赛者就将相同模型的四折交叉验证的输出合并,进而检验模型的结果。
在数据集划分中,提到的四种数据集划分方法可以相互结合使用,例如Domain下分层抽样式划分,不同的划分方法耗费的时间都不一样,一般我是建议如下:
 各类数据量大且较平衡:传统划分法。
 类别不平衡且某类数据少:分层抽样式法。
 有明显Domain且Domain数较少:Domain划分法。
 数据量较小或算力充足:K折划分法。

三、参数调节
我比较喜欢目标检测工具箱mmdetection [7],它已经封装好很多SOTA目标检测方法的相关代码,很多时候你只需要调参即可。因此这部分我称之为“参数调节”,但实际上,下面有些内容还是需要额外的编写代码。
接下来,我将以训练前/中/后三个过程中存在调节可能的参数或方法进行如下总结:
1. 训练前:
a. 数据增强:
 空间不变性:神经网络模型具有空间不变性,为了解决它,一般需要采用一些空间增强手段例如平移、旋转、翻转、缩放、实例平衡增强 [7]等。
 噪声:神经网络模型有时候过于依赖训练数据,缺少推断能力而影响通用性,即使人眼能识别出噪声图片里的目标,但模型却不太行,所以为了让模型更加鲁棒,可以考虑在训练集内加入高斯噪声、椒盐噪声等对模型进行干扰。
 目标遮挡或重叠:如果数据研究时发现存在多框重叠现象,或者存在目标遮挡,可以试着采用Cutout [9] 或Mixup [10] 等。
 过采样:有时候整体数据量过少,或某类别数少导致类别不平衡,可以考虑使用copy-paste [10] 、泊松融合 [11]等技巧,但要注意,增强的目标不要过于突兀,不然会造成模型过拟合。
 图像模糊:图像模糊的原因有很多,例如:镜头模糊,雾天图像,水下光线散射等,对此的数据增强手段有中值/高斯/动态模糊、去雾算法 [13], MSRCR [2]等。
 其它标签平滑 [10], 色调归一化 [2],Albumentation图片数据增强库 [14] 等。以上所有数据增强方法分线上和线下两种使用方式,不同数据增强方法之间存在功能重叠,基本都能在一定程度上减少模型过拟合,但也可以会有过拟合的可能(例如copy-paste和实例平衡增强等会重复部分数据集的可能)。

2. 训练时:
a. 训练尺度:根据显存和时间安排设置训练是否采取多尺度,正常来说,尺度越大越好,小目标能更好的被检测到,但也存在尺度调整过大,图片失真。在设置尺度上,我一般是放开Resize对长边的依赖(即长边至少为:训练原图尺寸最大长短比 * Resize短边上限),mmdetection论文提到提高短边上限能带来提升
b. 测试尺度取训练尺度的中间值即可。假设训练多尺度设置是[(4096, 600), (4096, 1000)],那么测试尺度如果你想设为单尺度,可以是(4096, 800),如果是多尺度,可以是[(4096, 600), (4096, 800), (4096, 1000)]。测试多尺度会更好些,但推理速度会变慢
c. Anchor (scales & ratios)正常来说,锚点框的设置保持默认配置就好,但是如果遇到某类别目标是极端长宽比,则可能需要根据数据研究的结果适当调整下锚点框宽高比率,而锚点框大小scale相对来说不太需要对其进行过多调整。我之前试过使用YOLOv2中提到的K-means来获取Anchor聚类结果,进而调整Anchor的设置,但是结果不太理想,据微文 [4] 作者所说,实际感受野是一个超参,无法准确求出,K- means聚类Anchor得到的范围实际上不一定有默认Anchor的广。简而言之,就是不要乱动默认的配置,可以添加多一个Anchor Ratio,但不建议自行胡乱调参。
d. Backbone:目标检测的主干网络很多,选择主干网络的第一要素就是得先确认模型的感受野是否尽可能大于数据集多数标注框的长边。当你确定了训练尺度,选择最大Resize比例去绘制标注框宽高散点图,然后选取合适的模型Backbone。如果模型感受野太小,只能观察到局部特征,不足以得到整个目标的信息;如果感受野过大,则会引入过多的无效信息。现在计算感受野有两种方法:(1)从上往下法:即从低层到高层,这种方法计算更便捷些,但只适用于比较有限的卷积,且由于没有处理由Stride引起的抽取像素重叠的问题,使得计算的感受野会偏大些;(2)从下往上法:即从高层到低层,计算感受野是通过递推计算,它很准确。这里不详细展开,详情计算方式可见 [4]。限制一些SOTA的主干模型有:ResNet, ResNeXt, DenseNet, SENet等。此外,如果存在极端宽高比的目标,可以使用可变形卷积网络(Deformable Convolution Net, DCN)
e. Neck:用的比较多的就特征金字塔网络(Feature Pyramid Networks, FPN),对于小目标检测非常好用
f. ROIHead:在mmdetection里RoIHead的作用是帮助模型基于RoI进行预测,现在比较受欢迎的模型是Cascade R-CNN,它级联三个不同IOU阈值(0.5,0.6,0.7)的头,但在2019广东工业智造创新大赛决赛 [15] 上,某团队针对评测mAP要求的IOU阈值0.1、0.3和0.5,降低了级联的阈值至0.4、0.5和0.6,从而获得了提升,说明宽松评测下,级联头阈值可适当减低以获取更多的预测框,这种方式可能会提升性能。另外,在天池”重庆大赛-瓶装白酒疵品质检”里,好像也还有选手通过增加多一个head,在某种程度上帮助模型更好的拟合数据,但不一定在每个赛题数据上都起作用。
g.混合精度训练: 开启fp16能加快模型运算速度。
h.学习率:学习率的设置应参考论文 [16]. 该论文提到在使用多GPU并行进行Minibatch SGD的行为被称作Large Minibatch SGD。假设有k个GPUs,那么Large Minibatch size =k * Minibatch size(即mmdetection中的img_per_batch),此时多GPU下学习率 = 单GPU下的Lr * k。总结来说,Lr = GPU数量 * Minibatch Size * 0.00125
学习率在衰退前使用warmup会好些,衰退策略使用Cosine会比Step更快帮助模型拟合数据。此外,mmdetection作者认为像多尺度训练这样的训练增强应该需要24epoch数进行训练,但一般来说1x的训练epoch数就能应付较多的场景。个人认为,1x(2epochs)和2x(24epochs)的选择得看训练后的损失曲线或mAP曲线的表现来决定。

3. 训练后:
a.如果EDA发现存在大量同类下多框重叠,例如水下图像中经常多个海胆目标重叠,建议使用Soft NMS。此外,在mmdetection中NMS都是在类内完成的,如果EDA发现数据不存在类间重叠(这种情况比较少发生),则可以考虑自己额外补充类间NMS(即所有类下的框一起NMS)。

四、模型验证
模型验证阶段看三个曲线:各类别AP曲线、不同IoU下的MAP曲线、损失曲线。
1. AP曲线:发现哪个类别的目标检测效果差,后续可以针对表现差的类别进行模型改进,例如: 专家模型,改变数据处理方式等。
2. MAP曲线: 更好的贴合比赛的评测指标,给出最直观的结果。
3. 损失曲线: 观察模型拟合表现,如果模型损失下降过快或过慢,可适当调节学习率或学习率衰减节点的设置。

五、模型融合
1. 融合选择
在知乎上,[17]  提供了关于模型集成的几种选择:
a. 同样的参数,不同的初始化方式
b. 不同的参数,通过交叉验证,选取最好几组。
c. 同样的参数,不同迭代次数训练下的
d. 不同的模型,线性融合,例如RNN和传统模型。

2. 融合方式:
a.  直接合并: 就是根据验证集的表现,选取不同模型设置下,最好表现的类别结果进行合并,例如有2个不同的模型设置(设置1和2)且预测类别有2个(类别A和B),类别A在模型设置2下表现最好,而类别B在模型设置1下表现最好,那么最后的提交结果应该由模型设置2下的类别A结果和模型设置1下的类别B结果合并组成。优点是该合并比较简单快速,缺点是它要求验证集的真实反应能力强,比如之前宫颈癌细胞检测比赛,数据集很大,验证集表现和线上测试集表现基本一致,它就很适合直接合并模型结果。
b. WBF: 权重框融合Weighted Boxes Fusion也是比较受欢迎的模型集成方法,它将同类下达到某IoU的框们,进行加权平均得到最终的框,权重为各预测框上预测类别的分数。WBF有两种融合思路: 不同backbone的融合和不同结构的模型的融合,据论文(代码已开源 [18])所述这种方法比前者提升更大。在使用中要注意,Soft NMS输出结果要搭配max的置信度融合方法(即在两个模型预测结果中选择其中最大的置信度作为平均融合框的置信度,避免平均融合后的结果不会受冗余低分框影响),而普通NMS输出结果搭配avg融合方式即可。

六、题外话
1. 比赛及队友选择
比赛可以根据个人喜好进行选择,比赛平台有很多,阿里天池、Kesci及各大公司在它们官网放的比赛等,个人比较喜欢天池,因为很多时候官方会公布baseline方案,选手可以进行学习,而且交流氛围且对比赛最终答辩的分享都做得很好,对数据错误的更新也十分及时,相反地,一些比赛如果后期不公开答辩或选手思路,除非前排大佬主动公开,否则对于抱着学习态度的参赛者来说很难去获取优秀的项目思路。所以对于刚开始参加比赛的新手来说,要看重是否该比赛的学习价值较高(较易上手但存在深入研究的空间、优秀代码是否会开源、参赛者讨论情况等)。后期参加多几次某个特定领域的比赛后,就可以在之前比赛的基础上深入去实践自己的想法。我其实不是太建议刚开始就组队,因为一般情况大佬不会愿意花过多成本带新人(要先进入大佬的眼,才有机会合作),而如果你找同水平新人组队,一个比赛切分几块去做的话,你可能会缺乏自我思考和失去熟悉整个比赛项目的机会。最后在自己参加一个比赛后,有个项目实施全貌,再考虑后期组队。建议一般是在组队截止前几天再找队友,把自己当前成绩和背景在比赛群交代好,基本都能找到队友。至于如何选择队友有几个方面要看:
a. 时间安排:双方时间能不能合理的安排在比赛上。
b. 已有成绩:当前比赛成绩?有想尝试的想法没?
c. 背景:学生/上班?主要还是时间安排上,另外有服务器资源没?专业背景?擅长?过往比赛经历?
d. 其它:外文阅读能力,代码能力,沟通能力等。

2. 参赛心得
虽然我参加的比赛不算太多,但确实打比赛能让疫情空闲的自己有更好的主观能动性,也让我结识了很多参赛者,我个人公号开始做的原由其实是为了让自己以后想要回顾当初比赛项目细节时,能方便我复盘。我公开比赛思路和代码的原因除了帮助个人复盘外,还有一个原因是想鼓励和监督自己能认真去记录这些知识点,因为很多时候,当你写给自己看和写给别人看时,是完全不一样的心态。开源会让自己在写代码时更注重代码的可读性,写思路分享时更注重实验细节的描述。虽然公号更新很少,但还是得到了很多朋友的支持。在参赛过程中,我刚开始主攻目标检测比赛,因为刚开始不了解,所以输入了很多论文和思路,并不断输出实践。但到后期就沉迷于调参,不太喜欢看外文文献或花一定时间研究一些在实现上比较复杂的思路,输入少而过分输出是很件不好的事,包括现在我写这篇比赛经验分享中,我也发现了有些知识点还不够深入,只是知其然而不知其所以然,后续我会陆续进行知识点扫盲。最后啰嗦一句,我开源的淘宝直播服装检索代码不是个合格的baseline方案(目标检测网络和检索网络没有实现端对端的训练),但考虑到部分数据预处理代码和EDA代码对一些参赛者可能有帮助,所以我还没在Github上关闭该仓库,近期我会关闭该项目避免误导更多人入坑。因为最近已开始入职培训了,可能会有很长一段时间不会对公号进行更新,希望大家谅解,祝各位学业或工作顺利。也在此感谢下比赛过程中帮助过我的朋友们,谢谢。

博客             :https://www.cnblogs.com/alvinai/
Github         :https://github.com/AlvinAi96
微信公众号  :zaicode
个人邮箱     :alvinai9603@outlook.com

参考文献:
[1] 阿里天池大赛项目:“数字人体”视觉挑战赛 - 宫颈癌风险智能检测诊断:
https://mp.weixin.qq.com/s/ZBeSjLa924h4l4MP0vTInQ
[2] Kesci大赛项目:2020年全国水下机器人(湛江)大赛 - 水下目标检测算法赛:
https://mp.weixin.qq.com/s/Mh8HAjIOVZ3KxWNxciq1mw
[3] 阿里天池大赛项目:天池新品实验室 - 淘宝直播商品识别:
https://mp.weixin.qq.com/s/06Ywh1YHROgyfomZ2836pg
[4] 目标检测和感受野的总结与想法:
https://www.cnblogs.com/pprp/p/12346759.html
[5] 天池CV赛事老司机,手把手带你入门目标检测赛题:
https://tianchi.aliyun.com/course/video?spm=5176.12282027.0.0.2be8379cwYiIGM&liveId=41141
[6] Kaggle X光肺炎检测比赛第二名方案解析 | CVPR 2020 Workshop:
https://mp.weixin.qq.com/s/X3JoTS3JqlT1uxFpChujRA
[7] mmdetection目标检测工具箱:
https://github.com/open-mmlab/mmdetection
[8] 两年三刷Pascal VOC最佳纪录,阿里图灵实验室怎样解决目标检测:
https://baijiahao.baidu.com/s?id=1652911649267060207&wfr=spider&for=pc
[9] Improved Regularization of Convolutional Neural Networks with Cutout:
https://arxiv.org/abs/1708.04552
[10] Bag of Freebies for Training Object Detection Neural Networks:
https://arxiv.org/abs/1902.04103
[11] Augmentation for small object detection:
https://arxiv.org/abs/1902.07296v1
[12] Poisson Image Editing:
https://www.cs.virginia.edu/~connelly/class/2014/comp_photo/proj2/poisson.pdf
[13] 【综述】图像去雾的前世今生:
https://mp.weixin.qq.com/s/SKJy8X5_UH8-W1yFRDQEoA
[14] Albumentations数据增强库:
https://github.com/albumentations-team/albumentations
[15] “数据引领飞粤云端” 2019广东工业智造创新大赛-决赛答辩直播 - 《布匹疵点智能识别赛道》:
https://tianchi.aliyun.com/course/video?liveId=41117 
[16] Accurate, Large Minibatch SGD: Training ImageNet in 1 Hour:
https://arxiv.org/abs/1706.02677
[17] WBF开源代码:
https://github.com/ZFTurbo/Weighted-Boxes-Fusion
[18] 知乎:你有哪些deep learning(rnn、cnn)调参的经验?:
https://www.zhihu.com/question/41631631
浏览 8
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报