【Transformer】Transformer 网络解析(Self-Attention 、Multi-Head Attention、位置编码、Mask等)
文章目录
1. 介绍
原论文地址:Attention Is All You Need
近年来,Transformer在CV领域很火,Transformer是2017年Google在Computation and Language上发表的,当时主要是针对自然语言处理领域提出的。
- 之前的RNN模型记忆长度有限;且无法并行化,只有计算完 时刻后的数据才能计算 时刻的数据,
- 但Transformer都可以做到。
在《Attention Is All You Need]》中作者提出了Self-Attention的概念,然后在此基础上提出Multi-Head Attention,所以本文对Self-Attention以及Multi-Head Attention 等理论进行讲解。
2. 模型
2.1 Self-Attention
为了便于理解,假设输入的序列长度为2,输入就两个节点 ,然后通过Input Embedding也就是图中的 将输入映射到 。紧接着分别将 分别通过三个变换矩阵(这三个参数是可训练的,是共享的)得到对应的 (这里在源码中是直接使用全连接层实现的,这里为了方便理解,忽略偏置参数 b)。
- 代表query,后续会去和每一个 进行匹配
- 代表key,后续会被每个 匹配
- 代表从 原始特征 中提取得到的信息
后续 q 和 k 匹配的过程可以理解成计算两者的相关性,相关性越大对应 v(value) 的权重也就越大。
接着先拿 和每个 进行match,点乘操作,接着除以 得到对应的权重 α,其中 d 代表向量 的维度。在本示例中等于2。
- 注意:除以 的原因在论文中的解释是:“进行点乘后的数值很大,导致通过softmax后梯度变的很小”,所以通过除以 来进行缩放。比如计算 :
到这儿,我们就完成了 公式中 部分。
到这,Self-Attention 的内容就讲完了。总结下来就是论文中的一个公式:
2.2 Multi-Head Attention
接下来是 Multi-Head Attention(多头注意力)模块,实际使用中基本使用的还是Multi-Head Attention模块。原论文中说使用多头注意力机制能够联合来自不同head部分学习到的信息:
- Multi-head attention allows the model to jointly attend to information from different representation subspaces at different positions.
其实只要懂了Self-Attention模块Multi-Head Attention模块就非常简单了。
- 首先还是和Self-Attention模块一样将 a 分别通过 得到对应的 q , k , v;
- 然后再根据使用的head的数目 h 进一步把得到的 q, k, v 均分成 h 份。
比如下图中假设h = 2,然后 拆分成 和 ,那么 就属于head1, 属于head2。
接着将每个head得到的结果进行concat拼接,比如下图中 ( 得到的 )和 ( 得到的 )拼接在一起, ( 得到的 ) 和 (head_2$ 得到的 ) 拼接在一起。
2.3 Self-Attention与Multi-Head Attention 对比
原论文章节 3.2.2 中有说两者的计算量其实是差不多。
- Due to the reduced dimension of each head, the total computational cost is similar to that of single-head attention with full dimensionality.
可以简单的尝试一下,这个Attention就是实现Multi-head Attention的方法,其中包括上面讲的所有步骤。
- 首先创建了一个Self-Attention模块(单头)a1;
- 然后把proj变量置为Identity(Identity对应的是Multi-Head Attention中最后那个 的映射,单头中是没有的,所以置为Identity即不做任何操作);
- 再创建一个Multi-Head Attention模块(多头)a2,然后设置8个head;
- 创建一个随机变量,注意shape;
- 使用fvcore分别计算两个模块的FLOPs。
注:FLOPs 为每秒浮点运算次数,也就是所用的时间。
通过实验发现:
- 可以发现确实两者的FLOPs差不多,Multi-Head Attention比Self-Attention 略高一点。
- 其实两者FLOPs的差异只是在最后的 上,如果把Multi-Head Attentio的 也删除(即把a2的proj也设置成Identity),可以看出两者FLOPs是一样的。
- 总结:可能是由于线性的相乘关系(矩阵乘法优化),导致多头和单头是差不多,差距也就在于多头比单头多了个映射。
2.4 Positional Encoding
上述所讲的 Self-Attention 和 Multi-Head Attention 模块,在计算中是没有考虑到位置信息的。假设在Self-Attention模块中,输入 得到 。对于 而言,
和 离它都是一样近的而且没有先后顺序。
- 假设将输入的顺序改为 ,对结果 也是没有任何影响的。
因此,为了引入位置信息,在原论文中引入了位置编码 positional encodings。
- To this end, we add “positional encodings” to the input embeddings at the bottoms of the encoder and decoder stacks.
如下图所示,位置编码是直接加在输入的 中的,即 和 拥有相同的维度大小。
关于位置编码在原论文中有提出两种方案,
- 一种是原论文中使用的固定编码,即论文中给出的sine and cosine functions方法,按照该方法可计算出位置编码;
- 另一种是可训练的位置编码,作者说尝试了两种方法发现结果差不多(但在ViT论文中使用的是 可训练 的位置编码)。
2.5 Mask
mask是Transformer中很重要的一个概念,mask操作的目的有两个:
-
让padding (不够长的补0) 部分不参与attention操作。(每个句子的序列长度不同)
-
在生成当前词语的概率分布时,让模型不会注意到这个词后面的部分,避免利用未来信息。
在自注意力机制中,每个位置都会与所有其他位置进行交互,因此为了避免模型在预测时利用未来信息,需要将未来位置的信息掩盖掉。在编码器中,需要将输入序列中不够长的部分进行mask,而在解码器中,还需要将当前位置之后的位置进行掩盖,以避免模型利用未来信息。掩盖的方式可以是将对应位置的注意力权重设置为0,或者将对应位置的输入向量设置为一个特殊的掩码向量。
2.5.1 padding mask
这个很好理解,下面就是一个mask矩阵,这个mask矩阵表示的是这个句子只有两个单词,句子后两个词是padding的内容,所以全都是0(假设序列长度为4)。我们在进行attention时不应该将这里考虑进attention,当给mask矩阵为0的对应位置替换一个负很大的值后,相应attention的结果就会趋近为0。
2.5.2 Masked Multi-Head Attention中的Mask
这个稍微复杂一点,我们先看看对应的mask矩阵(下三角矩阵),与得到的权重矩阵 点乘,进而可以屏蔽掉未来的位置。
3. 参考
【1】https://blog.csdn.net/qq_37541097/article/details/117691873
文章出处登录后可见!