0%

Attention Is All You Need

研究动机

​ (截至论文发表)之前的模型通常都是使用RNN与CNN。RNN与LSTM网络中包含隐藏层,并且模型的训练以来序列信息。导至模型难以并行训练,提高了空间复杂度。与此同时,Attention机制逐渐发展并在各种任务的序列模型和变换模型成为重要的组成部分。但是现有的Attention机制还是和RNN连接。

​ 因此本文提出了Transformer模型,舍弃了循环神经网络而完全采用attention机制来在输入和输出之间获取全局的依赖关系。

网络模型

​ 如上图所示,Transformer模型包括一个encoder和一个decoder。encoder包括6个相同层,每层包括两个子层。子层第一个是Multi-head self-attention 第二层是简单的Feed-forward network。在每个子层之间加入了残差连接(ResNet中的short-cut),并且每个子层后接着一个**Layer Normalization(LN)**也就是图中的Add & Norm。子层输出维度为512的向量。

​ 与encoder类似,decoder也包含6个相同的层。不同的是每层包括三个子层。在最开始额外添加了Masked Multi-Head Attention层,用来引入序列信息。同样的每个子层也包括了残差连接和LN。

Attention机制

Scaled Dot-Production Attention

​ 本文提出了Scaled Dot-Product Attention机制。

​ 输入向量包括qkvq、k、v三个向量,对于向量qqkk,先进行乘法,然后通过除以dk\sqrt{d_k}进行尺度收缩(因为认为q和k是独立的随机变量并且均值为0,方差为1,那么qkq \cdot k的均值为0,方差为dkd_k,方差扩大了dkd_k倍),接着对多个k进行softmax,然后将结果乘上vv

​ 因为输入是多个词向量,所以采用矩阵QKVQ、K、V。则公式如下:

Attention(Q,K,V)=softmax(QKTdk)VAttention(Q,K,V) = softmax(\frac{QK^T}{\sqrt{d_k}})V

​ 使用该Attention形式,矩阵运算的比例较高,可以很好的使用矩阵运算相关的优化代码进行加速。

Multi-Head Attention

​ 为了引入不同的表示的信息,本文采用了Multi-Head Attention,实际上就是对输入词向量xx生成hh个不同的QKVQ、K、V矩阵,分别进行上述的Scaled Dot-Production Attention,最后进行拼接,再乘一个矩阵WOW^O

MultiHead(Q,K,V)=Concat(head1,...,headh)WOwhereheadi=Attention(QWiO,KWiK,VWiV)MultiHead(Q,K,V) = Concat(head_1,...,head_h)W^O\\ where head_i = Attention(QW^O_i,KW^K_i,VW^V_i)

其中WiQRdmodel×dkWiKRdmodel×dkWiVRdmodel×dvWiORhdv×dmodelW_i^Q \in R^{d_{model} \times d_k}、W_i^K \in R^{d_{model} \times d_k}、W_i^V \in R^{d_{model} \times d_v}、W_i^O \in R^{hd_v \times d_{model}}

​ 下面的这些维度说明了将Q,K,VQ,K,V分别转化乘dk,dvd_k,d_v维度的矩阵,接着进行self-attention的处理,最后再进行拼接,再进行线性变换。

​ 论文中采取了h=8h=8dk=dv=dmodel/h=64d_k=d_v=d_{model}/h=64,8个部分并行计算。

Positon-wise Feed-Forward Networks

​ 对每个位置独立相同的采用一个feed-forward network,包括两个线性变换和一个ReLU激活函数:

FFN(x)=max(0,xW1+b1)W2+b2FFN(x) = max(0,xW_1 + b1)W_2+b_2

Positional Encoding

​ 网络没有循环和卷积结构,那么怎么引入序列信息呢?Transformer添加了**“Positional encodings”**来和输入相加。该模块位于最初的encoder和decoder的层。

PE(pos,2i)=sin(pos/100002i/dmodel)PE(pos,2i+1)=cos(pos/100002i/dmodel)PE_{(pos,2i)}=sin(pos/10000^{2i/d_{model}})\\ PE_{(pos,2i+1)}=cos(pos/10000^{2i/d_{model}})

pos是位置,i是维度

源码

先摸了