483. Happywhale - Whale and Dolphin Identification | happy-whale-and-dolphin
这是我第一次参加 Kaggle 比赛,非常幸运地获得了第一名!!!!
我非常感谢我的队友 @charmq!
我们非常享受这次比赛,并且一直努力到最后一刻。我们要深深感谢 Kaggle 工作人员组织了这场精彩的比赛,也感谢其他团队与我们竞争。
我们的解决方案基于带有动态边距的子中心 ArcFace(sub-center ArcFace with Dynamic margins),这在 @boliu0 的 Google Landmark Recognition 2020 第三名解决方案和 @christofhenkel 的 Google Landmark Recognition 2021 第一名解决方案中被证明是有效的。
基本上,我们的解决方案是由 @charmq 和我实现的两个流程的集成。由于我们在比赛期间互相分享知识,我们的流程有很多共同点。下面,我将主要解释我的流程,它在 CV 分数上略好一些。
我们使用了几种类型的边界框来裁剪图像。非常感谢 @jpbremer 和 @phalanx 提供了宝贵的数据集。我们还使用全身标注训练了自己的 yolov5 模型,我们将其称为 fullbody_charm。
对于训练数据,我们按 fullbody:fullbody_charm:backfin:detic:none = 0.60:0.15:0.15:0.05:0.05 的比例随机混合了几种边界框。特别是,将背鳍边界框结合到训练数据中显著提高了性能,可能是因为它增强了对仅包含背鳍图像的鲁棒性。以较小的比例添加未裁剪的图像也起到了正则化的作用。对于测试数据,我们取了 fullbody 和 fullbody_charm 之间预测的平均值。
我们将裁剪后的图像调整为固定大小。我们主要使用的图像大小为 (1024, 1024)。为了集成,一些模型使用了 (1200, 1200) 和 (1440, 1440) 的图像大小进行训练。
我们训练了几个不同的 imagenet 预训练骨干网络进行集成(efficientnet_b5, efficientnet_b6, efficientnet_b7, efficientnetv2_m, efficientnetv2_l 等)。单模型的最佳性能是由 efficientnet_b7 实现的。
使用 GeM 池化 (p=3) 代替 GAP 提高了性能。
ArcFace 头之前的归一化层很重要。在我们的实验中,Batchnorm 略好于 Layernorm。
除了骨干网络的最终特征图外,我们还使用了倒数第二层特征图来捕获更多的局部信息。我们简单地将这两个 GeM 池化后的特征图连接起来并传递给头部。
为了处理类别不平衡,我们采用了带有动态边距的 ArcFace。由于它似乎对超参数很敏感,我们在 (256, 256) 的图像和 efficientnet_b0 上使用 Optuna 对其进行了调整。看来获得的超参数在大型图像和架构上也效果良好。
在上一次比赛中,据报道将翻转图像作为不同类别处理显著提高了性能。在这次比赛中,我们认为这种技术效果不佳,因为有些图像是从不同角度拍摄的。为了处理这个问题,我们采用了 k=2 的子中心 ArcFace 配合通常的翻转数据增强。
我们还添加了第二个头部用于物种分类。带有动态边距的子中心 ArcFace 比简单的线性头部效果更好。
虽然我们主要在本地检查单折验证分数,但我们使用整个训练数据训练模型以进行提交。
将头部的学习率设置为骨干网络