Kaggle 比赛记录之 SIIM-ACR Pneumothorax Segmentation

记事

​ 随着 Kaggle: SIIM-ACR Pneumothorax Segmentation 接近尾声,我感觉有必要写一篇 blog 来记录一下这两个月的比赛经历,顺便总结一下经验。

​ 刚开始的时候想着这不过是一场普通CV类的比赛而已,肝一肝就能上金牌。但现实狠狠地打了我的脸。最初三天看了看比赛规则,了解了下RLE等语义分割的基本概念,看了看各路大佬的EDA,算是入了个小门。随后就一直沉沦在MMDetection和COCO格式的配置中,由于网上资料太少太旧,导致我花了整整15天才把程序跑通orz,还是在各路大神的帮助下。详情可参考另一篇博客:使用MMDetection进行语义分割。最后出的结果也非常地不尽人意,分数才 0.6+,而把所有预测结果全填上 -1 都有 0.78 分,着实难搞😑。

​ 中间一个月基本在走亲访友旅游摸鱼,直到八月中旬回学校,才重回赛场,放弃了MMDetection,找了个比较高分的PyTorch baseline,开始调参,也算是为这场比赛正式拉开了序幕(虽然只剩半个月了)。

Baseline细节:

  • 网络模型:UNet + ResNet34,使用imagenet进行预训练
  • 输入图片尺寸:512 * 512 (为了更加贴近模型预训练时使用的图片尺寸)
  • 训练集:验证集 = 4:1,使用 sklearn 中的 StratifiedKFold 进行五折划分
  • 在验证集和训练集中,正负样本数量1:1
  • 学习率策略:ReduceLROnPlateau
  • Loss:Focal Loss & Dice Loss
  • 优化器:Adam
  • 最优模型选择:根据Loss的值进行选择,loss越小模型越优
  • 生成结果时,单个分割区域的最少像素数:min_size == 3500
  • 输出:1024*1024 的概率矩阵(因为原数据图像大小是 1024*1024),每个元素对应像素点属于 mask 的概率。最后用一个 sigmoid 函数生成 mask

虽然是个分数挺高的 baseline,但还是有一些瑕疵:

  • 某行代码的 ‘!=’ 写成了 ‘==’
  • Trainer 类里的部分属性与下面传入函数的参数不是同一个变量,导致改了属性后传入的参数依然没改
  • 验证时没有加 with torch.no_grad() 导致显存溢出
  • 对数据去重的时候把单图多分割区域给删成了单图单分割区域

改完上述问题后单 resnet34 分数能上 0.84+。

​ 改完 bug 后第一步,把模型换成 SENet154 😏,单折 0.855 左右,好像海星的亚子。

​ 随后又测了 SE_ReNeXt101、EfficientUNet_B5、DPN131、DenseNet201、DenseNet121等模型,但只有 EfficientUNet_B5 能跟 SENet154 不相上下,而其他模型基本跟 ResNet34 差不多。

​ 对 SENet154 进行五折交叉验证,分数提高到 0.863。

​ 对 EfficientUNet_B5、ResNet34、SENet154 三模型进行等比例融合、min_size == 3000,分数提高到 0.869。同时 EfficientUNet_B5、SENet154 双模型 、min_size == 2800,分数提高到 0.868。

​ 使用 EfficientNet 单独进行二分类,将二分类中的负样本对应的预测样本替换成负样本,结果不理想,大概多模型融合后的分类能力已经很强了。

​ 对 EfficientUNet_B5、ResNet34、SENet154、SE_ReNeXt101 四模型按 3:2:3:2 的比例进行融合,min_size == 3000,分数提高到 0.8694。

​ 与此同时的另一边使用了 chexnet 进行二分类,将二分类的正样本对应的三模型预测样本的min_size降低到2500,负样本保持3000,将三模型的分数也提升到了 0.8694 。在 public leaderboard 排行60名,位于银牌区。

​ 可是离金牌还有 0.01 分的差距,光是这样调参怕是很难上金牌😪 —— 2019.8.28

​ 比赛进入第二阶段,更换了测试集。以新测试集的 1% 数据的成绩作为公榜成绩,剩下 99% 作为最终成绩。—— 2019.8.31

盲区

FocalLoss和diceLoss的实现细节和应用场景

Unet、Unet++、FastRCNN、MaskRCNN、FPN、DCN、Cascade、SENet、efficientNet的技术细节

学习率的相关优化算法及应用场景,如ReduceLROnPlateau、warm up

threshold的调整策略

PyTorch实战经验不足,baseline的自主编写

新兴模型复现

疑问

  • Q:为什么将训练集中的正负样本划为1:1能提高分数?

    A:能避免模型分类时倾向某一方,减少在分类时出现的错误。

  • Q:代码中最佳模型的评判标准为什么不是iOU而是loss?

    A:因为比赛分数的评判标准是Dice Loss

  • Q:每次五折验证的选择是否相同?

    A:是。StratifiedKFold在随机种子不变的情况下,每次五折交叉验证选择的样本都是相同的。

改进

下次比赛一定要记录每个模型提交的参数、文件和分数啊啊啊啊,不然最后多模型融合的时候不知道如何分配权重

通过对比两份分数的高低和csv的差别,是否能确定哪些预测是对的(好像有点场外)

下次比赛要从头跟到尾,这样能尝试到更多的tips和参数

高分 Solution

1st place solution

2rd place solution

3rd place solution

4th place solution

5th place solution

  • 基于半监督学习,在网络添加了二分类器。
  • 网络模型:带有 ASPP 结构的 UNet(ASPP 为 DeepLabV3+中的一种结构)
  • Backbone:se50 & se101
  • 图片尺寸:1024*1024
  • 优化器:Adam
  • 损失函数:1024 * BCE(results, masks) + BCE(cls, cls_target)
  • 半监督学习:mean-teacher[1-2] with NIH Dataset

mean-teacher 参考资料:

[1] https://github.com/CuriousAI/mean-teacher
[2] https://arxiv.org/pdf/1703.01780.pdf

6th place solution

  • 网络模型
    • EncodingNet (ResNets, 512 and 1024 size)
    • UNet (EfficientNet4, se-resnext50, SENet154 with 512, 640 and 1024 sizes)
  • 数据增强:Crops 和 Rotations 类型的增强
  • 损失函数:BCE + Dice (表示FocalLoss不太好用)
  • 比起原始尺寸的图像,小尺寸图像会少很多分
  • Tricks:
    • 在 EncodingNet 使用了 11 种 TTA
    • 删除了预测结果种面积小的mask

8th place solution

  • 数据分割:10%分出来用于融合(ensemble),在剩下90%的数据里进行十折交叉验证
  • 模型架构:DeepLabV3
  • Backbone:使用了组归一化的ResNet50/101 和 ResNeXt50/101
  • 损失函数:BCE(在所有图像上训练)或者 Dice(只在正样本上训练)
  • 优化器:Vanilla SGD, momentum 0.9
  • 训练:
    • batch size 4, 1024 x 1024
    • batch size 1, 1280 x 1280
  • 学习率策略:余弦退火,LR 0.01-0.0001
  • 模型融合:
    • 4 个模型使用 Dice 损失函数,在正样本上训练
    • 8 个模型使用 BCE 损失函数,在所有样本上训练。其中四个作为分类器使用
    • Max pixel value was taken as classification score, averaged across 4 models
    • Multiplied pixel-level scores from 4 models trained on positives only by this classification score, then averaged
    • Final ensemble: multiplied score as above averaged with pixel-level scores based on other 4/8 models trained on all images
  • TTA:Hflip
  • 后处理:删除了大小小于2048像素的mask(stage2),stage1中为4096像素

没起到效果的工作:

  • 使用了Unet, LinkNet, PSPNet, EncNet, HRNet等架构,但效果没有DeepLab好
  • SGD 的效果比 Adam, Adabound 优化器的效果更好
-------------本文结束感谢您的阅读-------------