论文笔记-理解-Attention Is All You Need

论文:Attention Is All You Need

源码地址:
不是google的源码
https://github.com/bojone/attention/blob/master/attention_tf.py
https://github.com/bojone/attention/blob/master/attention_keras.py

论文翻译:
https://www.yiyibooks.cn/yiyibooks/Attention_Is_All_You_Need/index.html

理解参考:
https://yq.aliyun.com/articles/342508?utm_content=m_39938
https://blog.csdn.net/mijiaoxiaosan/article/details/73251443

核心技术:
关于attention相关的内容,我不是太理解,之前没有研究过相关的文章,不太懂这个的技术以及原理,后面的很多内容参考了https://yq.aliyun.com/articles/342508?utm_content=m_39938 这篇文章,这篇笔记算是大部分转载了吧.
Attention
Google 的一般化 Attention 思路也是一个编码序列的方案,因此我们也可以认为它跟 RNN、CNN 一样,都是一个序列编码的层。
这里写图片描述
这里写图片描述这里写图片描述
如果忽略激活函数 softmax 的话,那么事实上它就是三个 n×dk,dk×m,m×dv 的矩阵相乘,最后的结果就是一个 n×dv 的矩阵。
于是我们可以认为:这是一个 Attention 层,将 n×dk 的序列 Q 编码成了一个新的 n×dv 的序列。
那怎么理解这种结构呢?我们不妨逐个向量来看。
这里写图片描述
其中 Z 是归一化因子。事实上 q,k,v 分别是 query,key,value 的简写,K,V 是一一对应的,它们就像是 key-value 的关系,那么上式的意思就是通过 qt 这个 query,通过与各个 ks 内积的并 softmax 的方式,来得到 qt 与各个 vs 的相似度,然后加权求和,得到一个 dv 维的向量。
其中因子?tp=webp&wxfrom=5&wx_lazy=1起到调节作用,使得内积不至于太大(太大的话 softmax 后就非 0 即 1 了,不够“soft”了)。
事实上这种 Attention 的定义并不新鲜,但由于 Google 的影响力,我们可以认为现在是更加正式地提出了这个定义,并将其视为一个层地看待。
此外这个定义只是注意力的一种形式,还有一些其他选择,比如 query 跟 key 的运算方式不一定是点乘(还可以是拼接后再内积一个参数向量),甚至权重都不一定要归一化,等等。
Multi-Head Attention
这个是 Google 提出的新概念,是 Attention 机制的完善。
这里写图片描述
不过从形式上看,它其实就再简单不过了,就是把 Q,K,V 通过参数矩阵映射一下,然后再做 Attention,把这个过程重复做 h 次,结果拼接起来就行了,可谓“大道至简”了。具体来说:
这里写图片描述
这里写图片描述
然后:
这里写图片描述
最后得到一个 n×(hd̃v) 的序列。所谓“多头”(Multi-Head),就是只多做几次同样的事情(参数不共享),然后把结果拼接。

Self Attention

到目前为止,对 Attention 层的描述都是一般化的,我们可以落实一些应用。比如,如果做阅读理解的话,Q 可以是篇章的词向量序列,取 K=V 为问题的词向量序列,那么输出就是所谓的 Aligned Question Embedding。
而在 Google 的论文中,大部分的 Attention 都是 Self Attention,即“自注意力”,或者叫内部注意力。
所谓 Self Attention,其实就是 Attention(X,X,X),X 就是前面说的输入序列。也就是说,在序列内部做 Attention,寻找序列内部的联系。
Google 论文的主要贡献之一是它表明了内部注意力在机器翻译(甚至是一般的 Seq2Seq 任务)的序列编码上是相当重要的,而之前关于 Seq2Seq 的研究基本都只是把注意力机制用在解码端。
类似的事情是,目前 SQUAD 阅读理解的榜首模型 R-Net 也加入了自注意力机制,这也使得它的模型有所提升。
当然,更准确来说,Google 所用的是 Self Multi-Head Attention:
这里写图片描述
Position Embedding
然而,只要稍微思考一下就会发现,这样的模型并不能捕捉序列的顺序。换句话说,如果将 K,V 按行打乱顺序(相当于句子中的词序打乱),那么 Attention 的结果还是一样的。
这就表明了,到目前为止,Attention 模型顶多是一个非常精妙的“词袋模型”而已。
这问题就比较严重了,大家知道,对于时间序列来说,尤其是对于 NLP 中的任务来说,顺序是很重要的信息,它代表着局部甚至是全局的结构,学习不到顺序信息,那么效果将会大打折扣(比如机器翻译中,有可能只把每个词都翻译出来了,但是不能组织成合理的句子)。
于是 Google 再祭出了一招——Position Embedding,也就是“位置向量”,将每个位置编号,然后每个编号对应一个向量,通过结合位置向量和词向量,就给每个词都引入了一定的位置信息,这样 Attention 就可以分辨出不同位置的词了。
Position Embedding 并不算新鲜的玩意,在 FaceBook 的 Convolutional Sequence to Sequence Learning 也用到了这个东西。但在 Google 的这个作品中,它的 Position Embedding 有几点区别:
1. 以前在 RNN、CNN 模型中其实都出现过 Position Embedding,但在那些模型中,Position Embedding 是锦上添花的辅助手段,也就是“有它会更好、没它也就差一点点”的情况,因为 RNN、CNN 本身就能捕捉到位置信息。
但是在这个纯 Attention 模型中,Position Embedding 是位置信息的唯一来源,因此它是模型的核心成分之一,并非仅仅是简单的辅助手段。
2. 在以往的 Position Embedding 中,基本都是根据任务训练出来的向量。而 Google 直接给出了一个构造 Position Embedding 的公式:
这里写图片描述
这里的意思是将 id 为 p 的位置映射为一个 dpos 维的位置向量,这个向量的第 i 个元素的数值就是 PEi(p)。
Google 在论文中说到他们比较过直接训练出来的位置向量和上述公式计算出来的位置向量,效果是接近的。因此显然我们更乐意使用公式构造的 Position Embedding 了。
3. Position Embedding 本身是一个绝对位置的信息,但在语言中,相对位置也很重要,Google 选择前述的位置向量公式的一个重要原因如下:
由于我们有 sin(α+β)=sinα cosβ+cosα sinβ 以及 cos(α+β)=cosα cosβ−sinα sinβ,这表明位置 p+k 的向量可以表明位置 p 的向量的线性变换,这提供了表达相对位置信息的可能性。
结合位置向量和词向量有几个可选方案,可以把它们拼接起来作为一个新向量,也可以把位置向量定义为跟词向量一样大小,然后两者加起来。
FaceBook 的论文用的是前者,而 Google 论文中用的是后者。直觉上相加会导致信息损失,似乎不可取,但 Google 的成果说明相加也是很好的方案。

突出贡献:
Attention 层的好处是能够一步到位捕捉到全局的联系,因为它直接把序列两两比较(代价是计算量变为 ��(n2),当然由于是纯矩阵运算,这个计算量相当也不是很严重)。

相比之下,RNN 需要一步步递推才能捕捉到,而 CNN 则需要通过层叠来扩大感受野,这是 Attention 层的明显优势。

存在问题:
并非所有问题都需要长程的、全局的依赖的,也有很多问题只依赖于局部结构,这时候用纯 Attention 也不大好。
事实上,Google 似乎也意识到了这个问题,因此论文中也提到了一个 restricted 版的 Self-Attention(不过论文正文应该没有用到它)。

它假设当前词只与前后 r 个词发生联系,因此注意力也只发生在这 2r+1 个词之间,这样计算量就是 ��(nr),这样也能捕捉到序列的局部结构了。但是很明显,这就是卷积核中的卷积窗口的概念。

通过以上讨论,我们可以体会到,把 Attention 作为一个单独的层来看,跟 CNN、RNN 等结构混合使用,应该能更充分融合它们各自的优势,

这个作者真的是超级厉害!!!!感觉把文章的思路理得超级清楚,内容写的特别好,这里我只转载了部分内容,完整的版本请看:
https://yq.aliyun.com/articles/342508?utm_content=m_39938

猜你喜欢

转载自blog.csdn.net/tuzixini/article/details/80927687