返回列表

10th place solution

346. Severstal; Steel Defect Detection | severstal-steel-defect-detection

开始: 2019-07-25 结束: 2019-10-24 缺陷检测 数据算法赛
第10名方案

第10名方案

作者: Aleksei Rozhkov
发布时间: 2019-10-26

总体方法

1) 针对不同的缺陷使用独立的模型(因为类别数量很少 - 这是可行的)

  • + 可以使用完全不同的架构/流程/采样器等
  • + 可以组合针对不同缺陷训练的模型,而不是重新训练单个模型
  • + 鼓励将问题(4缺陷检测)分解为更小的子问题(4个单缺陷检测)——这允许分别专注于完善它们,而不用担心破坏其他子问题的结果
  • + 更容易复用二值分割的代码
  • + 不需要平衡缺陷类别的损失
  • - 浪费宝贵的提交时间 → 可以集成的模型大小/数量较小
  • - 更多的训练时间
  • - 不同缺陷类型的检测器之间没有协同潜力

这样做是一个“贪心解”——我已经有二值分割的经验,我有点难过我错过了在这个比赛范围内学习更多新东西的机会。另一方面,这最大化了我获胜的机会,所以如果我必须再次做出决定——我会做同样的事情。

此外,我仍然可以在比赛结束后尝试用单个多缺陷模型来匹配/击败我当前方法的基准,尽管这样做的动力会减少 :)

2) 不预测缺陷2

  • + 更少的模型 → 更少的训练/研究/推理时间
  • + 尝试预测缺陷2总是会降低我的公共LB分数,所以不预测它 → 更高的分数
  • - 如果私有测试集包含更多带有缺陷2的图像实例——分数会下降

最初我打算只预测缺陷3和缺陷4,但在某个时候我在试图提高分数时碰壁了,并尝试预测缺陷1和缺陷2。令我惊讶的是,缺陷1带来了明显的分数提升,尽管不到理论可能值的一半,所以我决定保留它。另一方面,缺陷2甚至更加罕见,我一直无法从预测它中获得任何收益。无论如何,为了防止私有测试集中缺陷2更频繁的情况,我包含了一个针对缺陷2的模型,调整为仅在非常确信时才产生预测,并为此保留了第二个提交选择。比赛截止日期后,发现私有测试集似乎没有包含更多的缺陷2,但我认为这仍然是对第二次提交选择的合理使用。

3) 在全尺寸图像上训练

  • + 模型有更多的上下文 → 更容易做出正确的决定(避免假阳性/假阴性)
  • + 不需要在全图像上进行额外的微调阶段 / 如果不进行微调,域不匹配更少
  • - 需要更多的时间和GPU内存 → 实验更少,批量大小更小
  • - 模型看到的“独特”样本更少 → 更多的潜在过拟合

我也尝试过在裁剪图像和全尺寸图像上训练,在我所有的实验中,在裁剪图像上训练效果较差。我看到一些解决方案提到,当他们在裁剪带有缺陷的图像时,限制裁剪区域包含缺陷——这可能是正确训练裁剪图像的关键,但我没有尝试过。

4) 3折交叉验证

  • + 更大的验证集大小 → 更稳定的指标估计
  • + “相似度较低”的模型 → 集成更有益
  • + - 产生的模型更少 – 这没关系,因为反正我也受限于预测时间配额中能容纳的模型数量
  • - 更小的训练集大小 → 潜在的个体模型更弱
  • - 更长的验证时间

这对于避免本次比赛中排名剧烈波动可能很重要。考虑到我的验证集比公共测试集大2倍,我非常不愿意仅根据对公共排行榜分数的影响来做出关于解决方案的决定,并且只“信任”那些同时改善CV和公共LB的变化。

在某个时候,我开始担心反正我也在过拟合公共LB,因为向我的集成中添加更多模型降低了公共LB,这表明我的提交运气好,预测的小变化导致了公共LB的下降。我决定向验证集添加RandAugment类型(更多细节在增强部分),希望这样我会选择在不同条件下更稳健的模型/超参数,此外这将允许人工增加验证集的大小。

编码器

SE ResNeXt-50 / EfficientNet-b3,在ImageNet上预训练。第一个模型似乎仍然是大小/速度和准确性之间的良好权衡,而efficientnet相对较新,我想尝试将其用于分割任务。具有讽刺意味的是,它在PyTorch中的实现效率不是很高(至少与TensorFlow中的相比,见这个github issue)。这限制了其“放大”版本的使用,我选择了b3,它接近seresnext50,尽管我能够放入GPU内存的批量大小较小(3 vs 4),这可能会降低batchnorm的性能。

模型

尝试了来自 @pavel92 的优秀库

同比赛其他方案