Self-Attention
看到下面的第一个saw是动词,第二个saw是名词。
因为第一个saw和第二个saw在形式上没有任何差别。如果任务是进行词性的判断,把上面的词直接输入给神经网络,那么它肯定不能够正确分析。
想要正确分析词性,那么该怎么办呢?
一个解决方式就是让这个词考虑其上下文信息。可以设置一个window,考虑上下文的n个词,n是可以自己指定的。
如果有一个任务,不是一个短的window就可以解决的,而是考虑整个序列才行,那该怎么办呢?
很直接的想法就是把window开大一点,可以包含整个序列。这样就会有一个问题,输入给model的序列会有长有短,这样就需要统计整个训练资料,找出最长的一个序列,然后将window长度设置为该序列的长度。这样就会有一个致命的缺点:FC(full connected) 的参数会很大,这样不仅运算量很大,而且容易overfitting。
有没有更好的方法考虑输入的整个序列呢?
当前是今天的重点 Self-attention
self-attention会记录整个序列的信息,你输入几个vector,它就会输出几个vector。比如下图输入输入和输出了4个vector。
那么输出的4个vector有什么特点呢?
每个self-attention后输出的vector都是考虑了整个序列后才得到的。
输出的向量经过FC层后会进行相应的判断。
self attention是怎么考虑整个序列的呢?
下面的图可以看出,每个b向量都考虑了a1-a4向量。
输出的向量 b是怎么计算的呢?
根据a1找出与其相关的其他向量,每一个向量与a1关联的程度用一个数值α来表示。
怎么计算两个向量之间的关联性呢,也就是如何计算的α?
以下就是常见的计算α两种方式。例如左边的:输入向量分别乘上Wq和Wk 矩阵,得到q和k两个向量。然后再将q和k向量进行点乘得到α
,
分别计算a1与a2、a3和a4的关联性。
q1一般也会跟自己计算关联性
计算出a1和每个向量的关联性之后,会做一个softmax得到α’。然后会根据得到的α’,得出哪些向量跟a1是最有关联的。接着会根据关联性来抽取重要的信息 。
怎么抽取重要的信息呢?
把输入的每个向量都乘上一个Wv得到新的向量,也就是下图的v1-v4。然后再将v1和v4都去乘上对应的α’,然后将他们加起来,就能得到考虑全局信息的b向量了。
如果某一个向量得到的分数越高,比如a1和a2的关联性很强也就是a’1,2的值很大,那么得到的b1的值就可能比较接近于v2。也就是哪个向量的attention的分数越大,那么这个向量的v就会dominate抽出来的结果。
后续会计算 q2与k1,k2,k3,k4、q3与k1,k2,k3,k4、q4与k1,k2,k3,k4的计算结果
从矩阵角度进行分析
Wq, Wk, Wv是通过training data找出来的
参考自:李宏毅