搞懂Transformer结构,看这篇PyTorch实现就够了
作者丨Alexander Rush
来源丨哈工大SCIR
编辑丨极市平台
下面分享一篇实验室翻译的来自哈佛大学一篇关于Transformer的详细博文。
"Attention is All You Need"[1] 一文中提出的Transformer网络结构最近引起了很多人的关注。Transformer不仅能够明显地提升翻译质量,还为许多NLP任务提供了新的结构。虽然原文写得很清楚,但实际上大家普遍反映很难正确地实现。
所以我们为此文章写了篇注解文档,并给出了一行行实现的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 http://download.pytorch.org/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的全连接前馈网络。
Dncoder
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] https://arxiv.org/abs/1706.03762
[2] https://pytorch.org/
[3] https://github.com/harvardnlp/annotated-transformer
[4] https://drive.google.com/file/d/1xQXSv6mtAOLXxEMi8RvaW8TW-7bvYBDF/view?usp=sharing
[5] http://opennmt.net
[6] https://github.com/tensorflow/tensor2tensor
[7] https://github.com/awslabs/sockeye
[8] https://twitter.com/harvardnlp
[9] https://arxiv.org/abs/1409.0473
[10] https://arxiv.org/abs/1308.0850
[11] https://arxiv.org/abs/1512.03385
[12] https://arxiv.org/abs/1607.06450
[13] https://arxiv.org/abs/1409.0473
[14] https://arxiv.org/abs/1703.03906
[15] https://arxiv.org/abs/1609.08144
[16] https://arxiv.org/abs/1608.05859
[17] https://arxiv.org/pdf/1705.03122.pdf
原文 :http://nlp.seas.harvard.edu/2018/04/03/attention.html
觉得有用麻烦给个在看啦~
搞懂Transformer结构,看这篇PyTorch实现就够了相关推荐
- 一下子搞懂JDBC,看这篇就够了--以MySQL为例。
一下子搞懂JDBC,看这篇就够了–以MySQL为例. 文章目录 一下子搞懂JDBC,看这篇就够了--以MySQL为例. 一.什么是JDBC? 二.JDBC的使用步骤 三.jdbc进阶--上述各个类或接 ...
- 搞懂缓冲区,看这篇文章就够了
不管是操作系统,还是学语言,大家应该都听过缓冲区,那么什么是缓冲区?缓冲区又位于什么地方?在这篇文章,小编将带你了解缓冲区.❄️❄️❄️先让我们欣赏下面的一张图,让我们恭僖EDG夺得冠军.❄️❄️ ...
- python协程详解_彻底搞懂python协程-第一篇(关键词1-4)
任何复杂的概念或系统都不是凭空出现的,我们完全可以找到它的演化历程,寻根究底终会发现,其都是在一系列并不那么复杂的简单组件上发展演化而来! by 落花僧 本文通过一系列关键概念,逐步递进理解协程. 0 ...
- 【深度学习】搞懂 Vision Transformer 原理和代码,看这篇技术综述就够了
作者丨科技猛兽 编辑丨极市平台 导读 本文对Vision Transformer的原理和代码进行了非常全面详细的解读,一切从Self-attention开始.Transformer的实现和代码以及Tr ...
- 搞懂 Vision Transformer 原理和代码,看这篇技术综述就够了
↑ 点击蓝字 关注极市平台 作者丨科技猛兽 编辑丨极市平台 极市导读 本文对Vision Transformer的原理和代码进行了非常全面详细的解读,一切从Self-attention开始.Trans ...
- 彻底清楚搞懂toRef和toRefs是什么,也许你知道toRef和toRefs,一直有点蒙蔽,一直没搞懂它,看完这篇文章你彻底清楚
首先我们知道为什么要用toRef和toRefs,这篇文章让你彻底搞懂 比如我们使用 reactive来创建一个对象 <script> import {reactive} from &quo ...
- hashmap 允许key重复吗_搞懂 HashMap,这一篇就够了
HashMap 概述 「如果你没有时间细抠本文,可以直接看 HashMap 概述,能让你对 HashMap 有个大致的了解」. HashMap 是 Map 接口的实现,HashMap 允许空的 key ...
- 一文看懂Transformer内部原理(含PyTorch实现)
Transformer注解及PyTorch实现 原文:http://nlp.seas.harvard.edu/2018/04/03/attention.html 作者:Alexander Rush 转 ...
- 【Transformer】一文搞懂Transformer | CV领域中Transformer应用
目录 阅读本文的基础: 一.发展历史: 二.从上向下的理解Transformer 1.Transformer整体结构简单介绍 2.Transformer中的Self-attention (1)引入 ( ...
最新文章
- windows常用命令(高级语句篇)
- debin linux 指令手册,debianGNULinux系统应用手册.pdf
- 跳槽必看:产品经理面试试题汇总
- 高可用性、负载均衡的mysql集群解决方案
- 十个不可不看的Matlab GUI
- linux输出和错误信息文件,Log4j配置将错误信息输出到指定文件中[linux tomcat]
- 泰森中国宣布与阿里云达成战略合作
- 从何润东代言团宝,看团购行业逐渐成熟
- WiRadius认证计费管理系统
- 人工智能在围棋程序中的应用
- html文字纵向导航栏,JS+CSS实现另类带提示效果的竖向导航菜单
- Python实现图片转pdf
- Horizon 桌面用户会话10h后超时断开
- 如何搭建一个自己的微信公众号
- php 中文 无法写入 mysql_php数据库不能存入中文
- 获取SD卡序列号和厂商ID
- 十大人文科技类图书(转)
- CNN网络结构发展演变:从LeNet到HRNet(一)
- 群晖 NAS 与 百度云网盘互相进行同步
- 开源杀毒软件CLAMWIN