457. Google Landmark Recognition 2021 | landmark-recognition-2021
首先,我要感谢 Kaggle 工作人员和 Google 团队组织了 2021 年地标识别竞赛。我对自己的成绩感到非常惊讶和震惊,这使我登上了 Kaggle 总排行榜的第一名,这是许多 Kaggle 选手的终极目标。我的解决方案在检索和识别任务的模型和训练流程方面相似,但在细节上略有不同,尤其是在后处理(即重排序过程)方面。我试图向那些我从去年的解决方案中借鉴了聪明想法的人们表示感谢。对于识别赛道,我重用了 GLR2020 第二名解决方案和团队 All Data Are Ext 的第三名解决方案中的几个想法。如果我遗漏了谁,请评论指出。
我的解决方案是 DOLG 模型 [1] 和 Hybrid-Swin-Transformers 的集成,这两种架构都非常适合以单阶段的方式将地标的局部和全局描述符集成到单个特征向量中。我使用三步法训练模型,在每一步中扩大训练数据集和图像尺寸。对于主要处理非地标识别的后处理,我使用了与去年第一名识别解决方案相同的方法。
在深入细节之前,我想说明一下导致该解决方案的一些情况。首先,与去年相比,今年的比赛时间表明显更加紧张,这迫使我放弃了一些想法,专注于最有希望的方向。这特别导致我选择完全不考虑使用局部描述符进行空间验证,因为(至少在我看来)它的成本效益权衡很差,尤其是在内核运行时间有限的大规模图像识别中。其次,由于去年排名靠前的团队详细公开了他们的解决方案,大家都可以访问,因此超越的门槛相当高。为了命名一致,我对 gldv2 的子集使用以下定义:
此外,我用 GLRec 指代过去的 Google 地标识别竞赛,用 GLRet 指代检索。
我使用了与去年相同的交叉验证方案,即 2019 年标记的测试集,并且我的本地验证与 Public LB(公开排行榜)之间有很好的相关性。
我的训练流程遵循 GLRec 2020 第二名的训练数据集选择,但使用了 All Data Are Ext 的一些想法进行了改进。
作为第一步,我在干净的 gldv2c 上以较小的图像尺寸(例如 224x224)训练模型约 10 个 epoch。然后,我使用中大图像尺寸(例如 512x512)并在噪声较大的 gldv2x 上训练很长时间(30-40 个 epoch)。最后,我在大图像尺寸(例如 768x768)上也在 gldv2x 上微调几个 epoch。我在每一步都使用了 Adam 优化器和余弦退火学习率调度。我使用了与 All Data Are Ext 相同的数据增强,这被证明非常有效:
cfg.train_aug = A.Compose([
A.HorizontalFlip(p=0.5),
A.ImageCompression(quality_lower=99, quality_upper=100),
A.ShiftScaleRotate(shift_limit=0.2, scale_limit=0.2, rotate_limit=10, border_mode=0, p=0.7),
A.Resize(image_size, image_size),
A.Cutout(max_h_size=int(image_size * 0.4), max_w_size=int(image_size * 0.4), num_holes=1, p=0.5),
])
cfg.val_aug = A.Compose([A.Resize(image_size, image_size),])
对我来说,这是每场比赛中最有趣的部分,即设计和探索模型架构。我喜欢模型以端到端的方式解决问题的多个部分的想法。在地标识别中,利用全局和局部图像信息至关重要。虽然历史上这是通过两阶段方式解决的:一方面训练全局描述符进行初步识别,另一方面提取局部描述符使用空间验证进行后期重排序。最近,人们尝试使用单个模型同时训练局部和全局描述符(DELF/DELG)。但这仍然使用第二阶段的空间验证。
我实现了两种架构,将局部和全局描述