返回列表

20th place solution - maskrcnn-benchmark baseline

342. Open Images 2019 - Instance Segmentation | open-images-2019-instance-segmentation

开始: 2019-07-11 结束: 2019-10-01 计算机视觉 数据算法赛
第20名方案 - maskrcnn-benchmark 基线

第20名方案 - maskrcnn-benchmark 基线

作者:yu4u (Grandmaster) | 排名:第20名

感谢 Open Images 和 Kaggle 团队举办这场精彩的比赛,并祝贺所有(暂定)获奖者和奖牌获得者!

虽然我的成绩并不算突出,但这个方案可能值得分享,因为我直接使用了著名的 maskrcnn-benchmark 库,并且在使用其输出结果时没有进行 TTA(测试时增强)或任何后处理。使用 V100 8GPU 训练两个模型仅需 14 小时(x2)。

所有代码均可在 GitHub 上找到:https://github.com/yu4u/kaggle-open-images-2019-instance-segmentation

本次比赛和目标检测赛道主要需要解决两个问题:(1) 类别不平衡 和 (2) 类别层级结构。我仅在数据集创建阶段解决了这些问题。前者很容易处理:为每个类别使用固定数量的训练图像。在这篇文章中,我主要描述如何处理类别层级结构。

类别层级分组

首先,我将所有类别分为两组:layer0 和 layer1。从 challenge-2019-label300-segmentable-hierarchy.json 中我们可以看到:

  1. 层级结构的最大深度为 2(从 0 开始计算)
  2. 深度为 2 的类别只有 5 个。
Carnivore (食肉动物)
└── Bear (熊)
    ├── Brown bear (棕熊)
    ├── Polar bear (北极熊)
    └── Teddy bear (泰迪熊) <--- 你是认真的吗?

Reptile (爬行动物)
└── Turtle (海龟/龟)
    ├── Tortoise (陆龟)
    └── Sea turtle (海龟)

因此,我决定将深度为 0 的类别归为 layer0 组,将深度为 1 和 2 的类别归为 layer1 组。其思路是为这两个组分别建立不同的模型。

在训练每个模型时,使用专门的数据集,其中仅包含目标组类别的实例。这样做就无需关心类别层级结构了。

然而,实际上,仅从训练图像中制作仅包含目标类别且不包含非目标类别的数据集是不可能的。因此,我从训练图像中移除了非目标类别的实例。

数据处理细节

对于 layer0 组数据集:

  1. 移除遮挡目标类别对象 25% 或以上的非目标类别标注。
  2. 将非目标类别转换为其父类别(这样它就变成了目标类别。有些类别需要处理两次。'Teddy bear' 仅转换为 'Toy',而不是 'Carnivore')。

对于 layer1 组数据集:

  1. 移除遮挡目标类别对象 25% 或以上的非目标类别标注。
  2. 移除没有任何子类别的非目标类别标注(这对 layer1 组类别没有影响,因为它们之间没有关系)。
  3. 移除具有某些子类别的非目标类别标注,并在训练图像中将其边界框填充为灰色(仅移除标注不是个好主意,因为这会给模型带来“假假阳性”信号(损失))。

就是这样,开始训练吧!

同比赛其他方案