transformer来源于谷歌的一篇非常有名的文章:《attention is all you need》。用于的领域是NLP领域。这篇文章的名字很有意思,意思几乎是说,你不需要用RNN,你也不需要用CNN,你所需要的,只有attention层。transformer在NLP中一个很重要的应用是BERT。
2020年,Google在提出了一个将transformer应用在图像分类的模型ViT(vision transformer),具体思路为:将图像分为固定大小的patch,通过线性变化将其变为向量,并将其embeeding进transformer,之后便对其进行分类。transformer的结构通常来说是encoder+decoder,实质上,ViT仅仅使用了transformer的encoder部分,目的是提取特征。
在谷歌尝试将transformer应用至图像领域并获得了较好的效果后,难免会让人想要将transformer应用至视觉领域中的其他任务,比如说立体匹配等。以STTR的模型为transformer在立体匹配中的应用为例进行笔记记录,出自的文章为《Revisiting Stereo Depth Estimation From a Sequence-to-Sequence Perspective with Transformers》(Zhaoshuo Li等人,作者单位:Johns Hopkins University)。这篇文章主要从seq2seq的角度去看待深度估计问题,将代价空间的构建步骤用transformer替代了。
个人认为,现在的DL-based stereo主要是两个思想,一个是基于传统的改进与嵌入,将传统方法中的不可微的东西进行修改,使其可微,就可以将其嵌入进网络中训练了,另一个则是基于深度学习本身的发展,比如特征提取模块,优秀的backbone,以及像transformer这些优秀的block。
下文的文章结构为:
在原理中,首先回顾transformer在《attention is all you need》中的结构及描述,其次介绍其在STTR模型中的应用。
在实验中,首先描述论文中所给出的模型结果,其次给出作者开源代码的环境配置等实际操作。
原理
transformer 结构回顾
整体结构以及在NLP中的可视化表述
如果已经理解transformer里的各个结构的话,可以直接看这个总结性的ppt:下图即为transformer的整体描述图,摘自李宏毅老师的transformer课程PPT。
下图为在NLP中的attention的感性认识,描述的其实是输出的某一个word对输入的sequence中的每一个word的attention,这个所谓的attention,我个人的理解就是更广义的similarity。
transformer中的第一步解构:encoder与decoder
左半部分是encoders,右边是decoders,左右的Nx意思是有N个encoder、decoder(用stack的方式连接)。
encoder
由着箭头的走向,可以将encoder分为三个部分,分别为输入部分(embedding、位置信息嵌入)、注意力机制、前馈神经网络。
- 输入部分
- embedding
word2Vec或者随机初始化 - 位置编码
RNN是天然的时序,而transformer是并行的,也因此忽视了时序的关系,这就需要利用位置编码进行弥补。对于一个词向量的奇数位置以及偶数位置分别利用公式进行不同的编码,再和处理前的词向量进行相加。
已知sin以及cos具有以下的性质
{ sin ( α + β ) = sin α cos β + cos α sin β cos ( α + β ) = cos α cos β − sin α sin β \left\{\begin{array}{l} \sin (\alpha+\beta)=\sin \alpha \cos \beta+\cos \alpha \sin \beta \\ \cos (\alpha+\beta)=\cos \alpha \cos \beta-\sin \alpha \sin \beta \end{array}\right. {sin(α+β)=sinαcosβ+cosαsinβcos(α+β)=cosαcosβ−sinαsinβ
那么,自然有:
{ P E ( pos + k , 2 i ) = P E ( pos, 2 i ) × P E ( k , 2 i + 1 ) + P E ( p o s , 2 i + 1 ) × P E ( k , 2 i ) P E ( p o s + k , 2 i + 1 ) = P E ( p o s , 2 i + 1 ) × P E ( k , 2 i + 1 ) − P E ( p o s , 2 i ) × P E ( k , 2 i ) \left\{\begin{array}{l} P E(\text { pos }+k, 2 i)=P E(\text { pos, } 2 i) \times P E(k, 2 i+1)+P E(p o s, 2 i+1) \times P E(k, 2 i) \\ P E(p o s+k, 2 i+1)=P E(p o s, 2 i+1) \times P E(k, 2 i+1)-P E(p o s, 2 i) \times P E(k, 2 i) \end{array}\right. {PE( pos +k,2i)=PE( pos, 2i)×PE(k,2i+1)+PE(pos,2i+1)×PE(k,2i)PE(pos+k,2i+1)=PE(pos,2i+1)×PE(k,2i+1)−PE(pos,2i)×PE(k,2i)
该式则表达了pos位置与k位置的位置向量的关系,也就蕴含了相对位置的信息。
- embedding
至于位置编码为什么是和embedding vector进行相加,而不是进行concat,李宏毅老师则给出了以下的解释:
- 注意力机制
self-attention是一种比较新的layer,可以和RNN有类似的效果,输入是一个sequence,输出也是一个sequence,但是相对于RNN来说,拥有着RNN有的优点,即每一个seq的输出都是已经看过所有输入的了,同时,又克服了RNN的缺点,即可以并行。
下图为李宏毅老师transformer课程中的一个self-attention的截图(若侵则删):
计算attention离不开是三个矩阵:Q、K、V:
什么是attention?其实可以将其理解为一种两两之间的相似度。点乘是一个向量在另一个向量上投影的长度,常被用于表示相似度。在transformer中,用来计算attention的方式是scaled Dot-Product Attention,为什么要除以
d
\sqrt{d}
d呢,原因是dimension越大,值就会越大(不过除以不除以
d
的
影
响
有
多
大
,
并
没
有
做
过
实
验
,
可
以
做
实
验
试
一
下
\sqrt{d}的影响有多大,并没有做过实验,可以做实验试一下
d的影响有多大,并没有做过实验,可以做实验试一下)。得到attention后,再做soft-max,再做weighted sum得到。由下图可见,在得到
b
1
b^1
b1时,已经看过了
a
1
a^1
a1至
a
4
a^4
a4了,是一个weighted sum的过程。引申至立体匹配时,我不经想到该sef-attention可以进一步替代传统匹配方法中代价聚集的部分,比如说在基于双边滤波、引导滤波或者说基于MST、ST的代价聚集过程中,其实都是想在找全图中与待聚集像素在某种意义上相似的像素,然后进行类似于weighted sum的操作。
下图为做并行化的示意图,其实就是将embedding的vectors进行矩阵化。
下一步再做weighted sum:
再回顾一下seelf-attention的整体结构,为:
Attention
(
Q
,
K
,
V
)
=
softmax
(
Q
K
T
d
k
)
V
\operatorname{Attention}(Q, K, V)=\operatorname{softmax}\left(\frac{Q K^{T}}{\sqrt{d_{k}}}\right) V
Attention(Q,K,V)=softmax(dkQKT)V
在实际中,用multi-head,也就是得到多头,用到各自的Q,K,V,也就可以捕捉到多个信息。multi-head的好处就是,有的head想看local的信息,而有的head想看global的信息。以下为以两个head为例的示意图。
如果对
b
i
,
1
b^{i,1}
bi,1以及
b
i
,
2
b^{i,2}
bi,2不满意的话,可以对其做降维:
以机器翻译的场景为例,mutli-head 的示意图:绿色的head更注意到长距离的attention信息,红色的attention更注意到local或者说短距离的attenton信息。
- 残差网络
根据链式法则的推导,加入残差网络可以有效缓解梯度消失的问题,也因此可以使得网络层数更深一些。
Layer Normalization(简称LN)
BN在NLP中效果比较差。BN是对一个batch中的每一个维度的特征分别去做BN,基于的假设是batch中的第一行都是同一个维度。BN在batch_size小的时候效果比较差,因为是用batch的均值和方差来模拟所有的数据。然而,由于RNN的输入是动态的,也就是说长度不同,那么BN自然就不那么适用了。LN则是在对输入的一个句子的句向量做均值和方差,也就是词向量的加权。
- 前馈神经网络
注意,encoder生成的是K和V矩阵,decoder生成的是Q矩阵。
decoder
相比起encoder,有多一个masked multi-head attention,为什么?因为模型训练的时候,可以看到后面的句子,而预测的时候看不到后面的句子,为了处理掉这个模型训练和预测之间的gap,需要在decoder中进行的模拟,也就需要在decoder中将后面的句子给mask掉,不让网络看到。
STTR中的方法原理
STTR的整体网络结构为:
可以明显地看到,相对于常规的DL-based Stereo方法来说,STTR用transformer替换了cost volume,输入输出也有所不同。
在transform中的输入为左右特征图的核线,然后经过self-attention以及cross-attention。
self-attention以及cross-attention
在STTR中,使用了两种attention机制,一个是self-sttention,另一个是cross-attention。self-attention使用了自身影像中的语义信息,cross-attention则使用了两张影像之间的语义信息,随着层数的增加,attention将从全局的语义缩小至局部的语义。在比较大的纹理缺失的区域,attention倾向于关注主要特征,比如说边缘等。
在文章中用的multi-head的attention,所谓的multi-head是将特征编码
C
e
C_e
Ce切分为
N
h
N_h
Nh个的group,每个head的通道就有
C
h
=
C
e
/
N
h
C_h=C_e/N_h
Ch=Ce/Nh。每个head就是各自独立的group,各自的feature channel是不一样的,也因此有着不同的表达,可以计算各自的相似性。
对于某一个head来说,不妨将该head命名为
h
h
h,将
h
h
h所对应的query向量命名为
Q
h
\mathcal{Q_h}
Qh,key向量命名为
K
h
\mathcal{K_h}
Kh,value向量命名为
V
h
\mathcal{V_h}
Vh,query、key以及value向量均可以通过特征描述子
e
I
e_I
eI的线性变换得到,具体见下式:
Q
h
=
W
Q
h
e
I
+
b
Q
h
K
h
=
W
K
h
e
I
+
b
K
h
V
h
=
W
V
h
e
I
+
b
V
h
\begin{array}{l} \mathcal{Q}_{h}=W_{\mathcal{Q}_{h}} e_{I}+b_{\mathcal{Q}_{h}} \\ \mathcal{K}_{h}=W_{\mathcal{K}_{h}} e_{I}+b_{\mathcal{K}_{h}} \\ \mathcal{V}_{h}=W_{\mathcal{V}_{h}} e_{I}+b_{\mathcal{V}_{h}} \end{array}
Qh=WQheI+bQhKh=WKheI+bKhVh=WVheI+bVh
- 可以通过softmax的方式得到query向量与key向量之间的点积相似度:
α h = s o f t m a x ( Q h T K h C h ) \alpha_h=softmax(\frac{\mathcal{Q_h^T}\mathcal{K_h}}{\sqrt{C_h}}) αh=softmax(ChQhTKh) - multi-head输出的value向量为:
V O = W O C o n c a t ( α 1 V 1 , . . . , α N h V N h ) + b O \mathcal{V_O}=W_{\mathcal{O}}Concat(\alpha_1\mathcal{V_1},...,\alpha_{N_h}\mathcal{V}_{N_h})+b_{\mathcal{O}} VO=WOConcat(α1V1,...,αNhVNh)+bO - value向量
V
O
\mathcal{V_O}
VO将被直接加到原本的特征描述子的后面,形成一个残差连接:
e I = e I + V O e_I=e_I+\mathcal{V_O} eI=eI+VO
对于self-attention来说, Q h \mathcal{Q_h} Qh, K h \mathcal{K_h} Kh, V h \mathcal{V_h} Vh从同一张影像中计算而得。而对于cross-attention而言, Q h \mathcal{Q_h} Qh由source image计算而得,另外的 K h \mathcal{K_h} Kh以及 V h \mathcal{V_h} Vh则由target image计算而得。
Relative Positional Encoding相对位置编码,简称RPE
因为影像的attention本身所能够提供的信息并不够,因此额外选择了RPE(Relative Positional Encoding)的方式来提供位置信息。
在传统transformer中,位置的编码是直接加到特征描述图上的,这点在前面也介绍过,还给出过李宏毅老师对为什么是直接加的不同角度的解释。不妨设绝对位置编码为
e
p
e_p
ep,特征描述图为
e
I
e_I
eI,直接加上之后,就有:
e
=
e
I
+
e
p
e=e_I+e_p
e=eI+ep
再根据attention中的下面两个公式:
Q
h
=
W
Q
h
e
I
+
b
Q
h
K
h
=
W
K
h
e
I
+
b
K
h
V
h
=
W
v
h
e
I
+
b
V
h
\begin{aligned} \mathcal{Q}_{h} &=W_{\mathcal{Q}_{h}} e_{I}+b_{\mathcal{Q}_{h}} \\ \mathcal{K}_{h} &=W_{\mathcal{K}_{h}} e_{I}+b_{\mathcal{K}_{h}} \\ \mathcal{V}_{h} &=W_{v_{h}} e_{I}+b_{V_{h}} \end{aligned}
QhKhVh=WQheI+bQh=WKheI+bKh=WvheI+bVh
以及:
α
h
=
softmax
(
Q
h
T
K
h
C
h
)
\alpha_{h}=\operatorname{softmax}\left(\frac{\mathcal{Q}_{h}^{T} \mathcal{K}_{h}}{\sqrt{C_{h}}}\right)
αh=softmax(ChQhTKh)
省略softmax以及向量
b
b
b,将
e
I
e_I
eI用
e
I
+
e
p
e_I+e_p
eI+ep代替,对于attention矩阵中的某一个element来说,整理有:
α
i
,
j
=
e
I
,
i
T
W
Q
T
W
K
e
I
,
j
⏟
(1) data-data
+
e
I
,
i
T
W
Q
T
W
K
e
p
,
j
⏟
(2) data-position
+
e
p
,
i
T
W
Q
T
W
K
e
I
,
j
⏟
(3) position-data
+
e
p
,
i
T
W
Q
T
W
K
e
p
,
j
⏟
(4) position-position
\begin{array}{r} \alpha_{i, j}=\underbrace{e_{I, i}^{T} W_{\mathcal{Q}}^{T} W_{\mathcal{K}} e_{I, j}}_{\text {(1) data-data }}+\underbrace{e_{I, i}^{T} W_{\mathcal{Q}}^{T} W_{K} e_{p, j}}_{\text {(2) data-position }}+ \\ \underbrace{e_{p, i}^{T} W_{\mathcal{Q}}^{T} W_{\mathcal{K}} e_{I, j}}_{\text {(3) position-data }}+\underbrace{e_{p, i}^{T} W_{\mathcal{Q}}^{T} W_{\mathcal{K}} e_{p, j}}_{\text {(4) position-position }} \end{array}
αi,j=(1) data-data
eI,iTWQTWKeI,j+(2) data-position
eI,iTWQTWKep,j+(3) position-data
ep,iTWQTWKeI,j+(4) position-position
ep,iTWQTWKep,j
第(4)项只跟像素
i
i
i,像素
j
j
j的位置有关,然而,作者认为,视差只应该跟图像的信息有关,对于绝对的位置来说,没有关系,所以这项应该被丢弃掉。进而,作者通过将式(2)中的
e
p
,
j
e_{p,j}
ep,j,即像素
j
j
j的位置编码信息替换为
e
p
,
i
−
j
e_{p,i-j}
ep,i−j,即像素
i
−
j
i-j
i−j的位置信息,将式(3)中的
e
p
,
i
T
e^T_{p,i}
ep,iT变换为
e
p
,
i
−
j
T
e^T_{p,i-j}
ep,i−jT,并直接舍弃第四项的方式,实现了RPE模块。
不过我在这里有一个疑问,为什么不管
e
p
,
j
e_{p,j}
ep,j还是
e
p
,
i
T
e^T_{p,i}
ep,iT,都变换成了
e
p
,
i
−
j
e_{p,i-j}
ep,i−j,而不是一个变为
e
p
,
i
−
j
e_{p,i-j}
ep,i−j,另一个变为
e
p
,
j
−
i
e_{p,j-i}
ep,j−i?(原文:where
e
p
,
i
−
j
e_{p,i−j}
ep,i−j denotes the positional encoding between the i-th and j-th pixel)。直觉上来说,attention应当将取决于图像内容的相似性以及相对距离。
optimal transport,简称OT
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MHVu5yIl-1619746526145)(https://openaccess.thecvf.com/content_CVPR_2020/papers/Liu_Semantic_Correspondence_as_an_Optimal_Transport_Problem_CVPR_2020_paper.pdf)])](https://img-blog.csdnimg.cn/20210430093406436.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2Zsb3dfc3BlY3Rlcg==,size_16,color_FFFFFF,t_70)
optimal transport的理论可以参考博文。
OT的学习代码可以参考该github上的代码。(感谢各位前辈的开源工作)
OT在这里出现的作用是模拟传统方法中的唯一性约束。个人认为,也算是将传统方法中的某些思想嵌入进网络中,与GA-Net、SGM-NETs等传统改进的网络在某种角度上有着类似的思想。
T = argmin T ∈ R + I w × I w ∑ i , j = 1 I w , I w T i j M i j − γ E ( T ) s.t. T 1 I w = a , T T 1 I w = b \begin{array}{l} \mathcal{T}=\underset{\mathcal{T} \in R_{+}^{I_{w} \times I_{w}}}{\operatorname{argmin}} \sum_{i, j=1}^{I_{w}, I_{w}} \mathcal{T}_{i j} M_{i j}-\gamma E(\mathcal{T}) \\ \text { s.t. } \mathcal{T} 1_{I_{w}}=a, \mathcal{T}^{T} 1_{I_{w}}=b \end{array} T=T∈R+Iw×Iwargmin∑i,j=1Iw,IwTijMij−γE(T) s.t. T1Iw=a,TT1Iw=b
直观上来看, T \mathcal{T} T中的每个元素代表的是逐对的匹配概率,和attention很类似。但是由于occlusion,有些像素是无法形成匹配对的,对于这些像素来说,作者通过再加上一个学习参数 ϕ \phi ϕ来对其进行表示,即,代表unmatched pixel的cost。注意,代价矩阵M是cross-attention计算的负数,但是,并没有做softmax,因为OT的过程会归一化attention数值的。
attention mask模块,简称AM
在seq2seq模型中,AM主要出现在decoder部分,为的是模拟真实翻译时我们用户不知道输入sequence未出现信息的情况,而在STTR中的AM,有些不一样。
假设同名点在左右某条核线上的位置为:
x
L
x_L
xL,
x
R
x_R
xR,且在左右没有问题的时候,我们通常认为
x
L
x_L
xL绝对是大于
x
R
x_R
xR的,也因此,
x
L
x_L
xL的同名点
x
R
x_R
xR在右图的位置理论上是一定会小于
x
L
x_L
xL坐标的,这样也就相当于施加了一个几何约束。在STTR中的AM,实际上就是为了施加这样的约束。AM实际上是一个下三角的二值mask,作用于attention上。
Raw Disparity and Occlusion Regression
作者不采用加权和的方式进行视差回归,而是采用改进的WTA方式,并认为该方式对于multi-modal的分布更加鲁棒。
从optimal transport assignment矩阵
T
\mathcal{T}
T中选取最有可能的匹配,标记为
k
k
k。并且在
k
k
k周围建立起了3个像素的窗口,命名为
N
3
(
k
)
\mathcal{N_3}(k)
N3(k)(对该窗口进行normalization,使得窗口内的匹配概率的加和为1)。
假设候选视差的加权值为
d
~
raw
(
k
)
\tilde{d}_{\text {raw }}(k)
d~raw (k),设在assignment matrix
T
\mathcal{T}
T中的元素,即匹配概率,为
t
t
t,因此有:
t
~
l
=
t
l
∑
l
∈
N
3
(
k
)
t
l
,
for
l
∈
N
3
(
k
)
d
~
r
a
w
(
k
)
=
∑
l
∈
N
3
(
k
)
d
l
t
~
l
\begin{array}{c} \tilde{t}_{l}=\frac{t_{l}}{\sum_{l \in \mathcal{N}_{3}(k)} t_{l}}, \text { for } l \in \mathcal{N}_{3}(k) \\ \tilde{d}_{r a w}(k)=\sum_{l \in \mathcal{N}_{3}(k)} d_{l} \tilde{t}_{l} \end{array}
t~l=∑l∈N3(k)tltl, for l∈N3(k)d~raw(k)=∑l∈N3(k)dlt~l
至于匹配
k
k
k的occlusion概率的计算公式为:
p
o
c
c
(
k
)
=
1
−
∑
l
∈
N
3
(
k
)
t
l
p_{o c c}(k)=1-\sum_{l \in \mathcal{N}_{3}(k)} t_{l}
pocc(k)=1−l∈N3(k)∑tl
在这一步中,STTR不仅识别出了occlusion,还进一步给出了occlusion的置信度,是文章的一个亮点。
Context Adjustment Layer,简称CAL
视差的回归,以及遮挡图都是在核线上进行的,也因此缺少跨核线的信息。为了解决这个问题,作者使用了以下结构进行跨核线信息的聚集,即所谓的CAL:
对于occlusion,首先将left image以及occlusion进行concat,然后用两个卷积block+relu对其concat的信息进行处理,相当于聚合了occlusion的信息,然后得到最后的occlusion,没什么好说的。
对于final的视差来说,residual block首先将通道进行了扩展,然后再存回原本的通道维度中,并将raw disparity与residual block的输出进行concat,如此往复。
我认为,这个模块主要是将left image的信息融入了,即所谓的context adjustment。
实验
ablation studies
进行ablation studies的数据为Scene flow。
主要实验的模块有,attention mask(简称AM),optimal transport layer(简称OT),context adjustment layer(简称CAL),以及relative Positional encoding(简称RPE)。
测试的结果如下表:
看起来每一个模块加进去,整体的精度都是有所上升的。
参考链接
- https://mp.weixin.qq.com/s/zBsHIPSwmfxEI4zTz5Q5Cw
- 李宏毅老师的transformer视频:https://www.youtube.com/watch?v=UYPa347-DdE