461. NFL Health & Safety - Helmet Assignment | nfl-health-and-safety-helmet-assignment
恭喜获奖者,并感谢 @robikscube 举办这次比赛。这真是一场有趣的比赛。我们以这个notebook为起点并不断改进,最终获得了第4名。
我将逐步解释解决方案的流程:
训练我们自己的模型比使用基线头盔效果更好,因为我们可以使用视频图像进行训练,并且可以控制检测参数。
merge_asof 逻辑,以将轨迹映射到头盔。在最后几天,我用自定义跟踪替换了 deepsort。它在 Public LB(公开排行榜)上的得分明显更低(我没有时间也没有希望测试其验证性能),因此我们忽略了它,但结果证明它是我们最好的 Private LB(私人排行榜)提交。总之,它使用头盔相似度得分和 IOU 得分一起来跟踪头盔,而不是阈值化的逐步方法。其特征提取器模型是在 ArcFace 团队检测模型中训练的。
我暂时跳过这部分。@rytisva88 可以更好地解释这部分,因为是他负责这部分工作。

虽然球衣号码并不总是可见,但当它们清晰可见时我们仍然可以利用它们。通过裁剪头盔周围的区域,我创建了一个球衣号码数据集。我训练了一个带有 resnet34 骨干网络的双头模型(每个数字一个头)。尽管 resnet34 很小,但在仅仅2个 epoch 内仍然很容易在这个数据上过拟合。因此需要一些数据增强:
鉴于噪声的存在,该模型没有很高的召回率,但具有很高的精确率。而且只有约22名球员(球衣号码)可用,这有助于模型排除不可能的球衣号码。当模型确信时,2D 映射的标签会被球衣号码模型的预测覆盖。

对于每一帧 f 中的每个头盔 h,我计算其在簇 c 内拥有的每个标签预测的分数:np.log1p(conf[c][label])*conf[c][label]/conf[c].sum()
一帧内所有可能的头盔-标签匹配根据该分数排序。然后从最高分开始逐一分配,且同一标签不会被分配两次。
在聚类集成之后,我们可能有一些头盔没有分配到任何标签。为了覆盖这些情况,我在每一帧内拟合了一个线性回归模型,以头盔的 left 和 top 为目标,以跟踪数据的 x, y 为点。所以模型是在这两个2D空间之间进行映射。
我使用模型估计值和头盔 left、top 值创建了一个距离矩阵。如果我们直接使用这个距离矩阵,其性能非常接近仅做2D映射。因此,对于来自聚类集成的每个(标签,头盔)对,我减去 100*match_score 以使矩阵偏向聚类集成的输出。然后进行贪婪最小距离分配,所有头盔都获得了一个