Attention Is All You Need 解读

内容来源:作者授权发布

出品社区:DataFun

注:欢迎转载,转载请注明出处。

为方便阅读,大家可以先看下原论文:

《Attention Is All You Need》

https://arxiv.org/abs/1706.03762

Motivation:

  • 靠 attention 机制,不使用 rnn 和 cnn,并行度高

创新点:

  • 提出 self-attention,自己和自己做 attention,使得每个词都有全局的语义信息(长依赖):

    • 由于 Self-Attention 是每个词和所有词都要计算 Attention,所以不管他们中间有多长距离,最大的路径长度也都只是 1。可以捕获长距离依赖关系

  • 提出 multi-head attention,可以看成 attention 的 ensemble 版本,不同 head 学习不同的子空间语义。

attention表示成k、q、v的方式:

传统的 attention (sequence2sequence 问题):

上下文 context 表示成如下的方式( h 的加权平均):

那么权重 alpha(attention weight)可表示成 Q 和 K 的乘积,小 h 即 V (下图中很清楚的看出,Q 是大 H,K 和 V 是小 h):

上述可以做个变种,就是 K 和 V 不相等,但需要一一对应,例如:

  • V=h+x_embedding

  • Q = H

  • k=h

乘法 VS 加法 attention

加法注意力:

还是以传统的 RNN 的 seq2seq 问题为例子,加性注意力是最经典的注意力机制,它使用了有一个隐藏层的前馈网络(全连接)来计算注意力分配:

乘法注意力:

就是常见的用乘法来计算 attention score:

乘法注意力不用使用一个全连接层,所以空间复杂度占优;另外由于乘法可以使用优化的矩阵乘法运算,所以计算上也一般占优。

论文中的乘法注意力除了一个 scale factor:

论文中指出当 dk 比较小的时候,乘法注意力和加法注意力效果差不多;但当 d_k 比较大的时候,如果不使用 scale factor,则加法注意力要好一些,因为乘法结果会比较大,容易进入 softmax 函数的“饱和区”,梯度较小。

self-attention

以一般的 RNN 的 S2S 为例子,一般的 attention 的 Q 来自 Decoder (如下图中的大 H),K 和 V 来自 Encoder (如下图中的小 h )。self-attention 就是 attention 的 K、Q、V 都来自 encoder 或者 decoder,使得每个位置的表示都具有全局的语义信息,有利于建立长依赖关系。

Layer normalization(LN)

batch normalization 是对一个每一个节点,针对一个 batch ,做一次 normalization ,即纵向的 normalization:

layer normalization(LN),是对一个样本,同一个层网络的所有神经元做 normalization ,不涉及到 batch 的概念,即横向 normalization:

BN 适用于不同 mini batch 数据分布差异不大的情况,而且 BN 需要开辟变量存每个节点的均值和方差,空间消耗略大;而且 BN 适用于有 mini_batch 的场景。

LN 只需要一个样本就可以做 normalization,可以避免 BN 中受 mini-batch 数据分布影响的问题,也不需要开辟空间存每个节点的均值和方差。

但是,BN 的转换是针对单个神经元可训练的——不同神经元的输入经过再平移和再缩放后分布在不同的区间,而 LN 对于一整层的神经元训练得到同一个转换——所有的输入都在同一个区间范围内。如果不同输入特征不属于相似的类别(比如颜色和大小,scale 不一样),那么 LN 的处理可能会降低模型的表达能力。

encoder:

  • 输入:和 conv s2s 类似,词向量加上了 positional embedding,即给位置1,2,3,4…n 等编码(也用一个 embedding 表示)。然后在编码的时候可以使用正弦和余弦函数,使得位置编码具有周期性,并且有很好的表示相对位置的关系的特性(对于任意的偏移量 k,PE[pos+k] 可以由 PE[pos] 表示):

  • 输入的序列长度是 n,embedding 维度是 d,所以 输入是 n*d 的矩阵

  • N=6,6 个重复一样的结构,由两个子层组成:

    • 子层1:

      • Multi-head self-attention

      • 残余连接和 LN:

        • Output = LN (x+sublayer(x))

    • 子层2:

      • Position-wise fc层(跟卷积很像)

      • 对 n*d 的矩阵的每一行进行操作(相当于把矩阵每一行铺平,接一个 FC),同一层的不同行 FC 层用一样的参数,不同层用不同的参数(对于全连接的节点数目,先从512变大为2048,再缩小为512):

  • 整个 encoder 的输出也是 n*d 的矩阵

decoder:

• 输入:假设已经翻译出 k 个词,向量维度还是 d

• 同样使用 N=6 个重复的层,依然使用残余连接和 LN

• 3个子层,比 encoder 多一个 attention 层,是 Decoder 端去 attend encoder 端的信息的层:

  • Sub-L1:
    self-attention,同 encoder,但要 Mask 掉未来的信息,得到 k*d 的矩阵

  • Sub-L2:和 encoder 做 attention 的层,输出 k*d 的矩阵

  • Sub-L3:全连接层,输出 k*d 的矩阵,用第 k 行去预测输出 y

mutli-head attention:

MultiHead 可以看成是一种 ensemble 方式,获取不同子空间的语义:

获取每个子任务的 Q、K、V:

  • 通过全连接进行线性变换映射成多个 Q、K、V,线性映射得到的结果维度可以不变、也可以减少(类似降维)

  • 或者通过 Split 对 Q、K、V 进行划分(分段)

如果采用线性映射的方式,使得维度降低;或者通过 split 的方式使得维度降低,那么多个 head 做 attention 合并起来的复杂度和原来一个 head 做 attention 的复杂度不会差多少,而且多个 head 之间做 attention 可以并行。

参考文献:

1. Attention Is All You Need

https://arxiv.org/abs/1706.03762

2. WEIGHTED TRANSFORMER NETWORK FOR MACHINE TRANSLATION

https://arxiv.org/pdf/1711.02132.pdf

3. 详解深度学习中的 Normalization,不只是BN(2)

http://www.dataguru.cn/article-13032-1.html

4. BERT大火却不懂Transformer?读这一篇就够了

对作者感兴趣的小伙伴,欢迎点击文末阅读原文哦!

——END——

关于DataFun:

DataFun定位于最实用的数据智能社区,主要形式为线下的深度沙龙、线上的内容整理。希望将工业界专家在各自场景下的实践经验,通过DataFun的平台传播和扩散,对即将或已经开始相关尝试的同学有启发和借鉴。

DataFun的愿景是:为大数据、人工智能从业者和爱好者打造一个分享、交流、学习、成长的平台,让数据科学领域的知识和经验更好的传播和落地产生价值。

DataFun社区成立至今,已经成功在全国范围内举办数十场线下技术沙龙,有近三百位的业内专家参与分享,聚集了数万大数据、算法相关领域从业者。

看官点下「在看」再走呗! :point_down: