阅读本文的基础:
- 需要对【视觉卷积神经网络】比较熟悉。
- 需要对【目标分类、检测任务】比较熟悉。
- 需要对【RNN】有了解。
一、发展历史:
(参考:A Survey on Visual Transformer 2020.12.23) (参考Cheng He)
- 起源:2017年6月谷歌《Attention is all you need》
- 检测和分割:DETR(CNN+ Transformer,更简单和更灵活的pipeline)
- 分类:Vision Transformer(only Transformer:SOTA,减少训练计算资源)
- 像素级图像补全:Image GPT
- 车道标记检测:End-to-end Lane Shape Prediction with Transformers
二、从上向下的理解Transformer
- 本章的思路为:1、整体结构简单介绍 => 2、细节 => 3、整体结构详细介绍 => 4、Transformer的示例
1、Transformer整体结构简单介绍
(参考 龙心尘)
- Transformer由Encoders和Decoders组成,解决Seq2Seq问题
- Encoders = 6
×
\times
× encoder, 这6个encoder结构相同,但不共享参数。
- Decoders = 6
×
\times
× decoder, 这6个decoder结构相同,但不共享参数。
- 每个encoder都 = “self-attention” + “feed-forward network”。 self-attention,自注意力,获得上下文信息。feed-forward network,每个位置的单词对应的前馈神经网络都完全一样。(BP层和平常用的FC层的区别,参考:https://www.zhihu.com/question/470674012,感觉就是一个东西)
- 每个decoder都 = “self-attention” + “attention” + “feed-forward network”。注意力层,用来关注输入句子的相关部分 。
2、Transformer中的Self-attention
(参考:李宏毅老师的Transformer视频) (参考:A Survey on Visual Transformer 2020.12.23)
(1)引入
- 最简单的seq2seq结构就是RNN,缺点是不能并行化
- 用一维卷积网络做seq2seq,可以平行化,但是缺点是必须叠很多层才能拥有大感受野
- 利用Self-attention可以做到seq2seq结构,并且并行化,完全替代RNN
(2)self-attention
- 第一步:提取qkv
q: query(to match others)
q
q
q = [
W
q
a
i
W^qa^i
Wqai for
i
i
i in range(len(a))] k: key(to be matched)
k
k
k = [
W
k
a
i
W^ka^i
Wkai for
i
i
i in range(len(a))] v: value(information to be extracted)
v
v
v = [
W
v
a
i
W^va^i
Wvai for
i
i
i in range(len(a))] - 第二步:做attention得到
α
\alpha
α(除以根号d是为了获得更稳定的梯度)
用每个q(
q
i
q^i
qi)去和每个k(
k
j
k^j
kj)做乘法,得到attention(
α
i
j
=
q
i
k
j
d
\alpha^{ij}=\frac{q^ik^j}{\sqrt{d}}
αij=d
?qikj?) - 第三步:softmax得到
α
^
\hat{\alpha}
α^
α
^
i
j
=
e
x
p
(
α
i
j
)
/
∑
j
e
x
p
(
α
i
j
)
\hat{\alpha}^{ij}=exp(\alpha^{ij})/\sum_j{exp(\alpha^{ij})}
α^ij=exp(αij)/∑j?exp(αij) - 第四步:weighted-sum得到b
b
i
=
∑
j
α
^
i
j
v
j
b^{i}=\sum_j\hat{\alpha}^{ij}v^j
bi=∑j?α^ijvj
(3)并行化计算
- 第一步:得到qkv
Q
=
[
q
1
,
q
2
,
q
3
,
q
4
]
=
W
q
[
a
1
,
a
2
,
a
3
,
a
4
]
Q=[q^1,q^2,q^3,q^4]=W^q[a^1,a^2,a^3,a^4]
Q=[q1,q2,q3,q4]=Wq[a1,a2,a3,a4] - 第二步:做attention得到
α
\alpha
α
α
=
[
k
1
,
k
2
,
k
3
,
k
4
]
T
[
q
1
,
q
2
,
q
3
,
q
4
]
=
K
T
Q
\alpha=[k^1,k^2,k^3,k^4]^T[q^1,q^2,q^3,q^4]=K^TQ
α=[k1,k2,k3,k4]T[q1,q2,q3,q4]=KTQ - 第三步:softmax得到
α
^
\hat{\alpha}
α^
对每一列进行softmax - 第四步:weighted-sum得到b
b
=
[
b
1
,
b
2
,
b
3
,
b
4
]
=
[
v
1
,
v
2
,
v
3
,
v
4
]
α
^
=
v
α
^
b=[b^1,b^2,b^3,b^4] =[v^1,v^2,v^3,v^4]\hat{\alpha}=v\hat{\alpha}
b=[b1,b2,b3,b4]=[v1,v2,v3,v4]α^=vα^
(4)Multi-head Self-attention
-
意义:分为多个head,每个head做不同的工作,比如一个head负责局部,另一个负责全局(不同head is almost the same, except the随机初始化)。head数量是一个可调参数。 -
做法第一步:以2-head Self-attention为例。如图,qkv都分为两支,而左侧的q之和左侧的k做attention,右侧的q之和右侧的k做attention。 -
做法第二步:得到2个b,直接contact起来,如果得到的维度过大,可以直接再乘上一个矩阵降维。
(5)位置编码Positional Encoding
- 缺点:对于一个给定的self-attention层,无论序列以任何顺序输入,得到的输出总是相同的,因为self-attention无法关注到序列的位置信息。
- 解决方法:Positional Encoding,将位置信息编码到向量e里,再将其原始向量a相加。
- 为什么是e和a是相加而不是contact: 李宏毅老师也觉得很奇怪。
3、Transformer整体结构详细介绍
(参考:李宏毅老师的Transformer视频)
(1)整体
编码器部分同时输入“机器学习”四个中文,并同时得到编码结果。 解码器部分先输出“machine”,然后把“machine”作为解码器的输入,在输出“learning”。
(2)编码器部分
- Positional Encoding:见上文
- Multi-Head Attention:见上文
- Add: 输出和输入相加(残差连接,防止梯度消失)
- Layer Norm
第一、Layer Norm 一般搭配RNN使用 第二、Batch Norm 令同一batch中 “所有data” 的同一纬度 的均值为0方差为1 第三、Layer Norm 令同一data中 “所有纬度” 的 的均值为0方差为1,无Batch的概念 - Feed Forward:直接理解为两层全连接,权重映射+非线性激活+权重映射
(3)解码器部分
解码器部分先输出“machine”,然后把“machine”作为解码器的输入,在输出“learning”。
- Masked Multi-Head Attention:这一层的输入是已经产生的输出,比如在解码器部分先输出“machine”之后,下一次解码器的输入就是“machine”。(masked的意思是只关注已产生的输出)
- encoder-decoder attention层:就是解码器中的第二个Multi-Head Attention layer:它的K和V是编码器的,Q是之前层获得的。
解码过程动图
4、示例
(参考:李宏毅老师的Transformer视频)
- 在不同的语境中,Transformer可以自行关注到重点内容。
这个动物并没有过马路,因为它太累了:attention把"它"理解为动物。 这个动物并没有过马路,因为它太宽了:attention把"它"理解为马路。 - multi-head attention 能够自行关注到局部和全局信息。
下边的更关注局部信息(红色局部很明显),上边更关注长时信息(绿色全局很明显)。
5、Transformer的compress与accelerate
(参考:A Survey on Visual Transformer 2020.12.23)(参考:大连理工大学 王栋老师 A Survey on Visual Transformer 导读)
三、用Transformer解决计算机视觉问题
(参考:A Survey on Visual Transformer 2020.12.23)(参考:大连理工大学 王栋老师 A Survey on Visual Transformer 导读) 大部分视觉任务都只是使用了encoder部分,所以和CNN配合使用
1、iGPT(简介)
- 自监督模型
- 训练时,扣掉一个点,用周围的点去预测它。这样就会学到一个能理解图像内容的模型,再将这个模型用于特征提取。(类似于学英语,找到一篇文章,随机扣掉一个词,做完形填空,学好了之后去做阅读理解。)
- 微调时,用交叉熵。
- 完全照搬NLP中的策略
2、ViT(简介)
(参考Cheng He)(参考咫尺小厘米?)(论文)
(1)简介:
- An image is worth 16x16 words
- 将图像拆分为小块,并提供这些小块的线性嵌入序列作为transformer的输入。
- 性能优于CNN,计算资源减小4倍(但目前在显卡上计算效率不高);
- 需要大数据预训练:transformer没有CNN固有的一些先验(平移不变性、局部性),所以在中等数据集不如CNN。
- ViT在设计时尽可能地遵循原始的transformer。
(2)整体流程:
- 先把图像分为16x16块
- 每个块编码为向量,再加上位置编码
- 输入Transformer
- 分类层
3、DETR(详解)
(参考Cheng He) (参考梦里梦到梦?) (参考henaqvmoyi) (参考学无止境) (DETR原文) (看过的最好的讲解视频)
- 缺点:大目标的检测性能显著提高,但小目标检测性能下降
(1)流程简介:
- DETR是将目标检测视为一个集合预测(序列转换)问题。输入一个图像序列,输出为一个位置编码的集合序列。
(2)详细流程:
可以分为4个部分,backbone,encoder,decoder,后处理。
1)CNN Backbone+位置编码
输入图像尺寸为
B
×
3
×
H
×
W
B \times 3 \times H \times W
B×3×H×W,分为位置编码和特征提取两个分支
1.a 上边的分支:位置编码
- MASK编码:因为是固定尺寸输入,所以可能图片中只有一部分是原始图片,其他是padding。需要一个mask区分出原始图片,直接以下采样32倍的尺度绘制mask,与后续对齐。铺平后得到序列形式的Mask
- 位置编码:将位置信息编码为特征图,得到
B
×
256
×
H
32
×
W
32
B\times 256 \times \frac{H}{32} \times \frac{W}{32}
B×256×32H?×32W?的位置信息编码。
- 序列化: 将长宽两维铺平,对其铺平后得到尺寸为
H
W
3
2
2
×
B
×
256
\frac{HW}{32^2} \times B\times 256
322HW?×B×256的序列。
1.a下边的分支:特征提取
- CNN特征提取:(CNN去掉全局池化和线性层,下采样倍数为32,最后一层输出维度为2048),得到 尺寸为
B
×
2048
×
H
32
×
W
32
B \times 2048 \times \frac{H}{32} \times \frac{W}{32}
B×2048×32H?×32W?的特征图。
- 特征图降维:使用1x1的卷积对CNN特征提取得到的尺寸为
B
×
2048
×
H
32
×
W
32
B\times 2048 \times \frac{H}{32} \times \frac{W}{32}
B×2048×32H?×32W?的特征图进行降维,得到尺寸为
B
×
256
×
H
32
×
W
32
B\times 256 \times \frac{H}{32} \times \frac{W}{32}
B×256×32H?×32W?的特征图。
- 序列化: 将长宽两维铺平,对特征图铺平后得到尺寸为
H
W
3
2
2
×
B
×
256
\frac{HW}{32^2} \times B\times 256
322HW?×B×256的序列。
2)Encoder
- 输入:铺平的特征图(特征序列)
- 过程:特征映射
- 输出:与输入相同大小的特征序列
3)Decoder
- 输入:编码器的输出、object queries。
(与BERT不同,不做自回归操作,不把输出重新作为输入,只是one-shot) - object queries是什么:可以理解为100个提问者,每个提问者关注图像的某一区域,如图所示,第一个object query更关注图像的左侧区域,第二个object query更关注图像的中间和偏下区域。
- object queries输入Decoder之后,Decoder做了什么:object queries作为Q,而编码器的输出作为K和V,这可以理解为,提问者向编码器的输出提问,并且自行决定关注编码器的输出的哪些部分。多次询问,以及提问者之间多次互相讨论之后,会得到预测框的输出。
4)后处理:匈牙利算法
4.a 基于CNN的检测算法的label assignment:
(参考:mileistone)
- Faster RCNN/SSD/RetinaNet(Anchor机制):基于anchor与GT框IOU划分正负样本,允许多个anchor同时对应与某一个真值框
- YOLOv1(Grid Cell机制,无anchor):每个Grid Cell最多只负责一个object,遍历真值框,为每个真值框选择一个Grid Cell。
- YOLOv2(Grid Cell机制,有anchor):每个Grid Cell最多只负责一个object,遍历真值框,先为每个真值框选择一个Grid Cell;对于某一个真值框,计算它与它对应的Grid Cell中所有anchor的IOU,选择IOU最大的anchor作为positive;计算它与它对应的Grid Cell中所有proposal的IOU,IoU大于0.6的proposal对应的anchor为ignore。
- YOLOv3:每个Grid Cell最多只负责一个object,遍历真值框,先为每个真值框选择一个Grid Cell;对于某一个真值框,计算它与Grid Cell中所有anchor的IOU(左上角对齐,不考虑位置),选择IOU最大的anchor作为positive;对于某一个proposal,计算它与它对应的Grid Cell中所有gt的IOU,IoU大的ignore。
- FCOS(无anchor):对于每一层feature map,将每个坐标映射到原图,与包围它的GT框对应,有包围则为positive,没有则为negative,同时有多个的话取最小的为positive。
- FreeAnchor:与某一GT的IOU低于0.6的anchor为negative;与某一GT的IOU高的top 50为候选positive,候选positive anchor对应的loss小的则为正式positive;以外的anchor为ignore。
- AutoAssign:对于每一层feature map,将每个坐标映射到原图,与包围它的GT框对应,并不是直接划分正负样本,而是设定权重,positive的权重通过attention的方式来学,negative的权重通过与所有GT框之间最大的IoU负相关地确定。其余grid cell为negative,没有ignore。
4.b DETR的label assignment:
- DETR使用的Loss是L1Loss(xywh绝对误差)和GIouLoss。Decoder的输出经过分类器后会得到100个预测框(有些预测框为空),在计算loss之前需要将预测框与GT匹配。DETR使用匈牙利算法实现该过程,简要来说,就是找到一种匹配方案,使loss总和”最小,是一个存粹的匹配问题,没有参数不需要学习。
- 匈牙利算法的一个简单应用就是任务分配问题:N个人分配N项任务,一个人只能分配一项任务,一项任务只能分配给一个人,将一项任务分配给一个人是需要支付报酬,如何分配任务,保证支付的报酬总数最小。(已知每个人完成每项任务所需要的报酬:NxN的矩阵)。 实现过程可以参考:一点心青
4、Deformable DETR(只言片语)
(1)答案1:
- Deformable DETR比DETR训练快10x
- Backbone、 Matcher 和 positional encoding 的实现和 DETR是一样的
- multi-scale deformable attention
- DETR 中是直接回归的 bounding box 绝对坐标;Deformable DETR 引入了 reference,回归的是基于 point 坐标的 offset。
- head 的部分调整了初始化策略,应该对训练也有帮助
- K=1 的情况本身就相当于在 head 里引入了 Deformable Convolution ,baseline 上来就比 DETR 高了很多
(2)答案2:
- Deformable DETR之于 DETR,应该相当于 ResNet 之于 AlexNet
- 对全连接 Transformer 的计算量进行优化,为每个 query 采样 K 个 key-value pair
- 最大的性能收益,来源于这一方法可以自然地引入多尺度特征。
(3)答案3:
- self-attention的最大意义是在于建立长距离的相互关系,并且能够避免CNN中存在的归纳偏好问题,
- 如果仅仅只在self-attention引入局部的attention操作就会失去self-attention建立长距离相互关系的优点
- deformable attention操作降低self-attention的复杂度,同时保留了self-attention构建长距离相互关系的优点
|