搞懂Transformer结构,看这篇PyTorch实现就够了
搞懂Transformer结构,看这篇PyTorch实现就够了
机器学习研究组昨天
作者⼁Alexander Rush来源⼁哈⼯⼤SCIR
下⾯分享⼀篇实验室翻译的来⾃哈佛⼤学⼀篇关于Transformer的详细博⽂。
"Attention is All You Need"[1] ⼀⽂中提出的Transformer⽹络结构最近引起了很多⼈的关注。Transformer不仅能够明显地提升翻译质量,还为许多NLP任务提供了新的结构。虽然原⽂写得很清楚,但实际上⼤家普遍反映很难正确地实现。
decoder
所以我们为此⽂章写了篇注解⽂档,并给出了⼀⾏⾏实现的Transformer的代码。本⽂档删除了原⽂的⼀些章节并进⾏了重新排序,并在整个⽂章中加⼊了相应的注解。此外,本⽂档以Jupyter notebook的形式完成,本⾝就是直接可以运⾏的代码实现,总共有400⾏库代码,在4个GPU上每秒可以处理27,000个tokens。
想要运⾏此⼯作,⾸先需要安装PyTorch[2]。这篇⽂档完整的notebook⽂件及依赖可在github[3] 或 Google Colab[4]上到。
需要注意的是,此注解⽂档和代码仅作为研究⼈员和开发者的⼊门版教程。这⾥提供的代码主要依赖OpenNMT[5]实现,想了解更多关于此模型的其他实现版本可以查看Tensor2Tensor[6] (tensorflow版本) 和 Sockeye[7](mxnet版本)
Alexander Rush (@harvardnlp[8] or srush@seas.harvard.edu)
0.准备⼯作
# !pip install /whl/cu80/torch-0.3.0.post4-cp36-cp36m-linux_x86_64.whl numpy matplotlib spacy torchtext seaborn
内容⽬录
准备⼯作
背景
模型结构
- Encoder和Decoder
- Encoder
- Decoder
- Attention
- Attention在模型中的应⽤
- Position-wise前馈⽹络
- Embedding和Softmax
- 位置编码
- 完整模型
(由于原⽂篇幅过长,其余部分在下篇)
训练
- 批和掩码
- 训练循环
- 训练数据和批处理
- 硬件和训练进度
- 优化器
- 正则化
第⼀个例⼦
- 数据⽣成
- 损失计算
- 贪⼼解码
真实⽰例
- 数据加载
- 迭代器
- 多GPU训练
- 训练系统附加组件:BPE,搜索,平均
结果
- 注意⼒可视化
结论
本⽂注解部分都是以引⽤的形式给出的,主要内容都是来⾃原⽂。
1.背景
减少序列处理任务的计算量是⼀个很重要的问题,也是Extended Neural GPU、ByteNet和ConvS2S等⽹络的动机。上⾯提到的这些⽹络都以CNN为基础,并⾏计算所有输⼊和输出位置的隐藏表⽰。
在这些模型中,关联来⾃两个任意输⼊或输出位置的信号所需的操作数随位置间的距离增长⽽增长,⽐如ConvS2S呈线性增长,ByteNet呈现以对数形式增长,这会使学习较远距离的两个位置之间的依赖关系变得更加困难。⽽在Transformer中,操作次数则被减少到了常数级别。
Self-attention有时候也被称为Intra-attention,是在单个句⼦不同位置上做的Attention,并得到序列的⼀个表⽰。它能够很好地应⽤到很多任务中,包括阅读理解、摘要、⽂本蕴涵,以及独⽴于任务的句⼦表⽰。端到端的⽹络⼀般都是基于循环注意⼒机制⽽不是序列对齐循环,并且已经有证据表明在简单语⾔问答和语⾔建模任务上表现很好。
据我们所知,Transformer是第⼀个完全依靠Self-attention⽽不使⽤序列对齐的RNN或卷积的⽅式来计算输⼊输出表⽰的转换模型。
2.模型结构
⽬前⼤部分⽐较热门的神经序列转换模型都有Encoder-Decoder结构[9]。Encoder将输⼊序列映射到⼀个连续表⽰序列。
对于编码得到的z,Decoder每次解码⽣成⼀个符号,直到⽣成完整的输出序列:。对于每⼀步解码,模型都是⾃回归的[10],即在⽣成下⼀个符号时将先前⽣成的符号作为附加输⼊。
Transformer的整体结构如下图所⽰,在Encoder和Decoder中都使⽤了Self-attention, Point-wise和全连接层。Encoder和decoder的⼤致结构分别如下图的左半部分和右半部分所⽰。
2. Encoder和Decoder
Encoder
Encoder由N=6个相同的层组成。
我们在每两个⼦层之间都使⽤了残差连接(Residual Connection) [11]和归⼀化 [12]。
每层都有两个⼦层组成。第⼀个⼦层实现了“多头”的 Self-attention,第⼆个⼦层则是⼀个简单的Position-wise的全连接前馈⽹络。
Decoder也是由N=6个相同层组成。
除了每个编码器层中的两个⼦层之外,解码器还插⼊了第三种⼦层对编码器栈的输出实⾏“多头”的Attention。与编码器类似,我们在每个⼦层两端使⽤残差连接进⾏短路,然后进⾏层的规范化处理。
3. Attention
“多头”机制能让模型考虑到不同位置的Attention,另外“多头”Attention可以在不同的⼦空间表⽰不⼀样的关联关系,使⽤单个Head的Attention⼀般达不到这种效果。
4. Attention在模型中的应⽤
Transformer中以三种不同的⽅式使⽤了“多头”Attention:
1) 在"Encoder-Decoder Attention"层,Query来⾃先前的解码器层,并且Key和Value来⾃Encoder的输出。Decoder中的每个位置Attend输⼊序列中的所有位置,这与Seq2Seq模型中的经典的Encoder-Decoder Attention机制[15]⼀致。
2) Encoder中的Self-attention层。在Self-attention层中,所有的Key、Value和Query都来同⼀个地⽅,这⾥都是来⾃Encoder中前⼀层的输出。Encoder中当前层的每个位置都能Attend到前⼀层的所有位置。
3) 类似的,解码器中的Self-attention层允许解码器中的每个位置Attend当前解码位置和它前⾯的所有位置。这⾥需要屏蔽解码器中向左的信息流以保持⾃回归属性。具体的实现⽅式是在缩放后的点积Attention中,屏蔽(设为负⽆穷)Softmax的输⼊中所有对应着⾮法连接的Value。
5. Position-wise前馈⽹络
6. Embedding和Softmax
7.位置编码
我们也尝试了使⽤预学习的位置Embedding,但是发现这两个版本的结果基本是⼀样的。我们选择正弦曲线版本的实现,因为使⽤此版本能让模型能够处理⼤于训练语料中最⼤序了使⽤列长度的序列。
8.完整模型
下⾯定义了连接完整模型并设置超参的函数。
END. 参考链接
[1] /abs/1706.03762
[2] /
[3] github/harvardnlp/annotated-transformer
[4] le/file/d/1xQXSv6mtAOLXxEMi8RvaW8TW-7bvYBDF/view?usp=sharing
[5] opennmt
[6] github/tensorflow/tensor2tensor
[7] github/awslabs/sockeye
[8] twitter/harvardnlp
[9] /abs/1409.0473
[10] /abs/1308.0850
[11] /abs/1512.03385
[12] /abs/1607.06450
[13] /abs/1409.0473
[14] /abs/1703.03906
[15] /abs/1609.08144
[16] /abs/1608.05859
[17] /pdf/1705.03122.pdf
原⽂:nlp.seas.harvard.edu/2018/04/03/attention.html 想要了解更多资讯,请扫描下⽅⼆维码,关注机器学习研究会

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。