之前一直用transformer做各种工作,但self-attention 中的QKV 矩阵是啥意思,为啥相乘感觉一直没太理解,今天好好研究了一下,记录下。参考:自然语言处理:从SimpleRNN到BERT - 飞桨AI Studio星河社区 (baidu.com)
1.Seq2Seq+Attention
说self-attention就要先理解下attention到底是咋个意思。Attention 思想主要是来自于Seq2Seq 中。这里假设Seq2seq 的网络层是RNN,在做Seq2Seq 时,网络架构是这样的
详细说明下:
x1,x2...xm 是输入数据,一般都是经过embedding 后的数据,然后A 是RNN , 一个RNN网络输出有两个,一个是直接结果h1, 另一个是隐藏状态,直接传给了下一时刻。Seq2Seq Decode 的最开始输出有两个,一个是x`1,一个是RNN encode层中最后的输出结果,然后传到了Decode层中,这里x`1一般都是start 或者其他的起始状态值,是给定好的。接下来就继续执行,x`2 是x`1+S0 走一次RNN后,得到的状态S1, S1在接分类器得到的结果,x`3.....x`t 就是这么来的。但这里存在的问题就是如果输入过长,就回存在遗忘的问题。LSTM 是一个解决办法,但太长还是不行,就要引用了Attention。
先上图
这里比上图多了C0...Ct,这个就是Attention 的Context Vector。也就是说,decode 层在输出结果是,要考虑到这个Context Vector。
Context Vector是encode 层所有输出状态的加权平均,记为Ct,对于每一个Decode层的St,都要考虑这个Ct,
在没有使用attention前,St的计算方式为
使用attention后, St 计算方式为:
将状态从S0更新为S1。再计算C1,然后根据公式将状态从S1更新为S2。如此直至生成最后一个状态ST
那这个Ct 该如何计算呢,方法如下:
首先对所有的hi 使用一个权重矩阵WK 做线性变化,得到Ki 向量,对于S0, 使用一个WQ 权重矩阵也做线性变换,得到q0,
计算Ki 和q0 的内积,得到α0i, i∈(0,m),然后对α0i做Softmax变化,然得到的α0i, 然后S0 时刻的C0 = α00 *h0 +α01*h1+...α0m*hm,然后将这个结果带入attention s1 计算公式,就得到了s1,r然后依次类推,直到得到st.
其实在这里就已经用到了Q、K、V了。这里的Q是St 生成的矩阵向量,K是hi 生成的矩阵向量。V 是α00 *h0的值。可以理解为,St 查询hi位置的权重值。
2.Attention层
在上面的描述可以看到,其实RNN 网络并没有干啥事,就这做了一个输出的作用,那我能不能不要它了,直接上矩阵向量?答案是可以的,这就形成了单独Attention层。
首先是Encode层,通过rnn产生了hi,然后又对hi 使用权重矩阵相乘,得到Ki。在摒弃RNN 后,直接对输入的embedding 向量做WK权重相乘,得到K1, 然后用用一个Wv矩阵相乘,代替hi,得到如下结果
对于Decode 层,还是先从S0 开始,(S0 也是被embedding过了),先乘上一个Wq 权重矩阵得到qi,和上面一样,
就得到S0 状态下的α0i,
(偷懒了,直接粘贴了,主要感觉这个项目的作者要写的更明白一些)
对于我们训练网络来说,其实输入和输出都是已知的,这样就可以直接将X`1..X`n 带入,而不需要在做分类处理。这样一来我们就直接求Cn就可以得到Attention层了。
3. Self-Attention
理解了Attention 其实self-attention 就比较好理解了。Self-attention 可以理解为Attentio的特殊情况,即decode层还是他自己。本来在Attention 中的qi 还是需要输出数据与Wq 矩阵相乘得到,现在就不用输出数据了,直接还用本来的数据,可以理解为这样
更直观的就变成了这样
计算的过程还是和Attention 时一样,先从decode的x1 开始(但这里不再是start标识符了,而是数据),算decode x1 对多有encode x1...xm的权重值。
这里表明了权重值的意义高亮标注单词为权重α比较大的位置。权重表明了前文中最相关词的位置,即α表明了当前的输入与前文哪些词相关性较大。
4. 多头Self-Attention(Multi-Head Attention)
Transformer 里用的就是多头自注意力层,多头Self-Attention层由l个单头Self-Attention组成,每个单头Self-Attention相互独立,不共享参数。每个单头Self-Attention存在3个参数矩阵WQ,WK,WV,由l个单头Self-Attention组成的多头Self-Attention层共存在3l个参数矩阵
Bert Ernie 中都是用了8个注意力头。
以上文章的图像都来自于 AIStudio 项目:自然语言处理:从SimpleRNN到BERT - 飞桨AI Studio星河社区 (baidu.com)
如果觉得不清晰,可以去这个项目上看看,比较清楚。