上图中,Encoder与Decoder中红色圈中的部分为 Multi-Head Attention ,是由多个 Self-Attention组成的,虽然Encoder与Decoder中都有Multi-Head Attention,但他们略有区别:
- Encoder block 包含一个 Multi-Head Attention
- Decoder block 包含两个 Multi-Head Attention (其中一个用到 Masked)
- Decoder 的第二个多头注意力数据组成:
1). encoder数据输出之3/4入Multi-Head Attention(后1/4入Add&Norm层)
2). 从Decoder's OutputEmbeeding进来的数据,过Masked多头注意力并经过Add&Norm后的数据
什么是多头注意力
所谓多头,是将线性的变换之后的QKV切分为H份,然后对每一份进行后续的self-attention操作。如下图:
在上图的多头注意力结构中,中间的Scaled Dot-Product Attention为自注意力部分(Self-Attention 层), 被切分成了H头。可以理解为高维向量拆分为H个低维向量,并在H个低维空间里求解各自的self-Attention。
实现方法:先将由[batch-size、seq-len、dim]得到的向量x传递到h个不同的Self-Attention中。再将其拆分成H份,按[batch_size, seq_len, h, dim/h]在H个低维空间里求解各自的self-Attention
矩阵拆变分析如下
csharp
[batch-size、seq-len、dim]
[batch_size, seq_len, h, dim/h]
---举例---
[1024, 5, 512 ]
[1024, 5, 8, 512/8]
H是指折分的份数,将头数(Head) In transformer: H=8
多头注意力的意义
代码层面 把原始的维度切成H份,假如切成8份(h=8) 每份是512/8=64,在每个64维做相关度(即相乘)计算
原理层面 把原来在一个高维空间里衡量一个文本的任意两个字之间的相关度,变成了在8维空间里去分别衡量任意两个字的相关度的变化
工作原理
- 经过position embedding 与 word embedding 计算后得到的向量x进入Encoder,经过3次线性变化之后,得到 Q K V ,如下图:
-
进入Q/K/V的空间:第一张图仍然是一个完整的数据矩阵,经过第一次维度(batch_size)得到图右侧第1列,然后我们再次矩阵水平切为每行 (seq_len * 512维的信息) 数据(如下图右侧第二列),再以此按维度再切成H份(如最右侧的第三列)。再然后,计算一个字的维度,即将一个字分成H分,每一份为
512/H
维信息,那么一个完整的字一共有512/H
维度的信息。如下图: -
比如 "我" 字,按h=8拆分,得64(512/8) 维的信息。接下来再把我字的第一个64维度的信息分别和其他字的第一个64维的信息进行向量相乘。如果相乘的结果越大代表两个向量相似度接高,越小两个向量的相似度越低。如下图,右侧说明一个序列的第1个字的64维分别与其他字的第一个64维的向量相乘(对于我要吃汉堡,一共是5个字,对应右侧的5个图,从左到向,从上一下:我 想 吃 汉 堡)。
-
经过上图的拆分,由原来在512的大的维度空间里计算相似度,变成了在H个不同的(
512/H
) 维的子空间里分别去计算任意两个字的相似(关)度。
比如:原来只进行1次的512 * 512的向量相乘 现在变 进行8次 64 * 64 这样的向量相乘,即把原来的高维空间映射成了8个不同的64维的子空间,在每次64维的子空间时在,分别去衡量这一序列字词之任意两个字之间的相似度。进而提升模型的表达能力。
拆分成多个维度的的具象模型, 如下图:
- 当拆分计算完成即相乘之后,形成如下右图所示的矩阵. 下图右则第一个格子的相似关是: Q* Kt ,其他格子也是..最后再聚合起来(线性变化)成为一个512维的矩阵。
辅助向量QKV
在《Attention is all you need》论文中首次提出Transformer时构建了三个辅助向量QKV。而所谓QKV也就是Q(Query),K(Key),V(Value)。 他们本质上是代表了三个独立的矩阵,都是我们原本的序列X做了不同的线性变换之后的结果,都可以作为X的代表。
分析计算如下:
为了得到注意力矩阵,我们是先需要两个X的代表矩阵,用来计算相似度(计算相似度至少要有两个向量才),而Q和K就是用于这个工作的。相似度计算可以直接做点乘也可以用个MLP来计算等,计算之后再将结果经过一个softmax来保证输出的是attention weight,也即保证和为1 (否则用这个attention matrix的时候数据的scale会不断的变)。
得到了attention matrix之后要做的就是将这个weight用在X上,也即我们剩下的那个vector V身上。做法就是将attention matrix和V相乘求和即可得到最终结果。如下图:
我们可以把图中的Thinkin和Machine看成是x1和x2两个向量,x1需要计算与x2的关系,还需要计算x1与自己的关系,x1和x2都会通过训练生成属于自己的Q,K,V(计算x1与x2之间的关系是在x1与x2在生成各自的Q,K,V之后进行的)。
三个需要训练的矩阵分别表达的意义是:Q(查询),K(键值),V(值,实际的特征信息)
计算公式
其中 <math xmlns="http://www.w3.org/1998/Math/MathML"> W Q , W K 和 W V W^Q,W^K和W^V </math>WQ,WK和WV是三个可训练的参数矩阵,输入矩阵X分别与 <math xmlns="http://www.w3.org/1998/Math/MathML"> W Q , W K 和 W V W^Q,W^K和W^V </math>WQ,WK和WV相乘,生成Q, K和V, 相当于经历了一次线性变换。Attention不直接使用X,而是使用经过矩阵乘法生成的三个矩阵,因为使用了一次性变换,Attention不直接使用X,而是使用经过矩阵乘法生成的这三个矩阵,因为使用了三个可训练的参数矩阵,可增强模型的拟合能力。
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"> Q = X W Q K = X W K V = X W V Q = XW^Q \\ K = XW^K \\ V = XW^V \\ </math>Q=XWQK=XWKV=XWV
自注意力-Self-Attention
结构
上图是 Self-Attention 的结构,在计算的时候需要用到矩阵Q(查询),K(键值),V(值) 。在实际中,Self-Attention 接收的是输入(单词的表示向量x组成的矩阵X) 或者上一个 Encoder block 的输出。而Q,K,V正是通过 Self-Attention 的输入进行线性变换得到的。
自注意力机制将一个单词与句子中的所有单词联系起来,从而提取每个词的更多信息。
Q与 <math xmlns="http://www.w3.org/1998/Math/MathML"> K t K^t </math>Kt经过MatMul,生成相似度矩阵。对相似度矩阵每个元素除以 <math xmlns="http://www.w3.org/1998/Math/MathML"> d k \sqrt{d_k} </math>dk ,其中dk为K的维度大小。这个除法被称为Scale。 当 <math xmlns="http://www.w3.org/1998/Math/MathML"> d k d_k </math>dk很大时,Q* <math xmlns="http://www.w3.org/1998/Math/MathML"> K T K^T </math>KT的乘法结果方法变大, 进行Scale可使方差变小,训练时梯度更新更稳定。
Mask是机器翻译等自然语言处理任务中经常使用的环节。在机器翻译等NLP场景中,每个样本句子的长短不同,对于句子结束之后的位置,无需参与相似度的计算,否则影响Softmax的计算结果。
公式
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"> A t t e n t i o n ( Q , K , V ) = s o f t m a x ( Q K T d k ) ∗ V d k 是 Q , K 矩阵的列数,即向量维度 Attention(Q,K,V) = softmax(\frac{QK^T}{\sqrt{d_k}})*V \\ \\ d_k是Q,K矩阵的列数,即向量维度 </math>Attention(Q,K,V)=softmax(dk QKT)∗Vdk是Q,K矩阵的列数,即向量维度
Transformer论文中将这个Attention公式描述为 Scaled Dot-Product Attention。其中,Q为Query、K为Key、V为Value。Q、K、V其实都是从同样的输入矩阵X线性变换而来的(QKV见"KVQ向量章节")
公式推导分析:
- 先计算softwax,当输入为词向量矩阵X(每个词为矩阵中的一行),经过与三个系数 <math xmlns="http://www.w3.org/1998/Math/MathML"> W Q , W K W^Q,W^K </math>WQ,WK和 <math xmlns="http://www.w3.org/1998/Math/MathML"> W V W^V </math>WV 进行矩阵乘法,首先生成Q、K和V。 如下图:
-
得到 <math xmlns="http://www.w3.org/1998/Math/MathML"> Q K T QK^T </math>QKT之后,使用Softmax计算每一个单词对于其他单词的attention 系数,公式中的 Softmax 是对矩阵的每一行进行 Softmax。
-
得到 Softmax 矩阵之后可以和V 相乘,得到最终的输出Attention(Q,K,V) 。如下图:
- 最后再经过一个Conca(聚合)再经过Linear(线性变换) ,得到最后的整个多头注意力机制的输出。如下图与公式再展示。
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"> A t t e n t i o n ( Q , K , V ) = s o f t m a x ( Q K T d k ) ∗ V Attention(Q,K,V) = softmax(\frac{QK^T}{\sqrt{d_k}})*V </math>Attention(Q,K,V)=softmax(dk QKT)∗V
------ 笔记写于:2023年11月07日凌晨