返回列表

5th place solution: one-stage I3D with additional 2D model for bbox centers

412. NFL 1st and Future - Impact Detection | nfl-impact-detection

开始: 2020-11-16 结束: 2021-01-04 运动员表现 数据算法赛
第5名方案:单阶段I3D结合用于边界框中心的额外2D模型

第5名方案:单阶段I3D结合用于边界框中心的额外2D模型

作者:Ruslan Grimov | 比赛:NFL Impact Detection | 排名:第5名

感谢主办方,并祝贺所有获奖者!

以下是我的解决方案:

数据准备

视频被分割成形状为 8х224х224х3 的片段。作为正样本,我选择了包含撞击的帧及其前四帧和后三帧。使用固定步长的网格制作了大小为 224x224 的补丁。作为负样本,我选择了没有撞击的随机帧序列。此外,我还保存了每个帧序列的边界框位置和大小。

模型

从一开始,我就使用了 3D CNN,即来自 SlowFastI3D。我对其进行的唯一更改是在输入中添加了第四个通道,该通道对于第五帧始终为 1(不知道这是否有意义)。模型预测的是第五帧的边界框。然后,我附加了来自 pytorch_segmentation 的 FPN,具有六个输出通道且没有上采样。

来自主干网络第 2 到第 5 块的 3D 特征图使用 F.adaptive_avg_pool3d 转换为 2D 特征图,然后传递给 FPN。

FPN 生成大小为 6x56x56 的网格。网格的第一个通道负责网格特定单元格中是否存在边界框。接下来的四个通道负责边界框在网格单元内的位置和边界框的大小。最后一个通道预测单元格中是否存在撞击。所有这些预测仅针对八帧序列中的第五帧进行。总的来说,除了锚点之外,该网格类似于 YOLO 输出。

训练

第一阶段:在 224x224 补丁上训练

数据增强:

A.Compose([
            A.HorizontalFlip(p=0.5),
            A.OneOf([
                A.ColorJitter(p=1),
                A.HueSaturationValue(40, 60, 40, p=1),
                A.RGBShift(60, 60, 60, p=1),
                A.RandomGamma((20, 200), p=1)
            ], p=0.8),
            A.OneOf([
                A.GaussianBlur(p=1),
                A.GaussNoise((10.0, 50.0), p=1),
                A.MedianBlur(blur_limit=5, p=1),
                A.MotionBlur(p=1),
            ], p=0.6),
            A.ShiftScaleRotate(shift_limit=0.1, scale_limit=0.1, rotate_limit=0,
                            border_mode=0, p=0.4),
            # A.GridDistortion(p=0.2, border_mode=0),
        ])

损失函数

我有几种训练损失配置。HuberLoss 用作边界框位置和大小的损失。FocalBinaryLoss 或带有不同 pos_weight 参数的 nn.BCEWithLogitsLoss 用于预测边界框和撞击的存在。

调度器和优化器

使用带有默认参数的 Adam 和多阶段学习率衰减 10 倍。共进行了 10 个 epoch。

训练数据

对于每个 epoch,我选择所有正样本和 positive_count*2 个负样本。从第二个 epoch 开始使用难例挖掘。为此,我获取所有负样本的预测,并选择那些撞击置信度高于某个阈值(0.1)的样本。如果没有足够的难例,我会随机添加负样本。

第二阶段:在全图上训练

我冻结了主干网络,仅在大小为 8x3x720x1280 的全图上训练 FPN 几个 epoch。增强和优化器与第一阶段相同。

四个此类模型的集成在我的本地验证中得分为 0.48

然后我注意到头盔中心的检测效果不佳。它经常将护肩(我不知道确切叫什么)误认为是头盔,并给予其比某些头盔更高的置信度。

我认为这是因为边界框中心的真值数据仅包含点,而这些点并不总是位于头盔的中心,因此模型很难理解应该在哪里输出点。因此,我决定不使用边界框中心的点,而是预测直径等于边界框宽度和高度平均值的圆。这些圆向其边界逐渐消失。如图所示。