返回列表

Step by step (9th place solution)

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

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

Step by step (第9名方案)

作者: Jacek Poplawski | 比赛: Severstal: Steel Defect Detection | 排名: 9th

这将是一个很长的故事(就像我之前在 Porto Seguro 比赛中做的那样),所以给自己冲杯咖啡慢慢看吧 :)

过早优化是万恶之源

这次比赛的目标是什么?在我看来,目标是预测特定图像和特定缺陷类型的掩码。这就是数据的构建方式——一行数据是图像和缺陷类型的组合。

但出于某种原因,(几乎)每个人都认为目标是构建一个从一张图像预测4个掩码的模型。你可能认为这没什么区别,我会解释为什么我认为这很重要。

两个月前,我想构建4个分类模型和4个分割模型——每个类别一个。在这个帖子里,@phoenix9032 提出了三种流水线策略。请看策略2。

我们一致认为我们需要某种分类器。为什么我们需要它?它应该做什么?分类器以图像为输入,预测该类别存在缺陷的概率。我们该如何利用这些信息呢?

我们可以在分割之后使用这些信息,以此说明分割是无意义的。但在这种情况下,最初开始分割的理由是什么?我们只有1小时的时间来预测所有内容。

所以我们需要在分割之前使用这些信息。当分类器预测存在特定缺陷时,我们可以调用分割;如果没有,我们可以跳过分割以节省时间。但是等等——如果你的分割模型是一次预测4个掩码,你就不需要关于缺陷类型的信息,因为只要至少有一种缺陷可能存在,你就会调用分割。

但是,如果你构建一个有4个输出的单一分类器,然后针对缺陷使用单独的分割模型呢?那么你只需要对概率较高的缺陷类型执行分割。

你如何选择哪个模型是最好的?当然是指标最好的那个,对吧?但是如果你平均了4种缺陷,你怎么知道哪个模型指标最好?如果我告诉你预测每个掩码是独立的任务呢?当你把比赛分成4个不同的部分时,你可以独立处理每一部分——这使得解决方案更加稳定——然后你甚至可以在排名波动中生存下来。

这还不是全部。如何处理类别不平衡?我读到很多帖子说人们无法预测第1类和第2类。有些人放弃了第2类。在我的方案中,每个类别都是单独训练的。在不同的训练数据上。

你可以假设相反的情况——即预测缺陷不是独立的任务,没有像素同时具有两种不同的缺陷,所以你可能会说一次预测所有缺陷的模型更聪明。比如5类的softmax(我没时间尝试)。但是在预测掩码之后、保存提交文件之前,你在做什么?你在执行某种后处理——然后如果缺陷太小你可以完全移除它。这同样是针对每个类别独立的。

指标

很快我意识到指标有些不对劲。我不确定,也许我的想法有误——感谢 @zavareh89 的确认。

“排行榜分数是测试集中每个 ImageId、ClassId 对的 Dice 系数的平均值。”

这意味着比赛的分数是针对每张图像和每种缺陷类型分别计算的。因此,如果真实掩码是零像素,而你预测了零像素——你得分为1,但如果你预测了至少一个像素——你的得分为0。过滤掉空掩码至关重要。

Kernels 中使用的默认指标(至少在 keras kernels 中)获取整批图像,将四个掩码一起展平。然后在一维数组中计算交集和并集。在这种情况下,如果你展平所有图像和所有掩码,真实掩码何时是零像素?只有当批次中所有图像的所有4个掩码都为空时——这是罕见的情况。这个指标完全错了。

损失函数

如果我从 TGS Salt 比赛中学到了什么,那就是 Lovasz loss。

二元交叉熵的问题在于它在开始时有效,但随后损失在下降,指标却没有提升。Lovasz loss 对分割更好,但它需要一个好的模型作为起点,因为训练较慢。

我测试了 lovasz_hinge 和 lovasz_softmax。

所以正确的工作流程是:

  • 使用 BCE 训练
  • 选取最佳模型(使用指标而非损失!)
  • 使用 lovasz_hinge 训练

这总是有效的。

分割模型

感谢 @cdeotte 提供的关于如何使用分割模型的信息

感谢 @bibek777 提供的关于 EfficientNet 的信息

当然感谢 @pavel92 创建了 segmentation models 库 :)

起初我使用带有 resnet34 的 unet。然后我尝试了不同的网络——resnet50、densenet 等……但性能较低。然后我尝试了 efficientnet,终于变好了。

我在比赛结束时仍使用 resnet34 作为分类器,但对于分割,我切换

同比赛其他方案