赞
踩
这是首篇开源的将transformer用于行人重识别的文章,基于原来的bag of tricks (BoT)1。
文章标题:TransReID: Transformer-based Object Re-Identification
论文地址:https://arxiv.org/abs/2102.04378
代码地址:TransReID
安利小技巧:把链接github.com
变为github1s.com
试试,就是github后面加个1s(1秒)。
这是首篇使用视觉Transformer (ViT)实现ReID的文章。Transformer在视觉领域突然大火,它是一个完全由注意力组成的结构而不同于传统的CNN,原来用在语言处理领域,后来被拓展到了视觉领域,它的基本工作过程如下图所示,将图片切成若干个patches,以序列的形式输入ViT,这样做能充分挖掘每个patch之间的联系,所以理应有效。
作者基于ViT和Bag of tricks1设计了一个名为ViT-BoT的强baseline,性能媲美ResNet、ResNeSt等CNN网络,此外,ReID数据集除了包含ID信息和视觉信息外,往往还带有相机(非视觉)信息,传统的CNN Based方法很少用到非视觉信息,想用这些信息的话也得重新设计CNN,但是transformer很容易将非视觉信息编码为vector进行嵌入表示,这是其一大优点,作者考虑到了这点,并介绍了一个Side Information Embedding (SIE)模块。最后,为了作者设计了一个Jigsaw分支(包含一个Jigsaw patch module,JPM)以更好地训练ViT-Bot,JPM是受那些切割stripes方法的启发,与后者不同,JPM中的patches被打乱形成更大的patches。结合SIE和JPM,作者提出了TransReID模型架构。
ViT-BoT的结构如上图所示,由于ViT的原始训练策略不使用于ReID,作者做了一些改变:
重叠的patches——对于原始的ViT,输入图像被分割成
N
N
N个不重叠的patches,这样做不能保存patch周围的局部相邻结构,为此作者使用滑动窗口来生成具有重叠像素的patch,若窗口的步长为
S
S
S像素,patch的大小
P
=
16
P=16
P=16,相邻patches重叠区域的尺寸为
(
P
−
S
)
×
P
(P-S)\times P
(P−S)×P,那么将输入图像resize为
H
×
W
H \times W
H×W后,将分成式(1)中的
N
N
N个patches,其中
⌊
⋅
⌋
\lfloor\cdot\rfloor
⌊⋅⌋是向下取整,重叠区域越大,得到的patches越多,同时性能就更好,但也会增加计算量,所以要同时考虑性能和计算代价。
N
=
N
H
×
N
W
=
⌊
H
+
S
−
P
S
⌋
×
⌊
W
+
S
−
P
S
⌋
(1)
N=N_{H} \times N_{W}=\left\lfloor\frac{H+S-P}{S}\right\rfloor \times\left\lfloor\frac{W+S-P}{S}\right\rfloor\tag{1}
N=NH×NW=⌊SH+S−P⌋×⌊SW+S−P⌋(1)
Position Embedding——Position embedding ρ i \rho_i ρi 对第 i i i个patch p i p_i pi的位置信息进行编码,这对于transformer的编码器编码空间信息是很重要的,训练时加载ImageNet上预训练的ViT模型参数,由于图像分辨率不同,ImageNet上预处理的position embedding不能直接拿来用,所以作者加入了双线性插值(bilinear interpolation)以让ViT-BoT适应任意大小的输入图像,ViT-BoT的位置嵌入也是可学习的。
特征学习——给定一张图像,分成一系列patches,可学习的嵌入(如class token)位于patches的嵌入之前,最后一个编码器层(最终class token)用作图像的全局特征表示,最终的class token记为
f
f
f,与输入patches对应的输出表示为
P
0
=
{
p
o
1
,
p
o
2
,
p
o
3
,
…
,
p
o
N
}
P_0=\left\{p_{o_{1}}, p_{o_{2}}, p_{o_{3}}, \ldots, p_{o_{N}}\right\}
P0={po1,po2,po3,…,poN},
N
N
N是patches的数量,作者在最后的class token后面接了一个BNNeck1(就是联合ID loss和triplet loss),
L
I
D
\mathcal{L}_{ID}
LID是不带标签平滑的交叉熵损失,三元组损失是如式(2)的soft-margin版本。
L
T
=
log
[
1
+
exp
(
∥
f
a
−
f
p
∥
2
2
−
∥
f
a
−
f
n
∥
2
2
)
]
(2)
\mathcal{L}_{T}=\log \left[1+\exp \left(\left\|f_{a}-f_{p}\right\|_{2}^{2}-\left\|f_{a}-f_{n}\right\|_{2}^{2}\right)\right] \tag{2}
LT=log[1+exp(∥fa−fp∥22−∥fa−fn∥22)](2)
ViT-BoT能取得理想的性能但是并不能充分利用ReID数据的特性,为了进一步挖掘边缘信息和细粒度parts,作者提出了SIE模块和JPM模块,并引出下图所示的TransReID框架。
相机、视角及其他因素造成的外观差异是ReID面临的挑战性问题,对于CNN来说,用上相机ID、视角信息这些非视觉损失要修改网络结构或设计特定的损失,但这对于transformer来说小菜一碟,它可以编码这些side information得到embedding,如果一张图片的相机ID为 C C C,那么其相机embedding可表示为 S ( C ) \mathcal{S}(C) S(C),对于各个patch来说,位置嵌入是不同的,但是相机嵌入对一幅图像的所有patch都是相同的,如果视角标签 V V V可用,那么也可以得到视角嵌入 S ( V ) \mathcal{S}(V) S(V)。但是如何整合两种信息也是一个难题,直接使用 S ( C ) + S ( V ) \mathcal{S}(C)+\mathcal{S}(V) S(C)+S(V)可能会使两种信息抵消,所以作者提议将相机信息和视角信息共同编码为 S ( C , V ) \mathcal{S}(C,V) S(C,V),换句话说,对 C N C_N CN个相机ID和 V N V_N VN个视角标签, S ( C , V ) \mathcal{S}(C,V) S(C,V)共有 C N × V N C_N \times V_N CN×VN个不同的值,最终第 i i i个patch的输入embedding表示为公式(3), F \mathcal{F} F是学习特征表示的线性投影, λ \lambda λ是平衡 S ( C , V ) \mathcal{S}(C,V) S(C,V)的超参,由于每个位置嵌入 ρ i \rho_i ρi对于每个patch是不同的,但对于不同的图片却是相同的, S ( C , V ) \mathcal{S}(C,V) S(C,V)对同一图片的patches是相同的,但对不同图片而言不同,所以TransReID可以学到两种不同的embedding,整个输入嵌入为: [ E 0 ; E 1 , E 2 , … , E N ] \left[E_{0} ; E_{1}, E_{2}, \ldots, E_{N}\right] [E0;E1,E2,…,EN], E 0 E_{0} E0是class token。
E i = F ( p i ) + ρ i + λ S ( C , V ) (3) E^{i}=\mathcal{F}\left(p_{i}\right)+\rho_{i}+\lambda \mathcal{S}(C, V)\tag{3} Ei=F(pi)+ρi+λS(C,V)(3)
作者将ViT-BoT的最后一层改为两个并行分支,通过两个独立的Transformer层学习全局特征和局部特征,输入最后一层的隐藏特征记为
Z
l
−
1
=
[
z
l
−
1
0
;
z
l
−
1
1
,
z
l
−
1
2
,
…
,
z
l
−
1
N
]
Z_{l-1}=\left[z_{l-1}^{0} ; z_{l-1}^{1}, z_{l-1}^{2}, \ldots, z_{l-1}^{N}\right]
Zl−1=[zl−10;zl−11,zl−12,…,zl−1N],全局分支是将
Z
l
−
1
Z_{l-1}
Zl−1编码为
Z
l
=
[
f
g
;
z
l
1
,
z
l
2
,
…
,
z
l
N
]
Z_{l}= \left[f_{g} ; z_{l}^{1}, z_{l}^{2}, \ldots, z_{l}^{N}\right]
Zl=[fg;zl1,zl2,…,zlN]的标准transformer,
f
g
f_{g}
fg可以视为CNN里的全局特征,学习细粒度part级特征的一种方法是将
[
z
l
−
1
1
,
z
l
−
1
2
,
…
,
z
l
−
1
N
]
\left[z_{l-1}^{1}, z_{l-1}^{2}, \ldots, z_{l-1}^{N}\right]
[zl−11,zl−12,…,zl−1N]划分为
k
k
k组以便将shared token
z
l
−
1
0
z_{l-1}^0
zl−10连接起来,然后将
k
k
k个特征组馈入transformer层以学习
k
k
k个局部特征
{
f
l
1
,
f
l
2
,
…
,
f
l
k
}
\left\{f_{l}^{1}, f_{l}^{2}, \ldots, f_{l}^{k}\right\}
{fl1,fl2,…,flk},
f
l
k
f_l^k
flk是第
k
k
k组的输出token。不过有工作表明,token嵌入主要由附近的token决定,但是一组邻近的token embedding只能观察到有限的连续区域,为此,作者提出了JPM模块,在patches分组之前将其打乱,这是受ShuffleNet2的启发,打乱操作由shift和patch shuffle操作组成:
The shift operation:前
m
m
m个补丁移到末尾,
[
z
l
−
1
1
,
z
l
−
1
2
,
…
,
z
l
−
1
N
]
\left[z_{l-1}^{1}, z_{l-1}^{2}, \ldots, z_{l-1}^{N}\right]
[zl−11,zl−12,…,zl−1N]经
m
m
m步移动变成:
[
z
l
−
1
m
+
1
,
z
l
−
1
m
+
2
,
…
,
z
l
−
1
N
,
z
l
−
1
1
,
z
l
−
1
2
,
…
,
z
l
−
1
m
]
\left[z_{l-1}^{m+1}, z_{l-1}^{m+2}, \ldots, z_{l-1}^{N}, z_{l-1}^{1}, z_{l-1}^{2}, \ldots, z_{l-1}^{m}\right]
[zl−1m+1,zl−1m+2,…,zl−1N,zl−11,zl−12,…,zl−1m]
The patch shuffle operation:将shift操作得到的patch进一步打乱,得到:
[
z
l
−
1
x
1
,
z
l
−
1
x
2
,
…
,
z
l
−
1
x
N
]
,
x
i
∈
[
1
,
N
]
\left[z_{l-1}^{x 1}, z_{l-1}^{x 2}, \ldots, z_{l-1}^{x_{N}}\right], x_{i} \in[1, N]
[zl−1x1,zl−1x2,…,zl−1xN],xi∈[1,N]
而后将乱序的patch分为
k
k
k组,JPM用共享的transformer将其编码为
k
k
k个局部特征
{
f
l
1
,
f
l
2
,
…
,
f
l
k
}
\left\{f_{l}^{1}, f_{l}^{2}, \ldots, f_{l}^{k}\right\}
{fl1,fl2,…,flk},作者说经过shuffle操作,局部特征
f
l
k
f_l^k
flk可以覆盖不同parts的patch,全局特征
f
g
f_g
fg和
k
k
k个局部特征用
L
I
D
\mathcal{L}_{ID}
LID和
L
T
\mathcal{L}_{T}
LT训练,总的损失如公式(4):
L
=
L
I
D
(
f
g
)
+
L
T
(
f
g
)
+
1
k
∑
(
L
I
D
(
f
l
i
)
+
L
T
(
f
l
i
)
)
(4)
\mathcal{L}=\mathcal{L}_{I D}\left(f_{g}\right)+\mathcal{L}_{T}\left(f_{g}\right)+\frac{1}{k} \sum\left(\mathcal{L}_{I D}\left(f_{l}^{i}\right)+\mathcal{L}_{T}\left(f_{l}^{i}\right)\right)\tag{4}
L=LID(fg)+LT(fg)+k1∑(LID(fli)+LT(fli))(4)
推理阶段则将全局特征和局部特征连接作为最终的特征表示。
实验用到了行人和车辆ReID的数据集,其中有一个不常见的行人ReID数据集Occluded-Duke3,这是一个带有遮挡情况的数据集,值得一试。下图展示了和SOTA方法对比的结果,*表示使用的backbone是ViT-BoT
S
=
12
_{S=12}
S=12,c和v分别代表用到了相机信息和标签信息,b表示都用到了。
Transformer大火,作者设计了一个纯Transformer框架实现ReID,可以说是开创性工作,主要还是为我们这个方向提供了参考,证明Transformer是可行的,在ReID准确率饱和的今天,实属是曙光。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。