深入浅出Transformer
Transformer
Transformer是NLP的颠覆者,它创造性地用非序列模型来处理序列化的数据,而且还获得了大成功。更重要的是,NLP真的可以“深度”学习了,各种基于transformer的模型层出不穷,如BERT、GPT-2、T-NLG,而且模型参数量呈指数级增长。
Transformer之前,大家的思路都是在改进序列模型,从RNN到LSTM、GRU、Seq2Seq。如果你看过我之前写的深入浅出RNN就会知道,序列模型要靠遍历seq_len来处理data,效率低是显而易见的。不仅如此,深层网络很难收敛,因此,即使像google这样的大公司也只能堆叠10层左右的LSTM。
就在大家都认为“NLP本该如此”时,Transformer横空出世,它通过self-attention实现了对序列化数据的并行处理,不仅提高了计算效率,还打开深度学习的潘多拉魔盒,放出后“大魔王”BERT。从某种程度上说,Transformer的意义比BERT更重大。
Attention
self-attention是attention的进阶版,后者最早出现在机器翻译模型--Seq2Seq中。Figure 2是英文 to 德文的seq2seq模型,encoder和decoder都是RNN(LSTM或GRU),decoder主要是靠encoder提供的hidden state来生成output。
我们知道,RNN的hidden state会随着time step的递进而变化,一旦time step数量较多,也就是seq_len较大时,那么当前的hidden state -- \(h_t\)和早先的hidden state -- \(h_1\),它们的值可能会相差甚远甚至截然相反。这种情况称为记忆遗忘,LSTM虽然在一定程度上能够减轻这种遗忘,但这样还不够。
RNN的每个time step都会有一个output,但它们都没有被用到decoder的训练中。attention的作用就是为了能让这些output能够物尽其用。
如果将encoder的所有output一股脑儿丢给decoder,那效果肯定不好。最好的办法是能知道对于当前这个time step来说,哪些output有用哪些没用,然后取其精华去其糟粕。
attention的做法是给每个output一个权重,然后对所有的output做个加权求和,其计算结果--\(C_t\)将作为参数传给decoder。
Figure 3中最关键的地方就是\(a_t\)的计算,也就是如何为output添加权重。Effective Approaches to Attention-based Neural Machine Translation这篇paper给出了下面三条公式,其中任一条公式都能够用来计算权重,请你记住\(dot\ product\)这条公式,后面会用到。
Multi-Head Attention
Transformer的那篇论文--attention-is-all-you-need是用大白话来写的,没什么难度,如果你能它通读一遍,再搭配代码--The Annotated Transformer学习,那基本上你对它的理解就差不多了。因此,本文只分析它的核心模块--Multi-Head Attention,其他内容不再赘述。
如Figure 4所示,Multi-Head指的是将data均分成N份,再对每个sub-data分别做scaled dot-product attention,最后将所有的计算结果拼接起来。实验表明,multi-attention效果比single attention的效果要好。
\(dk\)是单个attention的隐层神经元数量,等于d_model / n_heads,而d_model是multi-head attention的总的隐层神经元数量,它不需要和hidden_size一致,可以通过linear layer来进行hidden_size和d_model之间的转换。
前面提过,attention layer的重点是为encoder的output添加权重。Scaled dot-product attention,顾名思义,就是以dot-product的方式来计算权重:\(h^T_th^-_s\)。既然Transformer是非序列模型,那就可以并行计算每个time step的attention权重,即:\(QK^T\)。
\(dk\)越大,dot-product的值就越大,而softmax的导数则会越小,这样不利于模型训练,因此,Transformer会将attention的权重不仅要乘以scale -- \(1/\sqrt {d_k}\)。
除了不能太大外,\(dk\)太小也不行。\(dk\)小了,就意味着head数量少了,这样一来,每个attention要处理的seq_len就会变长。实验表明,attention处理短seq_len的精度更高,因此,head数不宜过小。
Q、K、V虽然是三个不同数值的矩阵,但它们都是由同一个data(x或y)分别经过三个不同的Linear layer得到的,因此scaled dot-product attention也称为self-attention,不仅如此,它还可以应用于encoder中。
End
深入浅出Transformer的更多相关文章
- 深入浅出腾讯BERT推理模型--TurboTransformers
Overview TurboTransformers是腾讯最近开源的BERT推理模型,它的特点就是一个字,快.本人用BERT(huggingface/transformers)在V100上做了测试,测 ...
- 深入浅出 Jest 框架的实现原理
English Version | 中文版 深入浅出 Jest 框架的实现原理 https://github.com/Wscats/jest-tutorial 什么是 Jest Jest 是 Face ...
- 【深入浅出jQuery】源码浅析--整体架构
最近一直在研读 jQuery 源码,初看源码一头雾水毫无头绪,真正静下心来细看写的真是精妙,让你感叹代码之美. 其结构明晰,高内聚.低耦合,兼具优秀的性能与便利的扩展性,在浏览器的兼容性(功能缺陷.渐 ...
- 【深入浅出jQuery】源码浅析2--奇技淫巧
最近一直在研读 jQuery 源码,初看源码一头雾水毫无头绪,真正静下心来细看写的真是精妙,让你感叹代码之美. 其结构明晰,高内聚.低耦合,兼具优秀的性能与便利的扩展性,在浏览器的兼容性(功能缺陷.渐 ...
- 深入浅出Struts2+Spring+Hibernate框架
一.深入浅出Struts2 什么是Struts2? struts2是一种基于MVC的轻量级的WEB应用框架.有了这个框架我们就可以在这个框架的基础上做起,这样就大大的提高了我们的开发效率和质量,为公司 ...
- DOM 事件深入浅出(二)
在DOM事件深入浅出(一)中,我主要给大家讲解了不同DOM级别下的事件处理程序,同时介绍了事件冒泡和捕获的触发原理和方法.本文将继续介绍DOM事件中的知识点,主要侧重于DOM事件中Event对象的属性 ...
- DOM 事件深入浅出(一)
在项目开发时,我们时常需要考虑用户在使用产品时产生的各种各样的交互事件,比如鼠标点击事件.敲击键盘事件等.这样的事件行为都是前端DOM事件的组成部分,不同的DOM事件会有不同的触发条件和触发效果.本文 ...
- 深入浅出node(2) 模块机制
这部分主要总结深入浅出Node.js的第二章 一)CommonJs 1.1CommonJs模块定义 二)Node的模块实现 2.1模块分类 2.2 路径分析和文件定位 2.2.1 路径分析 2.2.2 ...
- IOS 网络-深入浅出(一 )-> 三方SDWebImage
首要我们以最为常用的UIImageView为例介绍实现原理: 1)UIImageView+WebCache: setImageWithURL:placeholderImage:options: 先显 ...
随机推荐
- 【JUC】如何理解线程池?第四种使用线程的方式
线程池的概念 线程池的主要工作的控制运行的线程的数量,处理过程种将任务放在队列,线程创建后再启动折现任务,如果线程数量超过了最大的数量,则超过部分的线程排队等待,直到其他线程执行完毕后,从队列种取出任 ...
- 用tarjan求LCA板子(比倍增快)
懒!!直接转载!!!! https://solstice23.top/archives/62
- 节点流(文件流) FileInputStream & FileOutputStream & FileReader & FileWriter
节点流(文件流) FileInputStream(字节流)处理视频类的 FileOutputStream(字节流) FileReader(字符流)处理文本文件 ...
- 二、【Python】机器学习-监督学习
关键词 分类(Classification) 回归(Regression) 泛化(Generalize) 过拟合(Overfitting) 欠拟合(Underfitting) 2.1 分类与回归 监督 ...
- SpringAOP使用及源码分析(SpringBoot下)
一.SpringAOP应用 先搭建一个SpringBoot项目 <?xml version="1.0" encoding="UTF-8"?> < ...
- Java实现 LeetCode 2 两数相加
两数相加 给出两个 非空 的链表用来表示两个非负的整数.其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字. 如果,我们将这两个数相加起来,则会返回一个新的链表来表 ...
- 关于VMware虚拟机启动EFI/UEFI支持
作为较新计算机和操作系统用于引导计算机的技术,可扩展固件接口 (EFI) 正在取代 BIOS.EFI 有时称为统一可扩展固件接口 (UEFI). 使用VMware创建虚拟机,默认还是会使用传统的BIO ...
- python—模块与包
模块: (一个.py文件就是一个模块module,模块就是一组功能的集合体,我们的程序可以导入模块来复用模块里的功能.) 模块分三种: 1.python标准库 2.第三方模块 3.应用程序自定义模块 ...
- CentOS7搭建Pacemaker高可用集群(1)
Pacemaker是Red Hat High Availability Add-on的一部分.在RHEL上进行试用的最简单方法是从Scientific Linux 或CentOS存储库中进行安装 环境 ...
- 7.keras-模型保存和载入
keras-模型保存和载入 1.数据的载入与预处理 import numpy as np from keras.datasets import mnist from keras.utils impor ...