Kaggle第一人 | 详细解读2021Google地标识别第一名解决方案(建议全文背诵)(一)

本文涉及的产品
函数计算FC,每月15万CU 3个月
简介: Kaggle第一人 | 详细解读2021Google地标识别第一名解决方案(建议全文背诵)(一)

1简介


谷歌Landmark Dataset v2 (GLDv2)已经成为一个流行的数据集,用于评估用于解决大规模实例级识别任务的架构和方法的性能。原始数据集由超过500万张图片和超过20万个类组成。数据集还提出了一些有趣的挑战,如类的长尾分布、类内变动性和噪声标签。

2019年的获奖方案带来了GLDv2的清洁版本,这是一个子集,包含150万张图像,包含81313个类,将在下面用GLDv2c表示。此外,GLDv2x将用于表示GLDv2的子集,该子集被限制为GLDv2c中存在但未被清除的81313个类。

对于识别,是关于对一组测试图像中的地标进行正确分类,其中有大量的非地标被用作噪声数据。采用全局平均精度(GAP)作为度量指标进行评价。

对于检索,任务是在数据库中找到与给定查询图像相关的类似图像,并使用mean Average Precision@100 (mAP)进行评估。


2本文方法


2.1 DOLG模型

DOLG是一种用于端到端图像检索的信息融合框架(正交Local and Global, DOLG)。该算法首先利用多尺度卷积和自注意力方法集中提取具有代表性的局部信息。然后从局部信息中提取与全局图像表示正交的分量。最后,将正交分量与全局表示法进行互补连接,然后进行聚合生成最终的表征。

image.png

图1

基于ResNet50的DOLG模型的Pytorch实现如下:

class DolgNet(LightningModule):
    def __init__(self, input_dim, hidden_dim, output_dim, num_of_classes):
        super().__init__()
        self.cnn = timm.create_model(
            'resnet101',
            pretrained=True,
            features_only=True,
            in_chans=input_dim,
            out_indices=(2, 3)
        )
        self.orthogonal_fusion = OrthogonalFusion()
        self.local_branch = DolgLocalBranch(512, hidden_dim)
        self.gap = nn.AdaptiveAvgPool2d(1)
        self.gem_pool = GeM()
        self.fc_1 = nn.Linear(1024, hidden_dim)
        self.fc_2 = nn.Linear(int(2*hidden_dim), output_dim)
        self.criterion = ArcFace(
            in_features=output_dim,
            out_features=num_of_classes,
            scale_factor=30,
            margin=0.15,
            criterion=nn.CrossEntropyLoss()
        )
    def forward(self, x):
        output = self.cnn(x)
        local_feat = self.local_branch(output[0])  # ,hidden_channel,16,16
        global_feat = self.fc_1(self.gem_pool(output[1]).squeeze())  # ,1024
        feat = self.orthogonal_fusion(local_feat, global_feat)
        feat = self.gap(feat).squeeze()
        feat = self.fc_2(feat)
        return feat

1、Local Branch

Local Branch的2个主要构建模块是Multi-Atrous卷积层和Self-Attention模块。前者是模拟特征金字塔,可以处理不同图像实例之间的比例变化,后者是利用注意力机制进行建模。这个分支的详细网络配置如图2所示。

  • Multi-Atrous卷积模块包含3个空洞卷积,以获取具有不同空间感受野的特征映射和一个全局平均池化分支。
  • 将Multi-Atrous卷积输出特征cat起来,然后经过1x1卷积层处理。
  • 将输出的特征传递给Self-Att模块建模每个局部特征点的重要性。
  • 首先使用CNN(1x1)-BN模块对其输入进行处理
  • 然后通过1x1卷积层生成的注意力映射
  • 再通过SoftPlus操作以及L2-Norm对后续特征进行归一化

image.png

Local Branch的配置。“Ds, c, k”表示空洞率为s,输出通道数为c,kernel-size为k的空洞卷积。“c, c, k”表示输入通道为c,输出通道为c,kernel-size为1的普通卷积。“R”、“B”和“S”分别代表ReLU、BN和Softplus。

Local Branch的Pytorch实现
class MultiAtrous(nn.Module):
    def __init__(self, in_channel, out_channel, size, dilation_rates=[3, 6, 9]):
        super().__init__()
        self.dilated_convs = [
            nn.Conv2d(in_channel, int(out_channel/4),
                      kernel_size=3, dilation=rate, padding=rate)
            for rate in dilation_rates
        ]
        self.gap_branch = nn.Sequential(
            nn.AdaptiveAvgPool2d(1),
            nn.Conv2d(in_channel, int(out_channel/4), kernel_size=1),
            nn.ReLU(),
            nn.Upsample(size=(size, size), mode='bilinear')
        )
        self.dilated_convs.append(self.gap_branch)
        self.dilated_convs = nn.ModuleList(self.dilated_convs)
    def forward(self, x):
        local_feat = []
        for dilated_conv in self.dilated_convs:
            local_feat.append(dilated_conv(x))
        local_feat = torch.cat(local_feat, dim=1)
        return local_feat
class DolgLocalBranch(nn.Module):
    def __init__(self, in_channel, out_channel, hidden_channel=2048):
        super().__init__()
        self.multi_atrous = MultiAtrous(in_channel, hidden_channel, size=int(Config.image_size/8))
        self.conv1x1_1 = nn.Conv2d(hidden_channel, out_channel, kernel_size=1)
        self.conv1x1_2 = nn.Conv2d(out_channel, out_channel, kernel_size=1, bias=False)
        self.conv1x1_3 = nn.Conv2d(out_channel, out_channel, kernel_size=1)
        self.relu = nn.ReLU()
        self.bn = nn.BatchNorm2d(out_channel)
        self.softplus = nn.Softplus()
    def forward(self, x):
        local_feat = self.multi_atrous(x)
        local_feat = self.conv1x1_1(local_feat)
        local_feat = self.relu(local_feat)
        local_feat = self.conv1x1_2(local_feat)
        local_feat = self.bn(local_feat)
        attention_map = self.relu(local_feat)
        attention_map = self.conv1x1_3(attention_map)
        attention_map = self.softplus(attention_map)
        local_feat = F.normalize(local_feat, p=2, dim=1)
        local_feat = local_feat * attention_map
        return local_feat

2、Orthogonal Fusion Module

image.png

以和为输入,计算每个局部特征点在全局特征上的投影。在数学上,投影可以表示为:

image.png

其中,是点积运算,是的L2范数:

如图3所示,正交分量是局部特征与其投影向量的差值,因此可以通过以下方法得到正交于的分量:

这样,可以提取出一个C×H×W张量,其中每个点都与正交。然后,在这个张量的每个点上加上C×1向量,然后这个新的张量被聚合成的向量。最后,使用一个FC层来生成512×1的特征向量。

这里,利用池化操作来聚合cat的张量,也就是说,图4a中的“A”是当前实现中的池化操作。实际上,它可以被设计成其他可学习的模块来聚合张量。

Orthogonal Fusion Module的Pytorch实现
class OrthogonalFusion(nn.Module):
    def __init__(self):
        super().__init__()
    def forward(self, local_feat, global_feat):
        global_feat_norm = torch.norm(global_feat, p=2, dim=1)
        projection = torch.bmm(global_feat.unsqueeze(1), torch.flatten(
            local_feat, start_dim=2))
        projection = torch.bmm(global_feat.unsqueeze(
            2), projection).view(local_feat.size())
        projection = projection / \
            (global_feat_norm * global_feat_norm).view(-1, 1, 1, 1)
        orthogonal_comp = local_feat - projection
        global_feat = global_feat.unsqueeze(-1).unsqueeze(-1)
        return torch.cat([global_feat.expand(orthogonal_comp.size()), orthogonal_comp], dim=1)

相关实践学习
【AI破次元壁合照】少年白马醉春风,函数计算一键部署AI绘画平台
本次实验基于阿里云函数计算产品能力开发AI绘画平台,可让您实现“破次元壁”与角色合照,为角色换背景效果,用AI绘图技术绘出属于自己的少年江湖。
从 0 入门函数计算
在函数计算的架构中,开发者只需要编写业务代码,并监控业务运行情况就可以了。这将开发者从繁重的运维工作中解放出来,将精力投入到更有意义的开发任务上。
相关文章
|
机器学习/深度学习 数据可视化 数据库
Kaggle第一人 | 详细解读2021Google地标识别第一名解决方案(建议全文背诵)(二)
Kaggle第一人 | 详细解读2021Google地标识别第一名解决方案(建议全文背诵)(二)
359 0
|
机器学习/深度学习 数据挖掘 计算机视觉
Google新作 | 详细解读 Transformer那些有趣的特性(建议全文背诵)(二)
Google新作 | 详细解读 Transformer那些有趣的特性(建议全文背诵)(二)
296 0
|
机器学习/深度学习 数据可视化 计算机视觉
Google新作 | 详细解读 Transformer那些有趣的特性(建议全文背诵)(一)
Google新作 | 详细解读 Transformer那些有趣的特性(建议全文背诵)(一)
268 0
|
数据可视化 定位技术 Sentinel
如何用Google Earth Engine快速、大量下载遥感影像数据?
【2月更文挑战第9天】本文介绍在谷歌地球引擎(Google Earth Engine,GEE)中,批量下载指定时间范围、空间范围的遥感影像数据(包括Landsat、Sentinel等)的方法~
4910 1
如何用Google Earth Engine快速、大量下载遥感影像数据?
|
编解码 人工智能 算法
Google Earth Engine——促进森林温室气体报告的全球时间序列数据集
Google Earth Engine——促进森林温室气体报告的全球时间序列数据集
273 0
|
编解码 人工智能 数据库
Google Earth Engine(GEE)——全球道路盘查项目全球道路数据库
Google Earth Engine(GEE)——全球道路盘查项目全球道路数据库
367 0
|
编解码
Open Google Earth Engine(OEEL)——matrixUnit(...)中产生常量影像
Open Google Earth Engine(OEEL)——matrixUnit(...)中产生常量影像
225 0
Google Earth Engine(GEE)——导出指定区域的河流和流域范围
Google Earth Engine(GEE)——导出指定区域的河流和流域范围
782 0
|
传感器 编解码 数据处理
Open Google Earth Engine(OEEL)——哨兵1号数据的黑边去除功能附链接和代码
Open Google Earth Engine(OEEL)——哨兵1号数据的黑边去除功能附链接和代码
420 0

热门文章

最新文章