文章目录
解决的task类型:输入是向量序列的问题
从待解决的tasks出发,如何将已有信息编码为向量序列
文字处理中的word embedding、one-hot encoding
语音识别中的声音信号编码,将声音信号的一帧编码为一个向量
用图表示的各种网络(社交网络)(药物发现task)中用一个向量编码图中一个顶点
输入为向量序列tasks分类
- 输入和输出数量相同:向量序列中每个向量对应一个输出
文字处理之词性标注(Part-Of-Speech Tagging, POS tagging)、经过预处理得到一串向量表示的声音讯号识别得到音标、社交网络中节点预测 - 输入是一个向量序列,输出是一个标签/scalar
情感分析(sentiment analysis)
语音识别说话人
图之分子性质预测 - 输入是一个序列,输出也是一个序列,且输出长度无法确定(Sequence to Sequence任务)
翻译
语音识别
运作原理
以input and output with the same length的情况,序列标注为例
使用全连接网络(fully-connected network)的问题:无法很好地考虑向量序列中向量之间的上下文的信息
fully-connected network专注于处理某一位置的信息,self-attention处理整个序列的信息
self-attention的运作过程:每一个输入向量
a
i
a^i
ai 在input序列中找到与之相关的其他向量,关联程度用
α
\alpha
α 来表示,用
α
\alpha
α 来决定
a
j
a^j
aj 在
b
i
b^i
bi的计算过程的参与程度,然后利用input vectors每一个vector与当前计算vector之间的
α
\alpha
α 得到output vector
计算注意力分数的策略:self-attention中注意力分数的计算:查询-键-值(Query-Key-Value)模式
点积(dot product):将
a
i
a^i
ai 和
a
j
a^j
aj分别乘上两个不同的矩阵
W
q
W^q
Wq和
W
k
W^k
Wk 得到两个向量
q
q
q和
k
k
k ,将
q
q
q和
k
k
k做点积,得到
α
\alpha
α
即计算出
a
i
a^i
ai和各个向量的关联性,在self-attention中使用点乘策略计算注意力分数如图所示
再使用softmax操作处理得到的注意力分数,得到归一化后的注意力分数
最后对input序列中重要信息进行抽取——使用矩阵
W
v
W^v
Wv处理input向量序列,得到新的向量
v
1
v^1
v1、
v
2
v^2
v2、
v
3
v^3
v3、
v
4
v^4
v4 再对这些向量使用注意力分数进行加权和(weighted sum)操作得到
b
i
b^i
bi
b
i
=
∑
j
α
i
,
j
′
v
j
b^i = \sum_j\alpha'_{i,j}v^j
bi=∑jαi,j′vj
ps:不一定要用softmax作为激活函数进行处理,甚至ReLU的结果会好于softmax
使用矩阵乘法角度重新阐释自注意力机制的运作
查询-键-值的计算得到过程:向量
a
i
a^i
ai乘上矩阵
W
q
W^q
Wq、
W
k
W^k
Wk、
W
v
W^v
Wv 得到向量
q
q
q、
k
k
k、
v
v
v
我们可以将所有input向量拼起来得到一个矩阵
I
I
I,作为矩阵乘法右项,乘法结果的每一列即对应input向量经过变换的向量结果
注意力分数的计算:
根据
α
1
,
1
\alpha_{1,1}
α1,1由
k
1
T
k_1^T
k1T和
q
1
q_1
q1做内积得到
α
1
,
2
\alpha_{1,2}
α1,2由
k
2
T
k_2^T
k2T和
q
1
q_1
q1做内积
α
1
,
3
\alpha_{1,3}
α1,3由
k
3
T
k_3^T
k3T和
q
1
q_1
q1做内积
通过归纳推理,我们可以得到将所有的
k
i
T
k_i^T
kiT(行向量)排列成的矩阵和所有的
q
i
q_i
qi(列向量)排列成的矩阵相乘得到矩阵
A
A
A, 则
A
A
A中每个元素
a
i
,
j
a_{i,j}
ai,j都是向量
a
j
a_j
aj在向量
a
i
a_i
ai上的注意力分数
归一化注意力分数:使用softmax函数使
A
A
A中每一列的值之和为1,得到矩阵
A
′
A'
A′ 即注意力矩阵(attention matrix)
用注意力矩阵
A
′
A'
A′与向量
v
v
v排列成的
V
V
V矩阵做乘积得到的结果即self-attention层的输出
O
O
O
解释:对于attention matrix一列的数据就是对应一个向量的self-attention变换的参数,于是需要把
A
′
A'
A′放在右边,按照列的顺序进行计算
总结:self-attention机制里面没有超参数,需要模型迭代学习的参数只有
W
q
W^q
Wq、
W
k
W^k
Wk、
W
v
W^v
Wv
多头注意力(multi-head self-attention)
提出melti-head self-attention是为了解决计算相关性的问题,因为相关有多种不同的形式,一个
W
q
W^q
Wq、
W
k
W^k
Wk、
W
v
W^v
Wv 往往只能得到一种相关形式,为了充分发掘向量序列中向量之间的联系,引入了多头机制
怎么做?
得到多头的方法:向量
a
a
a经过transform得到的向量
q
q
q再经过两个不同的transform,得到
q
i
,
1
q^{i,1}
qi,1和
q
i
,
2
q^{i,2}
qi,2 ,与之对应的有
k
i
,
1
k^{i,1}
ki,1和
k
i
,
2
k^{i,2}
ki,2,
v
i
,
1
v^{i,1}
vi,1和
v
i
,
2
v^{i,2}
vi,2
self-attention的过程:将
q
i
,
1
q^{i,1}
qi,1与
k
i
,
1
k^{i,1}
ki,1做点积得到
α
i
,
1
\alpha^{i,1}
αi,1 ,
α
i
,
1
\alpha^{i,1}
αi,1 和
v
i
,
1
v^{i,1}
vi,1得乘积,经过weighted sum最终得到
b
i
,
1
b^{i,1}
bi,1
多个头得到的
b
i
,
1
b^{i,1}
bi,1和
b
i
,
2
b^{i,2}
bi,2接起来,经过transform 得到最终的输出
b
i
b^i
bi
位置编码
当前的自注意力层没有考虑input向量组的位置信息:各个input向量同等地参与计算,改变向量组的排布不会影响output向量。
但实际上位置信息是很重要的,比如在词性标注task中,我们可以通过领域知识得到动词不容易出现在句首,那么我们可以利用这一点说如果一个词汇在句首,那它是动词的可能性是比较低的。
也就是说位置信息往往是有用的,我们需要在自注意力层考虑input向量的位置
位置编码(positional encoding):为每一个位置设定一个向量,即位置向量(positional vector)。第
i
i
i个位置的位置向量用
e
i
e^i
ei来表示。
位置向量的使用:将
e
e
e加到
a
i
a^i
ai上面
产生位置向量的方法:
"Attention Is All You Need"中使用的正弦函数产生
使用循环神经网络产生
截断自注意力
将自注意力机制用于其他领域的问题中
语音处理中的自注意力:
因为声音信号的表示会有大量的向量作为input,自注意力机制中向量内积计算量是一个
L
2
L^2
L2的数量级,并且这对内存要求也很高
为了解决向量序列长度过大的问题,使用截断自注意力(truncated self-attention)
如何实现:人为限定使用自注意力的范围,而非整个向量序列
自注意力VS卷积神经网络
将自注意力用于图像
一张图像可以视为一个向量序列,一个像素视为一个向量。
对比Self-Attention和CNN可知:
self-attention用于图像时,做内积会考虑整个图像的信息;而CNN则会选定一个感受野(receptive field),每一个filter只处理一个一个receptive field中的信息。
CNN可视作简化版的self-attention,self-attention中也可以引入receptive field的概念,一个input vector的所有关联程度大的input vectors就组成了它的receptive field。则我们可以说self-attention是让机器将感受野学习到,而CNN的receptive field是作为超参数人为设定的。
那这样一个结论会带给我们什么启发呢?
更灵活的模型需要更多数据来训练,若数据不够可能overfitting,而比较有限制的模型,适合在数据少的情况下使用,因为它更不易overfitting
或许我们可以在有大量数据的情况下使用self-attention替代CNN完成图像处理tasks
Google将self-attention和CNN在图像识别问题上的性能进行了对比。
另外这个结论也是在大数据时代跟传统统计学相悖的"the virtue of parsimony"的体现
自注意力与循环神经网络对比
- RNN的输入是一个个的向量,针对每一个input vector,都有一个用于记忆的表示隐状态的vector和一个RNN的block。而Self-Attention的输入是一组vectors
- self-attention的每个output vector都考虑了整个input vectors,RNN只考虑了当前对应input vector左边的vectors。但双向循环神经网络(Bidirectional Recurrent Neural Network, Bi-RNN)可视作考虑了整个input vectors序列
- 实现机制:RNN在使用memory时,对内存使用更有要求,我们这里考虑RNN中最右边的向量要考虑最左边的向量信息,则在整个传递过程中,最左边的input都必须存储在memory中。而self-attention做的只是矩阵乘法,可以轻易实现从整个序列非常远的向量抽取信息
- 计算性能:RNN在处理时由于后面的向量计算依赖前面向量的计算结果,因而无法实现并行化计算。而self-attention中每个output vector时同时产生的,可以实现并行化计算
self-attention VS GNN
图(graph)中self-attention的使用
因为graph中存在节点之间的边,我们可以做出假设:如果节点之间是相连的,那么这些节点是有关联的,因此我们的input vectors之间的关联性不需要通过注意力分数计算机制,而直接使用图的信息。具体来说,我们在计算attention matrix时,只计算有边相连的节点
当把self-attention按照这样的限制用在图上时,其实就是一种图神经网络(Graph Neural Network)
未来的研究方向
自注意力最大的问题是计算量大,如何减少self-attention机制的计算量是未来的研究方向
参考资料
- 李宏毅机器学习课程视频Transformer部分链接:https://www.bilibili.com/video/BV1JA411c7VT?p=11
- datawhale的李宏毅深度学习笔记《leedl-toturial》:https://github.com/datawhalechina/leedl-tutorial