前言

注意力(Attention)机制[2]由Bengio团队与2014年提出并在近年广泛的应用在深度学习中的各个领域,例如在计算机视觉方向用于捕捉图像上的感受野,或者NLP中用于定位关键token或者特征。谷歌团队近期提出的用于生成词向量的BERT[3]算法在NLP的11项任务中取得了效果的大幅提升,堪称2018年深度学习领域最振奋人心的消息。而BERT算法的最重要的部分便是本文中提出的Transformer的概念。

正如论文的题目所说的,**Transformer中抛弃了传统的CNN和RNN,整个网络结构完全是由Attention机制组成。更准确地讲,Transformer由且仅由self-Attenion和Feed Forward Neural Network组成。**一个基于Transformer的可训练的神经网络可以通过堆叠Transformer的形式进行搭建,作者的实验是通过搭建编码器和解码器各6层,总共12层的Encoder-Decoder,并在机器翻译中取得了BLEU值得新高。

作者采用Attention机制的原因是考虑到RNN(或者LSTM,GRU等)的计算限制为是顺序的,也就是说RNN相关算法只能从左向右依次计算或者从右向左依次计算,这种机制带来了两个问题:

时间片 的计算依赖 时刻的计算结果,这样限制了模型的并行能力;
顺序计算的过程中信息会丢失,尽管LSTM等门机制的结构一定程度上缓解了长期依赖的问题,但是对于特别长期的依赖现象,LSTM依旧无能为力。
Transformer的提出解决了上面两个问题,首先它使用了Attention机制,将序列中的任意两个位置之间的距离是缩小为一个常量;其次它不是类似RNN的顺序结构,因此具有更好的并行性,符合现有的GPU框架。论文中给出Transformer的定义是:

Transformer is the first transduction model relying entirely on
self-attention to compute representations of its input and output
without using sequence aligned RNNs or convolution。

遗憾的是,作者的论文比较难懂,尤其是Transformer的结构细节和实现方式并没有解释清楚。尤其是论文中的 , , 究竟代表什么意思作者并没有说明。通过查阅资料,发现了一篇非常优秀的讲解Transformer的技术博客。本文中的大量插图也会从该博客中截取。首先感谢Jay Alammer详细的讲解,其次推荐大家去阅读原汁原味的文章。

1. Transformer 详解

1.1 高层Transformer

论文中的验证Transformer的实验室基于机器翻译的,下面我们就以机器翻译为例子详细剖析Transformer的结构,在机器翻译中,Transformer可概括为如图1:

如论文中所设置的,编码器由6个编码block组成,同样解码器是6个解码block组成。与所有的生成模型相同的是,编码器的输出会作为解码器的输入,如图3所示:

我们继续分析每个encoder的详细结构:在Transformer的encoder中,数据首先会经过一个叫做‘self-attention’的模块得到一个加权之后的特征向量 Z ,这个Z 便是论文公式1中的 Attention(Q,K,V):

得到 Z 之后,它会被送到encoder的下一个模块,即Feed Forward Neural Network。这个全连接有两层,第一层的激活函数是ReLU,第二层是一个线性激活函数,可以表示为:

Encoder的结构如图4所示:

Decoder的结构如图5所示,它和encoder的不同之处在于Decoder多了一个Encoder-Decoder Attention,两个Attention分别用于计算输入和输出的权值:

Self-Attention:当前翻译和已经翻译的前文之间的关系;
Encoder-Decnoder Attention:当前翻译和编码的特征向量之间的关系。

1.2 输入编码

1.1节介绍的就是Transformer的主要框架,下面我们将介绍它的输入数据。如图6所示,首先通过Word2Vec等词嵌入方法将输入语料转化成特征向量,论文中使用的词嵌入的维度为 dmodel=512 。

在最底层的block中, X 将直接作为Transformer的输入,而在其他层中,输入则是上一个block的输出。为了画图更简单,我们使用更简单的例子来表示接下来的过程,如图7所示:

1.3 Self-Attention

Self-Attention是Transformer最核心的内容,然而作者并没有详细讲解,下面我们来补充一下作者遗漏的地方。回想Bahdanau等人提出的用Attention[2],其核心内容是为输入向量的每个单词学习一个权重,例如在下面的例子中我们判断it代指的内容,

The animal didn’t cross the street because it was too tired

通过加权之后可以得到类似图8的加权情况,在讲解self-attention的时候我们也会使用图8类似的表示方式

在self-attention中,每个单词有3个不同的向量,它们分别是Query向量( Q),Key向量( K )和Value向量( V ),长度均是64。它们是通过3个不同的权值矩阵由嵌入向量 X 乘以三个不同的权值矩阵 WQ ,WK ,WV 得到,其中三个矩阵的尺寸也是相同的。均是 512*64 。
注意是每个单词都有这三个向量

即1512X51264=1*64

那么Query,Key,Value是什么意思呢?它们在Attention的计算中扮演着什么角色呢?我们先看一下Attention的计算方法,整个过程可以分成7步:

如上文,将输入单词转化成嵌入向量;
根据嵌入向量得到 Q,K ,V 三个向量;
为每个向量计算一个score:score=Q*K ;
为了梯度的稳定,Transformer使用了score归一化,即除以 dk2\sqrt[2]{d~k~}2dk


对score施以softmax激活函数;
softmax点乘Value值 ,得到加权的每个输入向量的评分v ;
相加之后得到最终的输出结果 :Z=∑i=0n\sum_{i=0}^ni=0n v 。

上面步骤的可以表示为该图的形式。

实际计算过程中是采用基于矩阵的计算方式,那么论文中的 Q ,K ,V 的计算方式如图11:注意 X, Q, K, V 的每一行都表示一个单词

总结为矩阵形式:

详细计算过程如下:
公式中计算矩阵Q和K每一行向量的内积,为了防止内积过大,因此除以 dk 的平方根。Q乘以K的转置后,得到的矩阵行列数都为 n,n 为句子单词数,这个矩阵可以表示单词之间的 attention 强度。下图为Q乘以 KT ,1234 表示的是句子中的单词。
对该式的解释:
dk是Q,K矩阵的列数,即向量的维度,Q,K,V如何得到呢,在self-Attention有相关介绍

得到 QKT之后,使用 Softmax 计算每一个单词对于其他单词的 attention 系数,公式中的 Softmax 是对矩阵的每一行进行 Softmax,即每一行的和都变为 1.

得到 Softmax 矩阵之后可以和V相乘,得到最终的输出Z。

上图中 Softmax 矩阵的第 1 行表示单词 1 与其他所有单词的 attention 系数,最终单词 1 的输出 Zi 等于所有单词 i 的值 Vi 根据 attention 系数的比例加在一起得到,如下图所示:

在self-attention需要强调的最后一点是其采用了残差网络中的short-cut结构,目的当然是解决深度学习中的退化问题,得到的最终结果如下图。

Query,Key,Value的概念取自于信息检索系统,举个简单的搜索的例子来说。当你在某电商平台搜索某件商品(年轻女士冬季穿的红色薄款羽绒服)时,你在搜索引擎上输入的内容便是Query,然后搜索引擎根据Query为你匹配Key(例如商品的种类,颜色,描述等),然后根据Query和Key的相似度得到匹配的内容(Value)。

self-attention中的Q,K,V也是起着类似的作用,在矩阵计算中,点积是计算两个矩阵相似度的方法之一,因此式1中使用了QKT 进行相似度的计算。接着便是根据相似度进行输出的匹配,这里使用了加权匹配的方式,而权值就是query与key的相似度。

1.4 Multi-Head Attention

而 Multi-Head Attention 是由多个 Self-Attention 组合形成的,下图是论文中 Multi-Head Attention 的结构图。

Multi-Head Attention相当于 h 个不同的self-attention的集成(ensemble),在这里我们以 h=8 举例说明。Multi-Head Attention的输出分成3步:
将数据 X 分别输入到图13所示的8个self-attention中,得到8个加权后的特征矩阵 Zi { i=1,2…8 } 。
将8个Zi 按列拼成一个大的特征矩阵;
特征矩阵经过一层全连接后得到输出 Z 。

得到 8 个输出矩阵 Z1 到 Z8 之后,Multi-Head Attention 将它们拼接在一起 (Concat),然后传入一个Linear层,得到 Multi-Head Attention 最终的输出Z。

可以看到 Multi-Head Attention 输出的矩阵Z与其输入的矩阵X的维度是一样的。
同self-attention一样,multi-head attention也加入了short-cut机制。

1.5 Encoder-Decoder Attention

在解码器中,Transformer block比编码器中多了个encoder-cecoder attention。在encoder-decoder attention中, Q 来自于解码器的上一个输出,K 和 V 则来自于与编码器的输出。其计算方式相同。

由于在机器翻译中,解码过程是一个顺序操作的过程,也就是当解码第 K 个特征向量时,我们只能看到第 K-1 及其之前的解码结果,论文中把这种情况下的multi-head attention叫做masked multi-head attention。

解码器解码之后,解码的特征向量经过一层激活函数为softmax的全连接层之后得到反映每个单词概率的输出向量。

2.Encoder层详解


上图红色部分是 Transformer 的 Encoder block 结构,可以看到是由 Multi-Head Attention, Add & Norm, Feed Forward, Add & Norm 组成的。刚刚已经了解了 Multi-Head Attention 的计算过程,现在了解一下 Add & Norm 和 Feed Forward 部分。

2.1 Add & Norm

Add & Norm 层由 Add 和 Norm 两部分组成,其计算公式如下:

其中 X表示 Multi-Head Attention 或者 Feed Forward 的输入,MultiHeadAttention(X) 和 FeedForward(X) 表示输出 (输出与输入 X 维度是一样的,所以可以相加)。

Add指 X+MultiHeadAttention(X),是一种残差连接,通常用于解决多层网络训练的问题,可以让网络只关注当前差异的部分,在 ResNet 中经常用到:

Norm指 Layer Normalization,通常用于 RNN 结构,Layer Normalization 会将每一层神经元的输入都转成均值方差都一样的,这样可以加快收敛。

2.2 Feed Forward

Feed Forward 层比较简单,是一个两层的全连接层,第一层的激活函数为 Relu,第二层不使用激活函数,对应的公式如下。

X是输入,Feed Forward 最终得到的输出矩阵的维度与X一致。

2.3 组成 Encoder

通过上面描述的 Multi-Head Attention, Feed Forward, Add & Norm 就可以构造出一个 Encoder block,Encoder block 接收输入矩阵 Xn*d ,并输出一个矩阵On*d 。通过多个 Encoder block 叠加就可以组成 Encoder。

第一个 Encoder block 的输入为句子单词的表示向量矩阵,后续 Encoder block 的输入是前一个 Encoder block 的输出,最后一个 Encoder block 输出的矩阵就是编码信息矩阵 C,这一矩阵后续会用到 Decoder 中。

3.Decoder 结构


上图红色部分为 Transformer 的 Decoder block 结构,与 Encoder block 相似,但是存在一些区别:

包含两个 Multi-Head Attention 层。
第一个 Multi-Head Attention 层采用了 Masked 操作。
第二个 Multi-Head Attention 层的K, V矩阵使用 Encoder 的编码信息矩阵C进行计算,而Q使用上一个 Decoder block 的输出计算。
最后有一个 Softmax 层计算下一个翻译单词的概率。

3.1 第一个 Multi-Head Attention

Decoder block 的第一个 Multi-Head Attention 采用了 Masked 操作,因为在翻译的过程中是顺序翻译的,即翻译完第 i 个单词,才可以翻译第 i+1 个单词。通过 Masked 操作可以防止第 i 个单词知道 i+1 个单词之后的信息。下面以 “我有一只猫” 翻译成 “I have a cat” 为例,了解一下 Masked 操作。

下面的描述中使用了类似 Teacher Forcing 的概念,不熟悉 Teacher Forcing 的童鞋可以参考以下上一篇文章Seq2Seq 模型详解。在 Decoder 的时候,是需要根据之前的翻译,求解当前最有可能的翻译,如下图所示。首先根据输入 “” 预测出第一个单词为 “I”,然后根据输入 “ I” 预测下一个单词 “have”。

Decoder 可以在训练的过程中使用 Teacher Forcing 并且并行化训练,即将正确的单词序列 ( I have a cat) 和对应输出 (I have a cat ) 传递到 Decoder。那么在预测第 i 个输出时,就要将第 i+1 之后的单词掩盖住,注意 Mask 操作是在 Self-Attention 的 Softmax 之前使用的,下面用 0 1 2 3 4 5 分别表示 “ I have a cat ”。

第一步:是 Decoder 的输入矩阵和 Mask 矩阵,输入矩阵包含 “ I have a cat” (0, 1, 2, 3, 4) 五个单词的表示向量,Mask 是一个 5×5 的矩阵。在 Mask 可以发现单词 0 只能使用单词 0 的信息,而单词 1 可以使用单词 0, 1 的信息,即只能使用之前的信息。

第二步:接下来的操作和之前的 Self-Attention 一样,通过输入矩阵X计算得到Q,K,V矩阵。然后计算Q和 KT 的乘积 QKT

第三步:在得到 QKT 之后需要进行 Softmax,计算 attention score,我们在 Softmax 之前需要使用Mask矩阵遮挡住每一个单词之后的信息,遮挡操作如下:

得到 Mask QKT 之后在 Mask QKT 上进行 Softmax,每一行的和都为 1。但是单词 0 在单词 1, 2, 3, 4 上的 attention score 都为 0。

第四步:使用 Mask QKT与矩阵 V相乘,得到输出 Z,则单词 1 的输出向量 Z1 是只包含单词 1 信息的。

第五步:通过上述步骤就可以得到一个 Mask Self-Attention 的输出矩阵Zi ,然后和 Encoder 类似,通过 Multi-Head Attention 拼接多个输出Zi 然后计算得到第一个 Multi-Head Attention 的输出Z,Z与输入X维度一样。

3.2 第二个 Multi-Head Attention

Decoder block 第二个 Multi-Head Attention 变化不大, 主要的区别在于其中 Self-Attention 的 K, V矩阵不是使用 上一个 Decoder block 的输出计算的,而是使用 Encoder 的编码信息矩阵 C 计算的

根据 Encoder 的输出 C计算得到 K, V,根据上一个 Decoder block 的输出 Z 计算 Q (如果是第一个 Decoder block 则使用输入矩阵 X 进行计算),后续的计算方法与之前描述的一致。

这样做的好处是在 Decoder 的时候,每一位单词都可以利用到 Encoder 所有单词的信息 (这些信息无需 Mask)。

3.3 Softmax 预测输出单词

Decoder block 最后的部分是利用 Softmax 预测下一个单词,在之前的网络层我们可以得到一个最终的输出 Z,因为 Mask 的存在,使得单词 0 的输出 Z0 只包含单词 0 的信息,如下:

Softmax 根据输出矩阵的每一行预测下一个单词:

这就是 Decoder block 的定义,与 Encoder 一样,Decoder 是由多个 Decoder block 组合而成。

4. Transformer 总结

Transformer 与 RNN 不同,可以比较好地并行训练。
Transformer 本身是不能利用单词的顺序信息的,因此需要在输入中添加位置 Embedding,否则 Transformer 就是一个词袋模型了。
Transformer 的重点是 Self-Attention 结构,其中用到的 Q, K, V矩阵通过输出进行线性变换得到。
Transformer 中 Multi-Head Attention 中有多个 Self-Attention,可以捕获单词之间多种维度上的相关系数 attention score。

Attention机制学习记录(四)之Transformer相关推荐

  1. leveldb 学习记录(四)Log文件

    前文记录 leveldb 学习记录(一) skiplist leveldb 学习记录(二) Slice leveldb 学习记录(三) MemTable 与 Immutable Memtable le ...

  2. MySQL学习记录 (四) ----- SQL数据管理语句(DML)

    相关文章: <MySQL学习记录 (一) ----- 有关数据库的基本概念和MySQL常用命令> <MySQL学习记录 (二) ----- SQL数据查询语句(DQL)> &l ...

  3. Kafka学习记录(四)——消费者

    Kafka学习记录(四)--消费者 目录 Kafka学习记录(四)--消费者 对应课程 Kafka消费者工作流程 消费方式和流程 消费者组原理 消费者组初始化流程 消费者组详细消费流程 重要参数 ka ...

  4. Attention机制学习(二)使用

    前言 前一篇博客简要的介绍了一下传统的attention机制的基本思想, 本篇博客解读使用attention机制做机器翻译的第一篇论文,通过这篇论文看attention的使用方法. 论文: NEURA ...

  5. Attention机制学习(一)传统Attention机制

    前言 纵观神经网络的发展历程,从最原始的MLP,到CNN,到RNN,到LSTM,GRU,再到现在的Attention机制,人们不断的在网络里面加入一些先验知识,使得网络不过于"发散" ...

  6. OUC暑期培训(深度学习)——第六周学习记录:Vision Transformer amp; Swin Transformer

    第六周学习:Vision Transformer & Swin Transformer Part 1 视频学习及论文阅读 1.Vision Transformer 原文链接:https://a ...

  7. Alarm机制-学习记录

    整理自<第一行代码> 由于手机的休眠策略,Android会在长时间不操作的情况下自动让CPU进入到睡眠状态. Alrarm具有唤醒CPU的功能,它可以保证在大多数情况下需要执行定时任务的时 ...

  8. 【故障诊断发展学习记录四——数字孪生与控制系统健康管理(DT PHM)】

    数字数字 目录 1. 数字孪生的起源 1.1 数字工程 1.2  模型贯穿决策 1.3 数字工程路线图 1.4 数字工程战略目标 2. 美军数字工程 2.1 生态系统全视图 2.2 支持采办的的完整视 ...

  9. gRPC学习记录(四)--官方Demo

    了解proto3后,接下来看官方Demo作为训练,这里建议看一遍之后自己动手搭建出来,一方面巩固之前的知识,一方面是对整个流程更加熟悉. 官方Demo地址: https://github.com/gr ...

最新文章

  1. C++ 不能在构造函数中调用构造函数
  2. TFS修改工作区映射区
  3. 使用 JavaScript 实现灵活的固定导航功能
  4. 企业建设呼叫中心需要考虑哪些因素
  5. 重构-改善既有代码的设计(十)--简化函数调用
  6. [转]图片处理函数(自适应缩略图datatable中添加缩略图像)
  7. 高级JAVA - 利用函数式接口实现通用的取并集/交集/差集
  8. tiptop 编译运行_putty终于让我的TIPTOP脱离虚拟机在64位上运行了。
  9. 理解点击屏幕的事件响应---对UIView的hitTest: withEvent: 方法的理解
  10. 推荐一个准确率99.9%的离线IP地址定位服务!
  11. 基于SSM框架图书馆预约占座系统的设计与实现(附源码、论文)
  12. PAIP VCF通讯录的乱码以及导入导出
  13. 对JS中this的理解
  14. 苹果库乐队怎么玩_iPhone技巧丨苹果手机制作炫酷铃声,就是不一样!
  15. 《关键对话》教你如何摆脱沟通困境
  16. verilog latch
  17. 怎么用思维导图做会议纪要?MindNow来教你
  18. python api调用 验证码_Python语言调用创蓝253短信验证码API文档
  19. 驱动编程简单教程——PTC512(ADC芯片驱动)为例
  20. Windows10只关闭显卡驱动更新

热门文章

  1. 十问:关于翻译价格的一切都在这里丨打死个翻译官 1.3
  2. enter按键的事件监听
  3. COMSOL学习经验
  4. 职位名称:初级,罗马数字和难以捉摸的“ Python建筑师”
  5. 武林外传打怪 优化版
  6. NC6系列开发自定义参照
  7. ADI汽车音频总线的完整诠释,一个系列让你彻底搞懂A2B(本人很懂,不谦虚)
  8. 市场数学:盈利、亏损、和成本
  9. SqlCommand 添加参数-与DataAdapter更新
  10. JAVA完成九宫格程序