一种在大规模细粒度图像检索中学习属性感知哈希编码的方法
一种在大规模细粒度图像检索中学习属性感知哈希编码的方法
A2-NET: Learning Attribute-Aware Hash Codes for Large-Scale Fine-Grained Image Retrieval (NeurIPS 2021)

**工作内容:**通过MindSpore框架完成细粒度哈希检索的任务。具体而言,在大规模图像检索要求下,如果通过实值检索,计算复杂度较高,而如果使用简短的二值哈希编码替代原有的实值编码进行图像检索,检索效率就可以大大提升。而现有的哈希方法中,其哈希值没有实际意义,因此希望通过属性提取的方式使得生成的哈希编码具有实际的特征含义。
文章摘要:我们的工作重点是处理大规模的细粒度图像检索,根据查询中的细粒度细节对描述兴趣概念(即相同的子类别标签)的图像进行排名。对于这样的实际任务,我们希望能够减轻细粒度特性(小的类间变化和大的类内变化)以及细粒度数据的爆炸性增长所带来的挑战。在本文中,我们提出了一个属性感知哈希网络(A2-NET)来生成属性感知哈希码,不仅使检索过程更加高效,而且建立哈希码与可视化属性之间的显式对应关系。具体地说,基于注意捕获的视觉表示,我们开发了一个重建任务的编码器-解码器结构网络,可以无监督地从外观特定的视觉表示中提取高级属性特定的向量,而不需要属性注释。网络还在这些属性向量上设置了特征去相关约束,以增强它们的表示能力。最后,由保留原始相似性的属性向量生成所需的哈希码。在五个基准细粒度数据集上的定性实验表明,我们的方法优于其他方法。更重要的是,定量结果表明,所获得的哈希码能够较强地对应细粒度对象的某些关键属性。
研究背景:
细粒度图像检索作为细粒度图像分析的重要组成部分,近年来得到了越来越多的关注。细粒度图像识别是计算机视觉和模式识别领域的基础研究课题,旨在研究对某一传统语义类别下细粒度级别的不同子类类别进行视觉识别任务,如不同子类的狗、不同子类的鸟、不同车型的汽车等……细粒度图像识别被计算机视觉国际权威学者、ICCV Helmholtz奖及Marr奖获得Serge Belongie教授称为“视觉感知嵌入的基石性工作”。由于细粒度图像中的物体对象在类间差异中只有细微的视觉差异,缺又在姿态、规模等类内差异上有较大的变化,因此有较大的检索难度。
哈希学习是通过机器学习的方法,将数据映射成二进制串的形式,能显著减少数据的存储和通信开销,从而有效提高学习系统的效率。哈希学习的目的是学到数据的二进制哈希码表示,使得哈希码尽可能地保留原空间中的近邻关系,即保相似性。具体来说,每个数据点会被一个紧凑的二进制串编码,在原空间中相似的两个点应当被映射到哈希码空间中相似的两个点。哈希方法大致分为两类,即数据无关方法和数据依赖方法。在数据无关的哈希方法中,模型中的哈希函数通常随机生成,且独立于任何训练数据,但检索性能的提高需要用哈希码的长度换取。数据依赖的哈希方法试图从一些训练数据中学习哈希函数,称为学习哈希算法。与数据无关的方法相比,学习哈希算法可以用更短的哈希码实现更高的准确性。因此,在实际应用中学习哈希算法比数据无关方法更流行。随着深度学习的兴起,一些学习哈希方法将深度特征学习集成到哈希框架中,获得了很好的性能。在以往的工作中,针对大规模图像检索,已经提出了许多深度哈希方法。与深度无监督哈希方法相比,深度监督哈希方法能够充分挖掘语义信息,获得更高的检索精度。
方法流程概述:

步骤1,通过卷积神经网络提取图像中的全局特征与局部特征信息;
注意力在人类的感知中起着非常重要的作用,它让我们着重关注一样事物或是场景的显著特征,因此我们在卷积神经网络中引入注意力机制,来获取图像的全局与局部特征以更好的表达每一幅图像的显著特征。具体而言,首先需要通过卷积神经网络提取输入图像_I_i_ 的深度特征:
![D}L9EGADA{G)G]_~]ZSA7O9.png](https://fileserver.developer.huaweicloud.com/FileServer/getFile/cmtybbs/b34/d51/b6b/37a742cae9b34d51b6bf7b00bff11321.20221201150141.34122638836982039754409940316252:50531206012831:2400:1A59EA6E99B751380981DC7F7A3482561C7F30508D606400E5482AEA4B40762B.png)
在公式(1)中得到的深度特征_T__i_ 的基础上,引入C个局部注意力引导模块,记为_A^{c} ,再引入一个全局注意力引导模块,记为_A_'_ ,图像局部特征输出为:
![$}_F]N}0Q4JY3MD_R~@0$J.png
图像的全局特征输出为:

其中_v_i 是k维的近似二进制编码,它是通过变换矩阵_W 得到的高度浓缩的图像特征表达向量,_u__i 则是最终得到的图像的二进制编码,即可以通过k位的比特信息表达整张图像的信息,大大压缩的检索空间。第一次激活tanh用以约束_v_i 的数值空间并使梯度可进行反向传播,第二次激活则将特征向量约束为汉明编码加快图像检索速度。假设有n个查询点{q__i_}_{__i=1}^n 以及m个数据库点{__v_j}_{__j=1}^_m ,那么哈希编码的损失可以记为:

特征解码器通过重构经过tanh激活后的哈希空间特征_v__i ,将属性特征复原并约束特征损失,记作:
![G54KNBQZA27R6597CYUB.png
其中_u_i,__z__j∈{-1, +1}^{k} ,S∈{-1, +1}^{n×m} 。
其中,X={x__1_;_ x__2; ...; x__n}∈R^{d×n} ,d表示每一个特征向量_x__i_ 的维度;W^T 代表重构矩阵,为哈希变换矩阵_W 的转置;V'__=tanh(V)_ ,V={v__1_;_ v__2; ...; v__n}∈R^{k×n} ,通过无监督的编码重构,可以引导哈希学习保留相对完整且重要的整体图像特征信息,使得每一维哈希空间中的信息特征进行重组后可以更全面的表达原图像中蕴含的信息。
步骤3,增强步骤2中哈希模块学习得到的每个维度属性的鉴别能力,去除每个维度属性特征之间的冗余相关性。
对步骤2中经过哈希变换矩阵并经过tanh激活得到的特征向量_v__'_ _[i}构建自正交损失,记为:
![3U@WR$~(2MHIN@$RQW%U.png
其中_I_ 为单位矩阵,这样可以消除每个维度空间学习到的属性特征的冗余相关性,使得每个维度的属性特征都有自己独特且完整的表达含义,即每一个哈希维度都可以表示一种深度的属性特征信息。
整体的约束损失可以记为:
![5LXSE@EYQ6WC9X]%D]Q3HC9.png](https://fileserver.developer.huaweicloud.com/FileServer/getFile/cmtybbs/b34/d51/b6b/37a742cae9b34d51b6bf7b00bff11321.20221201150903.87923041672466710755477159576243:50531206012831:2400:B7AE3C65E59ED5721B54750685131D6F84BE6AF8F597F3119F0F19E43877E0A5.png)
其中_α_ 与β 为引入的超参数,用于对齐量纲。
输入图像的二进制哈希编码输出可以记为:
MindSpore****实现
框架安装:
首先下载安装完整版的cuda
运行:sudo sh cuda_11.0.3_450.51.06_linux.run

然后安装完整版的cudnn:
至官网 https://developer.nvidia.com/rdp/cudnn-download 找到Download cuDNN v8.1.0 (January 26th, 2021), for CUDA 11.0,11.1 and 11.2

然后运行sudo dpkg -i 加上3个deb的文件名(分别运行即可)
最后到MindSpore找到对应版本pip安装即可:

模型主体代码MindSpore实现:
class A_2_net(nn.Cell):
def __init__(self, code_length=12, num_classes=200, att_size=4, feat_size=2048, pretrained=False,
finetune=False):
super(A_2_net, self).__init__()
self.backbone = A_2_net_backbone(pretrained=pretrained)
self.refine_global = A_2_net_refine(is_local=False, pretrained=pretrained)
self.refine_local = A_2_net_refine(pretrained=pretrained)
self.attention = A_2_net_attention(att_size)
self.finetune = finetune
self.hash_layer_active = nn.Tanh()
self.unsqueeze = ops.ExpandDims()
self.mul = ops.Mul()
self.normlize = ops.L2Normalize()
self.concat = ops.Concat(1)
self.linear = ops.MatMul()
self.W = ms.Parameter(Tensor(np.random.uniform(-1, 1, (code_length, (att_size + 1) * feat_size)), ms.float32), name="w", requires_grad=True)
def construct(self, x):
out = self.backbone(x)
batch_size, channels, h, w = out.shape
global_f = self.refine_global(out)
att_map = self.attention(out)
att_size = att_map.shape[1]
att_map_rep = self.unsqueeze(att_map, 2)
att_map_rep = att_map_rep.repeat(channels, axis=2)
out_rep = self.unsqueeze(out, 1)
out_rep = out_rep.repeat(att_size, axis=1)
out_local = self.mul(att_map_rep, out_rep).view(batch_size * att_size, channels, h, w)
local_f, avg_local_f = self.refine_local(out_local)
_, channels, h, w = local_f.shape
local_f = local_f.view(batch_size, att_size, channels, h, w)
avg_local_f = avg_local_f.view(batch_size, att_size, channels)
global_f = global_f.view(batch_size, channels)
avg_local_f = self.normlize(avg_local_f)
global_f = self.normlize(global_f)
all_f = self.concat((avg_local_f.view(batch_size, -1), global_f))
deep_S = self.linear(all_f, self.W.T)
binary_like_code = self.hash_layer_active(deep_S)
if self.finetune:
after_f = self.linear(binary_like_code, self.W)
return binary_like_code, all_f, after_f
else:
return binary_like_code
总结与展望:
本文提出了一种基于属性感知的哈希网络,即A2-NET,用于处理大规模的细粒度图像检索任务。A2-NET的设计预期是高效并可解释的。由于是第一次对哈希可解释方向进行探索,该文也存在一定的局限性。在未来工作中,由于视觉属性在描述已知和未知实体方面都很有用,因此我们希望进一步研究识别未观测到的子类别,即基于属性感知哈希码的零样本细粒度识别。在使用MindSpore框架进行模型训练时,需要注意网络中的Dropout层不会在验证阶段自动失效从而导致结果降低,需要预先进行设置。MindSpore框架在模型训练阶段中有更高的运行速度,可以更好的支撑大规模数据集的训练。