行人重识别—Relation-Aware Global Attention模型介绍及代码实现

一、RGA关系感知全局注意力模型概述

RGA关系感知全局注意力中国科学技术大学和微软亚洲研究院在2020年CVPR提出的一篇基于全局注意力的行人重识别文章。行人重识别(re-ID)的目的就是在一个或者多个摄像机拍摄的不同场合下去匹配特定的人。通常给定输入图像,我们使用卷积神经网络来获取特征向量。再识别是通过匹配图像特征向量来找到具有相同身份的图像(基于特征距离)。对于CNN,注意力通常是局部卷积学习到的,而局部卷积会忽略全局信息和隐藏信息的关系。文章提出有效的关系感知全局注意力(RGA)模块使CNN能够充分利用全局的相关性来推断注意力。通过全局考虑特征之间的相互关系来确定注意力,对于每一个特征节点,通过堆叠关于该节点的成对关系和特征本身,提出了一种紧凑的表示。将RGA模块应用于空间和通道维度并且进行组合可以得到更好的效果

二、RGA整体网络架构—如何利用网络进行预测

行人重识别(re-ID)系统通常的做法就是通过主干特征提取网络(文章中采用了ResNet50)输入图像的特征向量表示,然后基于距离来进行图像匹配找到具有相同身份的图像。而本文的关系感知全局注意力模型是将特有的RGA模块应用于ResNet50主干网络,然后得到图像的特征向量表示。具体做法,就是在ResNet50的每一个残差块即res_layer1,res_layer2,res_layer3,res_layer4之后添加RGA模块,RGA模块包含了基于空间RGA-S和通道维度RGA-C的注意力机制。RGA网络的具体实现如下图所示:
在这里插入图片描述
需要注意的是,ResNet50的res4_layer中的最后一个空间下采用操作被删除,我们将其步长stride设置为1。

1、主干特征提取网络—ResNet50

ResNet残差网络有两个最主要的基本块,我们称之为Conv Block和Identity BlockConv Block和Identity Block的结构如下:


图片转自https://blog.youkuaiyun.com/weixin_44791964/article/details/104629135。

可以看到在Conv Block中,输入input在左右两边进行的操作的是不一样的,左边先进行了两次卷积块,一次卷积块即Conv+BN+Relu,然后又进行了Conv+BN的操作;而右边只进行了一次的Conv+BN;最后是将两边的输出进行相加Add和Relu激活函数操作;在Conv Block输入和输出的shape可以是不一样的,因此Conv Block是不可以连续的串联,它是用来改变网络的维度;而Identity Block中的左边的操作和Conv Block是一样的,而右边输入input不进行任何的操作,因此在Identity Block中输入和输出的shape是一样的,可以进行连续多次的串联,用于加深网络的深度ResNet网络就是由Conv BlockIdentity Block不断重复,ResNet网络不仅能达到很深,而且每次Block提取到的特征总是不比原来差!!!

具体ResNet50特征提取代码如下:

		# Networks
		self.conv1 = nn.Conv2d(3, 64, kernel_size=7, stride=2, padding=3, bias=False)
		self.bn1 = nn.BatchNorm2d(64)
		self.relu = nn.ReLU(inplace=True)
		self.maxpool = nn.MaxPool2d(kernel_size=3, stride=2, padding=1)
		self.layer1 = self._make_layer(block, 64, layers[0])
		self.layer2 = self._make_layer(block, 128, layers[1], stride=2)
		self.layer3 = self._make_layer(block, 256, layers[2], stride=2)
		self.layer4 = self._make_layer(block, 512, layers[3], stride=last_stride)
	
	# 残差卷积块的具体实现	
	def _make_layer(self, block, channels, blocks, stride=1):
		downsample = None
		if stride != 1 or self.in_channels != channels * block.expansion:
			downsample = nn.Sequential(
				nn.Conv2d(self.in_channels, channels * block.expansion,
						  kernel_size=1, stride=stride, bias=False),
				nn.BatchNorm2d(channels * block.expansion),
			)

		layers = []
		layers.append(block(self.in_channels, channels, stride, downsample))
		self.in_channels = channels * block.expansion
		for i in range(1, blocks):
			layers.append(block(self.in_channels, channels))

		return nn.Sequential(*layers)

2、RGA Module 关系感知全局注意力模块

为实现注意力,就要对特征的重要性有很好的认识,要对其进行客观评估。因此,全局信息至关重要,提出的关系感知全局注意力模块,能够充分利用结构的相关信息。

通常对于具有d维的N个相关特征的特征集
v={xi∈\inRd,i=1,…,N},我们的目标是学习一个mask,其有a=(a1,…,aN)∈\inRN表示N个特征的权重,根据它们的重要性进行加权,更新第i个特征向量为zi=ai*xi。要学习第i个特征向量的注意力值ai,有两种常见的策略,如下图(a)和(b)。

(a)局部注意力:每个特征都决定其局部注意力,例如对自身使用共享变换函数Γ\GammaΓ,即ai=Γ\GammaΓ(x)。这种局部策略不能完全利用与其它特征的相关性。关于全局注意力,一种方式就是使用更大kernel size的卷积使注意力的学习更加全局化;

另一种方式,如图(b):通过全连接的操作共同学习注意力。但是这通常在计算上很昂贵,并且需要大量的参数,尤其是当特征数量N较大时。

本文提出的关系感知全局注意力,如图( c )所示。其主要思想就是利用与第i个特征相关的成对关系(例如,相似性),来表示该特征节点的全局结构信息。特别地,使用Ri,j表示第i个特征和第j个特征之间的相似性。则对于第i个特征xi,其相似性向量为Ri=[Ri,1,…,Ri,N,R1,i,…,RN,i]。如何理解该Ri,Ri,1,…,Ri,N表示的是第i个特征与其它特征之间的关系,而R1,i,…,RN,i则表示的是其它特征与第i个特征之间的关系。听上去感觉有点重复?但是论文中解释这样加上去效果会好,而我自己的理解就是,“我(i)认为我跟别人(1,…,N)是好朋友,但是别人(1,…,N)却不一定认为跟我(i)是好朋友”,即Ri,1,…,Ri,N和R1,i,…,RN,i表示的相似性可能是不同的
在这里插入图片描述

1、Spatial Relation-Aware Attention 空间关系感知注意力—RGA-S

通过CNN层得到的特征图为的shape为HWC,设计的RGA-S空间关系感知注意力来学习大小为H*W的空间注意力图,取每个空间位置的C维特征向量作为特征节点。所有的空间形成位置形成一个有N=WxH个节点的图形,通过建立空间中节点之间的相似性矩阵,即NxN的矩阵,来表示节点之间的成对关系。
RGA-S的实现如下图所示:
在这里插入图片描述
为了方便解释RGA-S如何具体实现,我们以经过第一个残差块res1_layer的RGA-S1为例来给予说明,其它的RGA-S实现于此一样,只不过是特征图的H和W不一样而已。经过数据增强输入图片的shape为3x256x128,首先经过Zeropadding,然后是步长stride=2的卷积块(Conv+BN+Relu),得到的shape为64x128x64,再经过stride=2的MaxPooling,得到的shape为64x64x32,经过残差网络的第一个残差块,其中的卷积步长stride=1,得到res1_layer的shape为256x64x32,作为RGA-S1的输入。

RGA-S1的输入input为256x64x32,两个去向,如上图所示,一个是向右做embedding操作,即嵌入全局信息。具体做法是经过一个1x1卷积进行降维,将通道数减少为 256/8 =32,得到g_xs,此时shape为32x64x32,由于我们需要实现的是空间注意力机制,因此沿着通道数方向,进行mean求平均操作,将64维通道数使用其均值进行替代,此时g_xs的shape维1x64x32。第二个去向向下的操作,首先经过一个1x1卷积进行降维,将通道数减少为 256/8 =32,此时shape为32x64x32,记为theta_xs;进行了两次这样的操作,另一个记为phi_xs,shape同样为32x64x32。然后我们将theta_xs和phi_xs进行reshape操作,reshape为32x(64x32)=32x2048,然后再将theta_xs经过一次维度的调换permute,故此时的shape为2048x32,而phi_xs的shape为32x2048,于是将theta_xs和phi_xs进行矩阵的乘法,得到Gs,shape为2048x2048,至此Gs表示的就是该特征图空间中2048个特征节点之间的成对关系。首先找到我和别人的成对关系,将Gs进行reshape操作得到Gs_out,shape为 2048,64,32。其次,找到别人和我之间的成对关系,于是将Gs进行维度调换permute操作,得到的shape为2048x2048,再进行reshape操作得到Gs_in,shape为2048,64,32,进行关系对的堆叠cat操作,得到Gs_joint,shape为2048+2048=4096,64,32,然后再将Gs_joint进行1x1操作将4096浓缩成2048/8=256, 使用256维来代表空间成对关系,此时Gs_joint的shape变为256,64,32。于是,将全局的信息与空间中特征点之间的关系进行堆叠操作,得到ys,shape为257,64,32,再将关系维度使用1x1卷积进行浓缩,先将维度压缩成257/8=32,再使用1x1卷积压缩为1,shape为1,64,32,即我们得到了1个特征图上空间中特征节点之间的关系,输入input的shape为256,64,32,我们直到空间中的特征节点在即使在不同的特征图中其位置是不变的,于是我们将上述得到的一个特征节点关系特征图进行repeat操作,得到256个关系特征图,shape变为1,64,32->256,64,32,然后求sigmoid,转化为0-1之间的概率值,最后于输入input进行相乘操作,得到最后的输出256,64,32,即输出带有空间注意力的特征节点值。

空间关系感知全局注意力的具体代码实现如下:


		if self.use_spatial:
			self.gx_spatial = nn.Sequential(
				nn.Conv2d(in_channels=self.in_channel, out_channels=self.inter_channel,
						kernel_size=1, stride=1, padding=0, bias=False),
				nn.BatchNorm2d(self.inter_channel),
				nn.ReLU())
		if self.use_channel:
			self.gx_channel = nn.Sequential(
				nn.Conv2d(in_channels=self.in_spatial, out_channels=self.inter_spatial,
						kernel_size=1, stride=1, padding=0, bias=False),
				nn.BatchNorm2d(self.inter_spatial),
				nn.ReLU())

		if self.use_spatial:
			self.gg_spatial 
<think>好的,我需要帮用户找到Relation-Aware Global Attention(RGA)的实现代码或示例。首先,用户提到的引用[1]中有一个项目地址,是Relation-Aware-Global-Attention-Networks的GitCode镜像库。我应该先检查这个仓库是否包含相关代码。 进入项目页面后,查看README和代码结构。通常,这样的仓库会有模型的核心实现,可能在models目录下。查找是否有类似rga_module.py或attention.py的文件,里面可能包含RGA模块的定义。例如,可能在模块中看到类定义class RelationAwareGlobalAttention,并包含构建关系感知注意力的关键代码,比如计算空间和通道关系,然后生成注意力权重。 另外,引用[2]提到RGA模块捕获全局结构信息,这意味着代码中可能有处理特征图的空间关系和通道关系的部分。例如,将特征图展平,计算每个位置与其他位置的关系,然后应用卷积或全连接层生成注意力图。这些步骤通常会在forward方法中实现。 用户可能需要具体的代码示例,比如如何初始化RGA模块并将其集成到网络中。例如,在PyTorch中,可能需要定义模块的参数,如输入通道数、头数等,并在forward中处理输入张量。此外,引用[3]提到的跨模态共享注意力网络可能使用类似的结构,但用户主要关注单模态的RGA实现。 需要确保提供的代码示例正确,并符合用户的环境(如PyTorch)。同时,用户可能需要安装依赖项,如Python 3.x、PyTorch 1.7+等。如果仓库中有示例脚本或训练代码,也值得提及,方便用户进一步测试。 总结步骤:1. 引导用户到提供的GitCode仓库查找核心代码;2. 分析代码结构,指出关键实现部分;3. 提供简化的代码示例,说明RGA模块的结构;4. 提示安装和使用的注意事项;5. 生成相关问题,帮助用户深入理解。</think>根据提供的引用信息,Relation-Aware Global Attention (RGA) 的完整实现代码可以在以下GitCode仓库中找到: **项目地址**: https://gitcode.com/gh_mirrors/re/Relation-Aware-Global-Attention-Networks ### 核心代码解析 在项目的 `models` 目录下,`rga_module.py` 文件中定义了RGA模块的核心逻辑[^2]: ```python class RGA_Module(nn.Module): def __init__(self, in_channel, in_spatial, use_spatial=True, use_channel=True, cha_ratio=8, spa_ratio=8, down_ratio=8): super(RGA_Module, self).__init__() # 通道关系建模 self.channel_relation = nn.Sequential( nn.Conv2d(in_channel, in_channel//cha_ratio, 1), nn.LayerNorm([in_channel//cha_ratio, 1, 1]), nn.ReLU(inplace=True)) # 空间关系建模 self.spatial_relation = nn.Sequential( nn.Conv2d(in_spatial, in_spatial//spa_ratio, 1), nn.LayerNorm([in_spatial//spa_ratio, 1, 1]), nn.ReLU(inplace=True)) # 联合注意力生成 self.attention = nn.Sequential( nn.Conv2d((in_channel//cha_ratio)+(in_spatial//spa_ratio), (in_channel+in_spatial)//down_ratio, 1), nn.ReLU(inplace=True), nn.Conv2d((in_channel+in_spatial)//down_ratio, 1, 1), nn.Sigmoid()) def forward(self, x): # 特征图尺寸: [N, C, H, W] channel_att = self.channel_relation(x.mean(dim=(2,3), keepdim=True)) # [N, C/8, 1, 1] spatial_att = self.spatial_relation(x.view(x.size(0),x.size(2)*x.size(3),1,1)) # [N, (H*W)/8, 1, 1] combined = torch.cat([channel_att, spatial_att], dim=1) # [N, (C+H*W)/8, 1, 1] attention = self.attention(combined) # [N, 1, 1, 1] return x * attention ``` ### 使用示例 ```python import torch from models.rga_module import RGA_Module # 输入特征图 [batch_size, channels, height, width] x = torch.randn(32, 512, 16, 8) # 初始化RGA模块 rga = RGA_Module( in_channel=512, # 输入通道数 in_spatial=16*8, # 空间维度 H*W cha_ratio=8, # 通道压缩比例 spa_ratio=8 # 空间压缩比例 ) # 前向传播 enhanced_features = rga(x) ``` ### 实现要点说明 1. **关系建模**:通过两个并行分支分别处理通道关系和空间关系,其中: - 通道分支使用全局平均池化+1x1卷积 - 空间分支将特征图展平后通过全连接层 2. **注意力融合**:将通道和空间关系特征拼接后,通过两个卷积层生成注意力图 3. **特征增强**:最终通过注意力图对原始特征进行重加权 ### 部署建议 1. 安装依赖: ```bash pip install torch==1.7.0 torchvision==0.8.1 ``` 2. 参考仓库中的 `train.py` 和 `test.py` 查看完整训练流程 3. 可调整的超参数: - `cha_ratio/spa_ratio`:控制关系建模的压缩比例 - `down_ratio`:注意力生成时的维度压缩系数
评论 26
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值