Transformer
Layer Norm
Batch Norm(左): 在每个batch里,将特征均值变成0,方差变成1,如下蓝色,不同batch的相同feature维度做norm
Layer Norm(右): 在同一batch的不同feature里做norm
在实际训练中数据是(Batch*Seq*Feature),不同batch对应的seq的长度不同,然而又用了等长的feature表达。样本长度变化较大的时候,均值和方差的抖动比较大。Layer Norm在每个样本内部算均值和方差,较为稳定。
Attention
从整个序列中提取信息。尤其是self-attention,从自身中提取所有信息,再根据q-k找出相似度最大的信息,也就是有用的信息作为了特征向量。
例如给出一个q “hello”,根据q “hello”的vector去整个序列中计算点乘,越大的代表相似度(compatibility)越大,越小的代表相似度越小(比如空间上垂直)(e.g. “hello”和“hi”的相似度应该越大)。得到所有key和q“hello”的相似度之后,再再各个维度上根据相似度加权计算v,得到attention的output。
output再经过后面的Feed-Forward层等投影到目标的语义空间。
Multi-head Attention
有了上面的概念,类似于CNN不同通道的不同filter,使用不同head的attention可以提取出不同特性的信息。
Transformer实现的意义和RNN是一样的,将时序信息传递给输入进行计算,实现时序信息的传递。RNN中是前一时刻传递给后一时刻,Transformer中是通过attention在全局的序列中提取信息。又由于Transformer中不同信息可以并行从query中抽取,效率高于顺序时序的RNN。
DETR (DEtection TRansformers)
End-to-end Object Detection with Transformers
相比Faster R-CNN等做法,DETR最大特点是将目标检测问题转化为无序集合预测问题(set prediction)。论文中特意指出Faster R-CNN这种设置一大堆anchor,然后基于anchor进行分类和回归其实属于代理做法即不是最直接做法,目标检测任务就是输出无序集合,而Faster R-CNN等算法通过各种操作,并结合复杂后处理最终才得到无序集合属于绕路了。现在核心问题来了:输出的 (b,100) 个检测结果是无序的,如何和 GTBounding Box 计算loss?这就需要用到经典的二分图匹配算法了,也就是常说的匈牙利算法。
图解总结DETR的四步:
1. CNN抽取特征
2. Transformer的encoder,学习全局特征
3. Transformer的decoder,生成多个预测框
4. 预测框和GT做匹配,求得loss(推理的话,就是根据置信度阈值输出各个预测框的目标类型)
Object detection set prediction loss
二分图匹配问题:DETR的预测结果是大小为N(固定)的集合(也就是N个预测框),因此需要将所有N个框与GT的框进行匹配,计算loss。解决方案是scipy.linear_sum_matrix,在位置重叠度和分类正确度二者中找到最优解,也就是找到每个GT框对应的唯一框。
目标检测的目标函数如上图
object queries: learnable position embedding,类似于anchor的概念
总述:先根据CNN提取特征,得到向量与相同大小的position embedding层相加,然后长宽拉直作为transformer encoder的输入。encoder输出一个与输入大小相同的向量,与object queries在decoder处做attention,得到对应各个检测框的特征向量 ,再将特征向量送给FFN进行一个类别和位置框的预测。最后匈牙利算法二分图匹配,计算loss再反向传播。
论文代码解析(36行实现,无敌)
超参:row 33,nheads是multi-head attention
模型初始化:backbone是ResNet50
前向过程:没什么特别的,pos是position embedding的向量,h是上面100*256的特征向量
Attention的可视化实验,突出输出各个点的attention区域(上encoder/下decoder):
可见decoder明显attention到了很多边缘特征,类似于u-net,恢复细节的效果
ViT
paper title: an image is worth 16x16 words
意思就是把一张图分成16x16的patch,每个patch里做attention
contribution
将attention用到cv领域,同时减少拉直的图片的序列长度
将transformer直接用于cv,尽量少的修改
ViT在ImageNet上比CNN第几个点,是因为CNN自带的两个inductive biases,相当于是强先验信息:
1.sliding window:基于图片上相邻区域具有相邻特征
2.translation equivalent:类似于平移不变性的意义,没有特别懂
所以效果体现:在更大的数据集上,vis transformer>>cnn
Transformer在nlp领域,自监督的训练方法,BERT是“denosing完形填空”,GPT是“next word prediction”。视觉Transformer的各种其他的改进attention方式确实有效,但是需要大量的设计进行GPU训练的加速,在部署实现上有困难。
ViT模型图如下
图像切割成16x16的patch之后,分别做patch embedding(将各个patch图像经过linear projection的全连接层)和position embedding(根据patch位置的特征向量),二者直接sum上,再在首部接上cls token,作为Transformer encoder输入的seq。seq经过multi-head attention,
最难以理解的地方 - Extra Learnable Embedding: CLS Token/Embedding
CLS Token就是在输入seq最前面加上一维,初始化为0。由于没有给他初始信息,他有从所有的seq成员token都相互做了attention,那么这个cls token的所有信息都是从所有其他token处学到的信息,最后认为可以拿来表示所有token的特征。在nlp中cls token的特征代表的是句子级别的意义,换到图像上cls token的输出就代表了整个图像也就是所有像素的整体语义。最后只用拿出cls token的特征向量(也就是整个output seq的第0维),作为整张图片提取出的特征向量,直接丢进MLP就能够实现分类任务。
补充:当然这个拿来做classification是有道理的,拿其他token经过Transformer的输出的特征表示也是有道理的,或是取global max/mean pooling等等,实验证明都可以,不同任务有不同的做法…
下图是用cls token做分类,和用以往feature map做分类的准确率比较:
总结下和原始transformer编码器不同的地方:
- 输入编码器的位置编码需要考虑2-D空间位置。
- 位置编码向量需要加入到每个Encoder Layer中。
- 在编码器内部位置编码Positional Encoding仅仅作用于Query和Key,即只与Query和Key相加,Value不做任何处理。