vision transformer
transformer的自注意力机制解读
本质上是对RNN无法实现并行计算的一种改进(并且这种改进本质上就是通过简化的举证乘法来实现的)
使用RNN(单向或者双向)去处理sepuence—to—sepuence时,对于输入序列
因此提出自注意力机制的思想就是:希望对于输出变量
实现方式:在query,key,value的基础上通过矩阵运算实现。
首先,对于输入序列进行embeding得到相应的嵌入编码
在此基础上进一步计算attention值(本质上就是在计算两个向量之间的相似性,相似性越大,那么在对当前向量进行预测是,就应该对其他向量赋予更加多的注意力),计算方式就是简单的向量内积,只需要计算一个权值。
然后得到四个注意力值
在此基础上实现并行计算:首先是完成嵌入编码,在此基础上在计算每一个向量的query、key、value值。嵌入编码
接下来就是query矩阵和key矩阵计算attention值,此处的计算方式是向量的内积。但是本质上还是基于矩阵运算实现,将key矩阵进行转转置即可。然后进行矩阵乘法,这样就能够计算出全部向量的注意力值(每个向量的注意力值本质上也是一个向量)
多头的自注意力机制
将上述的self-attention,扩展为两头计算,对于一个嵌入编码
使用这种多头的注意力机制,就能够实现不同的关注,比如让其中一头的注意力机制更加关心全局信息,另外一头更加关注于局部信息。
位置编码
在上述实现中,将序列中每一个向量都是平等的对待的,并不包含相应的位置信息(在计算key value query时并有考虑相应的位置信息)
在每一个词向量处设定一个位置编码
采取相加而没有采取concat的原因在于:对于采取concat的方式,为保持模型输入的维度必然需要与transformation矩阵做乘法,在做完乘法后实际上也就转化为了相加的形式:
位置编码的实现方式:
pos是单词的位置,i是Positional Encoding的维度,取值范围是:
使用self-attention替代encoder-decoder中的RNN:
将这种自注意力机制应用于图像处理,也就是在处理当前像素时,可计算整张图像的attention值,原本的固定的CNN的感受野,转变到现在的自学习的感受野。
transformer的总体架构
- encoder部分
在上述框架中encoder部分,绿色的block总计有n个,并且编码的方式为(FFN是一个前馈网络):
- decoder阶段
在decoder阶段,绿色的block部分依旧会重复N次,Masked Multi-Head Self-attention,masked的意思是使attention只会attend on已经产生的sequence。
decoder的输出是,对应i位置的输出词的概率分布。
在transformer中的encoder过程是能够实现并行计算的,但是在decoder阶段并不能进行并行计算。需要按照RNN的方式去进行处理。(实际上只有在测试阶段才会采取RNN的方式去进行处理,在训练阶段通过mask的方式依旧是在进行并行运算的。)
- 包含两个 Multi-Head Attention 层。
- 第一个 Multi-Head Attention 层采用了 Masked 操作。
- 第二个 Multi-Head Attention 层的Key,Value矩阵使用 Encoder 的编码信息矩阵
进行计算,而Query使用上一个 Decoder block 的输出计算。 - 最后有一个 Softmax 层计算下一个翻译单词的概率(上述条件是对每一个decoder层都成立的)
此处的mask操作,为的是在翻译的过程,处理第i个单词时只能使用与第i个以及它之前的信息,在self-attention的基础上加入了一个mask操作。
在上图的实现方式中:
- 输入矩阵包含 “\< Begin > I have a cat” (0, 1, 2, 3, 4) 五个单词的表示向量,Mask是一个 5×5 的矩阵。在Mask可以发现单词 0 只能使用单词 0 的信息,而单词 1 可以使用单词 0, 1 的信息,即只能使用之前的信息。
得到 Attention矩阵 ,此时先不急于做softmax的操作,而是先于一个 Mask矩阵相乘,使得attention矩阵的有些位置归0,得到Masked Attention矩阵 。Mask矩阵是个下三角矩阵,想在计算矩阵的某一行时,只考虑它前面token的作用。即:在计算第一行时,刻意地把矩阵第一行的后面几个元素屏蔽掉,只考虑 。在产生have这个单词时,只考虑 I,不考虑之后的have a cat,即只会attend on已经产生的sequence,这个很合理,因为还没有产生出来的东西不存在,就无法做attention。 - Masked Attention矩阵进行 Softmax,每一行的和都为 1。但是单词 0 在单词 1, 2, 3, 4 上的 attention score 都为 0。得到的结果再与
矩阵相乘得到最终的self-attention层的输出结果 - 将多头注意力机制的结果进行concat,做线性变换输出最终的结果。
注:第2个Multi-Head Self-attention的query来自第1个Self-attention layer的输出,key、value来自Encoder的输出
通常将key、value视为句子/图片的内容信息,将query视为一种引导信息(那么在decoder中,这种引导信息的来源就是已经完成翻译的词向量)
最后得到transformer的总体结构:
vision transformer的前向传播基本流程
patch & position embeding
思想:将CV问题也转化为seq2seq问题,并且需要减少计算的复杂度。
实现:将一个
在此基础上加入一个额外的token(借鉴nlp领域,cls)在transformer encoder中计算的是每个patch之间的自注意力,无法选择最终哪一个patch的输出去实现分类,因此加入一个cls,让他和其他的patch进行注意力的计算,将cls的输出作为分类的依据,因此输入encoder的矩阵为
位置编码:使用一个表实现,表总计196行(和patch的数量保持一致),每一行对应的一个向量,向量的维度为768,对于位置信息是直接加到输入向两中的(直接做对应位置的加法)
transformer encoder
接下来就是一个标准的transformer的encoder,首先是layer norm 维度不发生改变,在此基础上转化为三个 q,k,v,三个 q,k,v的维度和多头自注意力的头数有关,假设存在n个头,那么每一个 q,k,v的维度就是
在后续的MLP层中,通常是先将维度放大四倍,在对其进行还原。最终序列的输出依旧是