学习:Attention Is All You Need(1)

复制链接2

这两天在看attention模型,看了下知乎上的几个回答,很多人都推荐了一篇文章Neural Machine Translation by Jointly Learning to Align and Translate 我看了下,感觉非常的不错,里面还大概阐述了encoder-decoder(编码)模型的概念,以及传统的RNN实现。然后还阐述了自己的attention模型。我看了一下,自己做了一些摘录,写在下面

1.Encoder-Decoder模型及RNN的实现

所谓encoder-decoder模型,又叫做编码-解码模型。这是一种应用于seq2seq问题的模型。

那么seq2seq又是什么呢?简单的说,就是根据一个输入序列x,来生成另一个输出序列y。seq2seq有很多的应用,例如翻译文档摘取问答系统等等。在翻译中,输入序列是待翻译的文本,输出序列是翻译后的文本;在问答系统中,输入序列是提出的问题,而输出序列是答案

为了解决seq2seq问题,有人提出了encoder-decoder模型,也就是编码-解码模型。所谓编码,就是将输入序列转化成一个固定长度的向量;解码,就是将之前生成的固定向量再转化成输出序列
在这里插入图片描述
当然了,这个只是大概的思想,具体实现的时候,编码器和解码器都不是固定的,可选的有CNN/RNN/BiRNN/GRU/LSTM等等,你可以自由组合。比如说,你在编码时使用BiRNN,解码时使用RNN,或者在编码时使用RNN,解码时使用LSTM等等。

这边为了方便阐述,选取了编码和解码都是RNN的组合。在RNN中,当前时间的隐藏状态是由上一时间的状态和当前时间输入决定的,也就是
在这里插入图片描述
获得了各个时间段的隐藏层以后,再将隐藏层的信息汇总,生成最后的语义向量
在这里插入图片描述
一种简单的方法是将最后的隐藏层作为语义向量C,即
在这里插入图片描述
解码阶段可以看做编码的逆过程。这个阶段,我们要根据给定的语义向量C和之前已经生成的输出序列 y 1 , y 2 , … y t − 1 y_1,y_2,…y_{t−1} y1,y2,yt1来预测下一个输出的单词 y t y_t yt,即
在这里插入图片描述
也可以写作
在这里插入图片描述
而在RNN中,上式又可以简化成
在这里插入图片描述
其中s是输出RNN中的隐藏层,C代表之前提过的语义向量, y t − 1 y_{t−1} yt1表示上个时间段的输出,反过来作为这个时间段的输入。而g则可以是一个非线性的多层的神经网络,产生词典中各个词语属于 y t y_t yt的概率。

encoder-decoder模型虽然非常经典,但是局限性也非常大。最大的局限性就在于编码和解码之间的唯一联系就是一个固定长度的语义向量C。也就是说,编码器要将整个序列的信息压缩进一个固定长度的向量中去。但是这样做有两个弊端,一是语义向量无法完全表示整个序列的信息,还有就是先输入的内容携带的信息会被后输入的信息稀释掉,或者说,被覆盖了。输入序列越长,这个现象就越严重。这就使得在解码的时候一开始就没有获得输入序列足够的信息, 那么解码的准确度自然也就要打个折扣了

2.Attention模型

为了解决这个问题,作者提出了Attention模型,或者说注意力模型。简单的说,这种模型在产生输出的时候,还会产生一个“注意力范围”表示接下来输出的时候要重点关注输入序列中的哪些部分,然后根据关注的区域来产生下一个输出,如此往复。模型的大概示意图如下所示
在这里插入图片描述
相比于之前的encoder-decoder模型,attention模型最大的区别就在于它不在要求编码器将所有输入信息都编码进一个固定长度的向量之中。相反,此时编码器需要将输入编码成一个向量的序列,而在解码的时候,每一步都会选择性的从向量序列中挑选一个子集进行进一步处理。这样,在产生每一个输出的时候,都能够做到充分利用输入序列携带的信息。而且这种方法在翻译任务中取得了非常不错的成果。

在这篇文章中,作者提出了一个用于翻译任务的结构。解码部分使用了attention模型,而在编码部分,则使用了BiRNN(bidirectional RNN,双向RNN)

2.1 解码

我们先来看看解码。解码部分使用了attention模型。类似的,我们可以将之前定义的条件概率写作
在这里插入图片描述
上式 s i s_i si表示解码器i时刻的隐藏状态。计算公式是
在这里插入图片描述
注意这里的条件概率与每个目标输出 y i y_i yi相对应的内容向量 c i c_i ci有关。而在传统的方式中,只有一个内容向量C。那么这里的内容向量 c i c_i ci又该怎么算呢?其实 c i c_i ci是由编码时的隐藏向量序列 ( h 1 , … , h T x ) (h_1,…,h_{T_x}) (h1,,hTx)按权重相加得到的。
在这里插入图片描述
由于编码使用了双向RNN,因此可以认为 h i h_i hi中包含了输入序列中第i个词以及前后一些词的信息。将隐藏向量序列按权重相加,表示在生成第j个输出的时候的注意力分配是不同的。 α i j \alpha _{ij} αij的值越高,表示第i个输出在第j个输入上分配的注意力越多,在生成第i个输出的时候受第j个输入的影响也就越大。那么现在我们又有新问题了, α i j \alpha _{ij} αij又是怎么得到的呢?这个其实是由第i-1个输出隐藏状态 s i − 1 s_{i−1} si1和输入中各个隐藏状态共同决定的。也即是
在这里插入图片描述
也就是说, s i − 1 s_{i−1} si1先跟每个h分别计算得到一个数值,然后使用softmax得到i时刻的输出在 T x T_x Tx个输入隐藏状态中的注意力分配向量。这个分配向量也就是计算 c i c_i ci的权重。我们现在再把公式按照执行顺序汇总一下:
在这里插入图片描述
上面这些公式就是解码器在第i个时间段内要做的事情。作者还给了一个示意图:
在这里插入图片描述

2.2 编码

在这里插入图片描述

3.实验结果

为了检验性能,作者分别使用传统模型和attention模型在英语-法语的翻译数据集上进行了测验。

传统模型的编码器和解码器各有1000个隐藏单元。编码器中还有一个多层神经网络用于实现从隐藏状态到单词的映射。在优化方面,使用了SGD(minibatch stochastic gradient descent)以及Adadelta,前者负责采样,后者负责优化下降方向。

得到的结果如下:
在这里插入图片描述
图中RNNenc表示传统的结构,而RNNsearch表示attention模型。后面的数字表示序列的长度。可以看到,不论序列长度,attention模型的性能均优于传统的编码-解码模型。而RNNsearch-50甚至在长文本上的性能也非常的优异

除了准确度之外,还有一个很值得关注的东西:注意力矩阵。之前已经提过,每个输出都有一个长为 T x T_x Tx的注意力向量,那么将这些向量合起来看,就是一个矩阵。对其进行可视化,得到如下结果
在这里插入图片描述
其中x轴表示待翻译的句子中的单词(英语),y轴表示翻译以后的句子中的单词(法语)。可以看到尽管从英语到法语的过程中,有些单词的顺序发生了变化,但是attention模型仍然很好的找到了合适的位置。换句话说,就是两种语言下的单词“对齐”了。因此,也有人把注意力模型叫做对齐(alignment)模型。而且像比于用语言学实现的硬对齐,这种基于概率的软对齐更加优雅,因为能够更全面的考虑到上下文的语境。

############################分割线################################

复制链接1

Introduction

本文是谷歌发表的文章,针对nlp里的机器翻译问题,提出了一种被称为”Transformer”的网络结构,基于注意力机制。文章提出,以往nlp里大量使用RNN结构和encoder-decoder结构,RNN及其衍生网络的缺点就是慢,问题在于前后隐藏状态的依赖性,无法实现并行,而文章提出的”Transformer”完全摒弃了递归结构,依赖注意力机制,挖掘输入和输出之间的关系,这样做最大的好处是能够并行计算了

Background

在此之前,针对机器翻译这个领域,为了应对RNN无法并行问题,已经有过一些使用CNN的解决方案了,例如谷歌的ByteNetFacebook的FairSeq等等。
  
自注意力机制(Self-attention)能够把输入序列上不同位置的信息联系起来,然后计算出整条序列的某种表达,目前自注意力机制主要应用于阅读理解提取摘要文本推论等领域。

模型结构

大多数自然语言转换模型都包含一个encoder-decoder结构,模型的输入是一个离散符号序列(symbol)x=(x1,x2,⋯,xn),encoder负责将它映射成连续值序列z=(z1,z2,⋯,zn)。而给定z,decoder负责生成一个输出符号序列y=(y1,y2,⋯,ym)。模型是自回归的,即之前生成的输出会作为额外的输入,用于生成下一个输出。

Encoder与Decoder堆叠

Encoder

Transformer模型的Encoder由6个基本层堆叠起来,每个基本层包含两个子层,第一个子层是一个注意力机制,第二个是一个全连接前向神经网络。对两个子层都引入了残差边以及layer normalization

Decoder

Transformer模型的Decoder也由6个基本层堆叠起来,每个基本层除了Encoder里面的那两个以外,还增加了一层注意力机制,同样引入残差边以及layer normalization。
在这里插入图片描述

注意力机制

注意力机制(Attention)简单来说就是给定一个查找(query)和一个键值表(key-value pairs),将query映射到正确的输入的过程。此处的query、key、value和最终的输出都是向量。输出往往是一个加权求和的形式,而权重则由query、key和value决定。

Additive Attention

Scaled Dot-Product Attention

输入包含 d k d_k dk维的query和key,以及 d v d_v dv维的value。通过计算query和各个key的点积,除以 d k \sqrt {d_k} dk 归一化,然后经过softmax激活变成权重,最后再乘value。点积注意力机制的优点是速度快、占用空间小
在这里插入图片描述
在这里插入图片描述

Multi-Head Attention

用h(本文取8)个不同的线性变换分别将 d m o d e l d_{model} dmodel维的key、value和query映射成 d k d_k dk维、 d k d_k dk维和 d v d_v dv维,然后再代入注意力机制,产生总共 h × d v h×d_v h×dv维输出,然后拼起来,再用一个线性变换得到最终的输出。
在这里插入图片描述
在这里插入图片描述

本文使用的注意力机制

本文使用的是Multi-Head Attention,具体体现在三个方面。

  • 在“encoder-decoder attention”层中,query来自前一个decoder层,而key和value是encoder的输出。这允许decoder的每个位置都去关注输入序列的所有位置。
  • encoder包含self-attention层,在self-attention层中所有的key、value和query都来自前一层的encoder。这样encoder的每个位置都能去关注前一层encoder输出的所有位置。
  • decoder包含self-attention层

前向神经网络

这是一个 Position-wise 前向神经网络,encoder和decoder的每一层都包含一个前向神经网络,激活函数顺序是线性、RELU、线性。
在这里插入图片描述

位置编码

由于本文的模型结构没有使用任何递归结构卷积结构,为了让模型能利用输入序列的顺序信息,必须引入某种能表达输入序列每个部分的绝对或相对位置的信息才行。文章采取的方法是位置编码(positional encoding),在送入encoder和decoder之前,先对输入进行编码,编码后的向量维度是 d m o d e l d_{model} dmodel。具体来说,采用正弦和余弦函数进行编码。
在这里插入图片描述

为什么使用self-attention

从三个方面去对比self-attention递归结构卷积结构的优劣性,首先是每一层的计算复杂度,其次是能够被并行的计算量,最后是网络中长期依赖的路径长度。对比显示,self-attention表现最好。
在这里插入图片描述

训练

训练数据使用WMT English-German数据集,包含450w对语句。句子都被编码过了,使用了一个大小约37000个token的字典。样本被分为若干个batch,每个batch大概25000个token,每个batch中的句子长度保持基本一致。硬件上使用了8块GPU。Optimizer使用了Adam。过拟合方面使用了dropoutLabel Smoothing

结果

不论是英语-德语还是英语-法语的翻译任务,对比之前的一些模型,本文提出的模型都达到更好的BELU值,同时Training Cost也最低。
在这里插入图片描述

本文开源代码

https://github.com/tensorflow/tensor2tensor

参考资料

Attention Is All You Need
一文读懂「Attention is All You Need」| 附代码实现
attention实现keras版
attention实现tensorflow版
对Attention is all you need 的理解

#############################分割线##############################

一文读懂「Attention is All You Need」| 附代码实现

赋值链接2
摘要: 前言 2017 年中,有两篇类似同时也是笔者非常欣赏的论文,分别是 FaceBook 的 Convolutional Sequence to Sequence Learning 和 Google 的 Attention is All You Need,它们都算是 Seq2Seq 上的创新,本质上来说,都是抛弃了 RNN 结构来做 Seq2Seq 任务。

序列编码

深度学习做 NLP 的方法,基本上都是先将句子分词,然后每个词转化为对应的词向量序列。这样一来,每个句子对应的是一个矩阵 X=(x1,x2,…,xt),其中 xi 都代表着第 i 个词的词向量(行向量),维度为 d 维,故?tp=webp&wxfrom=5&wx_lazy=1。这样的话,问题就变成了编码这些序列了。

第一个基本的思路是 RNN 层,RNN 的方案很简单,递归式进行
在这里插入图片描述
不管是已经被广泛使用的 LSTMGRU 还是最近的 SRU,都并未脱离这个递归框架。RNN结构本身比较简单,也很适合序列建模,但 RNN 的明显缺点之一就是无法并行,因此速度较慢,这是递归的天然缺陷

另外我个人觉得 RNN 无法很好地学习到全局的结构信息,因为它本质是一个马尔科夫决策过程。

第二个思路是 CNN 层,其实 CNN 的方案也是很自然的,窗口式遍历,比如尺寸为 3 的卷积,就是:
在这里插入图片描述
在 FaceBook 的论文中,纯粹使用卷积也完成了 Seq2Seq 的学习,是卷积的一个精致且极致的使用案例,热衷卷积的读者必须得好好读读这篇文论

CNN 方便并行,而且容易捕捉到一些全局的结构信息,笔者本身是比较偏爱 CNN 的,在目前的工作或竞赛模型中,我都已经尽量用 CNN 来代替已有的 RNN 模型了,并形成了自己的一套使用经验,这部分我们以后再谈。

Google的大作提供了第三个思路:纯 Attention,单靠注意力就可以。

RNN 要逐步递归才能获得全局信息,因此一般要双向 RNN 才比较好;CNN 事实上只能获取局部信息,是通过层叠来增大感受野;Attention 的思路最为粗暴,它一步到位获取了全局信息,它的解决方案是:
在这里插入图片描述
其中 A,B 是另外一个序列(矩阵)。如果都取 A=B=X,那么就称为 Self Attention,它的意思是直接将 xt 与原来的每个词进行比较,最后算出 yt

待续…
###########################分割线#################################

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值