machine-learning-notes
  • 封面
  • 目录
  • 前言
  • 个人前言
  • 机器学习前言
    • 什么是机器学习和模式识别
    • 机器学习的应用
    • 机器学习的流程
    • 不同的机器学习算法对相同数据预测效果不同
    • 快速入门机器学习
    • 机器学习需要参考哪些书
    • 机器学习的学习路径
    • 深度学习的学习路径
    • 互联网机器学习特定岗位所需技能
  • 机器学习面试
  • 数学基础
  • 微积分
    • 泰勒展开
    • e的直观认识
    • 傅里叶变换
    • 希尔伯特空间
  • 线性代数
    • 范数
    • 矩阵求导
    • 特征值
    • 奇异值分解
  • 概率与信息论
    • 综述概率论基本定义
    • 概率论与贝叶斯先验
    • 正态分布
    • 贝叶斯概率
    • 概率符号说明
    • 共轭先验
    • 信息论
  • 数值计算与优化
    • 最小二乘法
    • 等式约束的拉格朗日乘子法
    • 凸优化
      • 凸集和凸函数
      • 凸优化问题
  • 梯度下降算法
    • 随机梯度下降SGD
    • 动量法Momentum
    • 牛顿动量Nesterov
    • AdaGrad
    • RMSprop
    • Adadelta
    • Adam
    • Nadam
    • AMSGrad
    • AdasMax
  • 概率图模型
    • 概率图模型概论
    • 概率图简介
  • 编程基础
  • linux
    • linux常用命令
    • shell
      • 输入输出重定向
  • python
    • python简介
    • python语法
      • 基础语法
      • 数据结构
      • 过程控制
      • 函数
      • 类和对象
      • 文件操作
      • 正则表达式
    • python库
      • numpy
      • pandas
      • scipy
      • matplotlib
      • scikit-learn
    • python应用
      • 排序算法
  • 数据结构与算法
    • 数据结构
    • 算法思想
      • 排序
        • 堆排序
        • 归并排序
        • 快速排序
      • 递归
    • 剑指offer
      • 链表
      • 二叉树
      • 数组
      • 字符串
      • 栈和队列
      • 递归
      • 动态规划
      • 其他
    • leetcode
    • 编程语言
      • c++
  • Hadoop
    • Hadoop简介
    • MapReduce
  • Hive
  • Spark
  • TensorFlow
    • TensorFlow1.0
      • TensorFlow基础
      • TensorFlow基础概念解析
      • TensorFlow机器学习基础
      • Tensorflow分布式架构
    • TensorFlow2.0
  • PyTorch
  • 机器学习
  • 机器学习概论
  • 特征工程
  • 感知机
  • k近邻
  • 朴素贝叶斯
  • 线性模型
    • 最大熵模型
    • 指数族分布与广义线性模型
    • 线性回归
      • Ridge回归(岭回归)
      • Lasso回归
    • Logistic回归-对数几率回归
  • 决策树
  • 支持向量机
    • 线性可分支持向量机与硬间隔最大化
    • 线性支持向量机与软间隔最大化
    • 非线性支持向量机与核函数
    • 序列最小最优化算法SMO
    • SVM总结
  • 集成学习
    • Bagging
      • 随机森林
    • Boosting
      • AdaBoost
      • GradientBoosting
        • GBDT
        • XGBoost
          • XGBoost理论
          • XGBoost实践
    • Stacking
  • 降维
    • PCA主成分分析
    • 流形学习
  • EM算法
  • HMM隐马尔科夫模型
  • CRF条件随机场
  • 聚类
    • k均值聚类
    • 高斯混合模型
  • 主题模型
    • LDA隐狄利克雷分布
  • 知识点
    • 损失函数
    • 负采样
  • 机器学习算法总结
  • 深度学习
  • 深度学习概论
  • ANN人工神经网络
  • 知识点
    • Batch Normalization
  • CNN卷积神经网络
  • 深度学习优化算法
  • RNN循环神经网络
  • LSTM长短期记忆网络
  • GRU门控循环单元
  • GNN图神经网络
    • GNN图神经网络综述
    • GCN图卷积网络
      • GCN图卷积网络初步理解
      • GCN图卷积网络的numpy简单实现
      • GCN图卷积网络本质理解
      • GCN图卷积网络全面理解
      • SEMI-SUPERVISED CLASSIFICATION WITH GRAPH CONVOLUTIONAL NETWORKS ICLR2017
  • 神经网络架构搜索
    • Weight-Agnostic-Neural-Networks Google2019
  • 强化学习
  • 强化学习概论
  • 马尔科夫决策过程
  • 动态规划
  • 无模型方法一:蒙特卡洛
  • 无模型方法二:时间差分
  • 无模型方法三:多步自举
  • 函数近似和深度网络
  • 策略梯度算法
  • 深度强化学习
  • 基于模型的强化学习
  • 强化学习前景
  • 自然语言处理
  • 自然语言处理概论
  • 自然语言
  • 语言模型和中文分词
  • word2vec
    • word2vec概述
    • word2vec算法原理
    • word2vec源码分析
    • word2vec实践
  • Seq2Seq模型和Attention机制
  • Self-Attention和Transformer
  • 知识图谱
  • 推荐系统
  • 推荐系统概论
  • 基础知识
  • 进阶知识
    • 机器学习
      • Factorization Machines ICDM2010
    • embedding
      • Network Embedding
        • LINE: Large-scale Information Network Embedding
    • 深度学习
      • DeepFM: A Factorization-Machine based Neural Network for CTR Prediction 2017
      • DSSM: Learning Deep Structured Semantic Models for Web Search using Clickthrough Data CIKM2013
    • 图卷积网络
      • Graph Convolutional Neural Networks for Web-Scale Recommender Systems KDD2018
    • 强化学习
      • DRN基于深度强化学习的新闻推荐模型
  • 业界应用
    • YouTube
      • Deep Neural Networks for YouTube Recommendations RecSys2016
    • Alibaba
      • Learning Tree-based Deep Model for Recommender Systems KDD2018
      • Deep Interest Network for Click-Through Rate Prediction KDD2018
      • DSIN:Deep Session Interest Network for Click-Through Rate Prediction IJCAI2019
Powered by GitBook
On this page
  • Self-Attention机制和Transformer
  • 模型的思想
  • RNN的缺陷
  • Transformer为何优于RNN
  • Transformer模型架构
  • Encoder模块
  • Self-Attention机制
  • multi-headed Attention
  • 词向量Embedding输入
  • 位置编码
  • skip connection和Layer Normalization
  • Encoder模块汇总
  • Decoder模块
  • Decoder的Mask-Multi-Head-Attention输入端
  • Decoder的Encode-Decode注意力层
  • Decoder的输出
  • Transformer动态流程图
  • Transformer特点
  • 代码实现
  • 参考资料

Was this helpful?

Self-Attention和Transformer

PreviousSeq2Seq模型和Attention机制Next知识图谱

Last updated 5 years ago

Was this helpful?

Self-Attention机制和Transformer

能否不用RNN/LSTM去做自然语言处理呢?如何用深度神经网络去做?可以用Transformer。它可以用注意力机制来代替RNN,而且效果比RNN更好。

论文中给出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。

模型的思想

RNN的缺陷

在没有Transformer以前,大家做神经机器翻译用的最多的是基于RNN的Encoder-Decoder模型:

Encoder-Decoder模型当然很成功,在2018年以前用它是用的很多的。而且也有很强的能力。但是RNN天生有缺陷,只要是RNN,就会有梯度消失问题,核心原因是有递归的方式,作用在同一个权值矩阵上,使得如果这个矩阵满足条件的话,其最大的特征值要是小于1的话,那就一定会出现梯度消失问题。后来的LSTM和GRU也仅仅能缓解这个问题

Transformer为何优于RNN

那如果要获得比RNN更进一步能力的提升,那怎么办呢?Transformer给了我们一种答案。

Transformer中抛弃了传统的CNN和RNN,整个网络结构完全是由Attention机制组成。 作者采用Attention机制的原因是考虑到RNN(或者LSTM,GRU等)的计算限制为是顺序的,也就是说RNN相关算法只能从左向右依次计算或者从右向左依次计算,这种机制带来了两个问题:

  1. 时间片 ttt 的计算依赖 t−1t-1t−1 时刻的计算结果,这样限制了模型的并行能力

  2. 顺序计算的过程中信息会丢失,尽管LSTM等门机制的结构一定程度上缓解了长期依赖的问题,但是对于特别长期的依赖现象,LSTM依旧无能为力。

Transformer的提出解决了上面两个问题:

  1. 首先它使用了Attention机制,将序列中的任意两个位置之间的距离缩小为一个常量;

  2. 其次它不是类似RNN的顺序结构,因此具有更好的并行性,符合现有的GPU框架。

Transformer模型架构

Transformer模型总体的样子如下图所示:总体来说,还是和Encoder-Decoder模型有些相似,左边是Encoder部分,右边是Decoder部分。

Encoder:输入是单词的Embedding,再加上位置编码,然后进入一个统一的结构,这个结构可以循环很多次(N次),也就是说有很多层(N层)。每一层又可以分成Attention层和全连接层,再额外加了一些处理,比如Skip Connection,做跳跃连接,然后还加了Normalization层。其实它本身的模型还是很简单的。

Decoder:第一次输入是前缀信息,之后的就是上一次产出的Embedding,加入位置编码,然后进入一个可以重复很多次的模块。该模块可以分成三块来看,第一块也是Attention层,第二块是cross Attention,不是Self-Attention,第三块是全连接层。也用了跳跃连接和Normalization。

输出:最后的输出要通过Linear层(全连接层),再通过softmax做预测。

再换用另一种简单的方式来解释Transformer的网络结构。

需要注意的上图的Decoder的第一个输入,就是output的前缀信息。

Encoder模块

Self-Attention机制

我们把上图的网络简化一下,理论上Encoder和Decoder只有一个模块,那也算是Transformer。

那我们就来看下最简单的模型,它是怎样工作的。重点是看Encoder和Decoder里面的Attention机制是怎么运作的。

这个绿色的框(Encoder #1)就是Encoder里的一个独立模块。下面绿色的输入的是两个单词的embedding。这个模块想要做的事情就是想把x1x_1x1​转换为另外一个向量r1r_1r1​,这两个向量的维度是一样的。然后就一层层往上传。

转化的过程分成几个步骤,第一个步骤就是Self-Attention,第二个步骤就是普通的全连接神经网络。但是注意,Self-Attention框里是所有的输入向量共同参与了这个过程,也就是说,x1x_1x1​和x2x_2x2​通过某种信息交换和杂糅,得到了中间变量z1z_1z1​和z2z_2z2​。而全连接神经网络是割裂开的,z1z_1z1​和z2z_2z2​各自独立通过全连接神经网络,得到了r1r_1r1​和r2r_2r2​。

x1x_1x1​和x2x_2x2​互相不知道对方的信息,但因为在第一个步骤Self-Attention中发生了信息交换,所以r1r_1r1​和r2r_2r2​各自都有从x1x_1x1​和x2x_2x2​得来的信息了。

如果我们用直觉的方式来理解Self-Attention,假设左边的句子就是输入x1,x2,...,x14x_1,x_2,...,x_{14}x1​,x2​,...,x14​,然后通过Self-Attention映射为z1,z2,...,z14z_1,z_2,...,z_{14}z1​,z2​,...,z14​,为什么叫Self-Attention呢,就是一个句子内的单词,互相看其他单词对自己的影响力有多大。比如单词it,它和句子内其他单词最相关的是哪个,如果颜色的深浅来表示影响力的强弱,那显然我们看到对it影响力最强的就是The和Animal这两个单词了。所以Self-Attention就是说,句子内各单词的注意力,应该关注在该句子内其他单词中的哪些单词上。

具体注意力的不同强弱是怎么计算出来的呢?下面就讲解Self-Attention。

首先说下Attention和Self-Attention的区别

Attention和self-attention的区别

以Encoder-Decoder框架为例,输入Source和输出Target内容是不一样的,比如对于英-中机器翻译来说,Source是英文句子,Target是对应的翻译出的中文句子,Attention发生在Target的元素Query和Source中的所有元素之间。

Self Attention,指的不是Target和Source之间的Attention机制,而是Source内部元素之间或者Target内部元素之间发生的Attention机制,也可以理解为Target=Source这种特殊情况下的Attention。

两者具体计算过程是一样的,只是计算对象发生了变化而已。

下图就是Self-Attention的计算机制。已知输入的单词embedding,即x1x_1x1​和x2x_2x2​,想转换成z1z_1z1​和z2z_2z2​。

转换方式如下:

先把x1x_1x1​转换成三个不一样的向量,分别叫做q1q_1q1​、k1k_1k1​、v1v_1v1​,然后把x2x_2x2​转换成三个不一样的向量,分别叫做q2q_2q2​、k2k_2k2​、v2v_2v2​。那把一个向量变换成另一个向量的最简单的方式是什么?就是乘以矩阵进行变换了。所以,需要三个不同的矩阵WQW^QWQ、WKW^KWK、WvW^vWv,即

q1=x1WQq2=x2WQk1=x1WKk2=x2WKv1=x1WVv2=x2WV\begin{aligned} &q_1=x_1 W^Q\quad q_2=x_2 W^Q\\ &k_1=x_1 W^K\quad k_2=x_2 W^K\\ &v_1=x_1 W^V\quad v_2=x_2 W^V\\ \end{aligned}​q1​=x1​WQq2​=x2​WQk1​=x1​WKk2​=x2​WKv1​=x1​WVv2​=x2​WV​

可以注意到,上述过程中,不同的xix_ixi​分享了同一个WQW^QWQ、WKW^KWK、WvW^vWv,通过这个操作,x1x_1x1​和x2x_2x2​已经发生了某种程度上的信息交换。也就是说,单词和单词之间,通过共享权值,已经相互发生了信息的交换。

然后,有了q1q_1q1​、k1k_1k1​、v1v_1v1​和q2q_2q2​、k2k_2k2​、v2v_2v2​,怎么才能得到z1z_1z1​和z2z_2z2​呢?计算过程是这样子的:我们用v1v_1v1​和v2v_2v2​两个向量的线性组合,来得到z1z_1z1​和z2z_2z2​,即

z1=θ11v1+θ12v2z2=θ21v1+θ22v2\begin{aligned} &z_1=\theta_{11}v_1+\theta_{12}v_2\\ &z_2=\theta_{21}v_1+\theta_{22}v_2 \end{aligned}​z1​=θ11​v1​+θ12​v2​z2​=θ21​v1​+θ22​v2​​

那怎么才能得到组合的权重 θ\thetaθ 呢?有

[θ11,θ12]=softmax(q1k1Tdk,q1k2Tdk)[θ21,θ22]=softmax(q2k1Tdk,q2k2Tdk)\begin{aligned} &[\theta_{11},\theta_{12}]=\text{softmax}\left(\frac{q_1k^T_1}{\sqrt{d_k}},\quad \frac{q_1k^T_2}{\sqrt{d_k}}\right)\\ &[\theta_{21},\theta_{22}]=\text{softmax}\left(\frac{q_2k^T_1}{\sqrt{d_k}},\quad \frac{q_2k^T_2}{\sqrt{d_k}}\right) \end{aligned}​[θ11​,θ12​]=softmax(dk​​q1​k1T​​,dk​​q1​k2T​​)[θ21​,θ22​]=softmax(dk​​q2​k1T​​,dk​​q2​k2T​​)​

通过上述的整个流程,就可以把输入的x1x_1x1​和x2x_2x2​转换成了z1z_1z1​和z2z_2z2​。这就是Self-Attention机制。有了z1z_1z1​和z2z_2z2​,再通过全连接层,就能输出该Encoder层的输出r1r_1r1​和r2r_2r2​。

讲到这里,你肯定很困惑为什么要有qqq、kkk、vvv向量,因为这个思路来自于比较早的信息检索领域,qqq就是query,kkk就是key,vvv就是值,(k,v)就是键值对、也就是用query关键词去找到最相关的检索结果。

举个例子,假设query是5G,然后k-v键值对有

k-v: 5G : Huawei
k-v: 4G : Nokia

那query(5G)和key(5G)的相关性是100%,和key(4G)的相关性是50%。这就是为什么用query,key,value这种概念。

为了得到query,key,value,一个xxx就得做3次乘法,那n个xxx就得做3n3n3n次乘法。为了比较高效的实现矩阵乘法,要进行类似matlab中的向量化操作,因为因为GPU中矩阵运算的复杂度是O(1)O(1)O(1)不是O(N2)O(N^2)O(N2)。如果我们能把上面的操作变为矩阵操作,那我们就能很好的利用GPU做并行计算。具体的矩阵操作如下图所示。

用公式表示即为

Attention(Q,K,V)=softmax(QKTdk)V\text{Attention}(Q,K,V)=\text{softmax}\left(\frac{QK^T}{\sqrt{d_k}}\right)VAttention(Q,K,V)=softmax(dk​​QKT​)V

为什么这里要用矩阵而不是神经网络呢?因为矩阵运算能用GPU加速,会更快,同时参数量更少,更节省空间。

注意,上式中的dkd_kdk​是向量qqq或kkk的维度,这两个向量的维度一定是一样的,因为要做点积。但是vvv的维度和向量qqq或kkk的维度不一定相同。上式为什么要除以dk\sqrt{d_k}dk​​呢?因为为了防止维数过高时QKTQK^TQKT的值过大导致softmax函数反向传播时发生梯度消失。那为什么是dk\sqrt{d_k}dk​​而不是dkd_kdk​呢?这就是个经验值,从理论上来说,就是还需要让QKTQK^TQKT的值适度增加,但不能过度增加,如果是dkd_kdk​的话,可能就不增加了。

multi-headed Attention

如果用不同的WQW^QWQ、WKW^KWK、WvW^vWv,就能得到不同的QQQ、KKK、VVV。multi-headed Attention就是指用了很多个不同的WQW^QWQ、WKW^KWK、WvW^vWv。

那这样的好处是什么呢?可以让Attention有更丰富的层次。有多个QQQ、KKK、VVV的话,可以分别从多个不同角度来看待Attention。这样的话,输入xxx,对于不同的multi-headed Attention,就会产生不同的zzz。

那现在一个xxx就有了多个版本的zzz,那该怎么结合为一个zzz呢?

那就将多个版本的xxx拼接称为一个长向量,然后用一个全连接网络,即乘以一个矩阵,就能得到一个短的xxx向量。

把multi-headed输出的不同的zzz,组合成最终想要的输出的zzz,这就是multi-headed Attention要做的一个额外的步骤。

multi-headed Attention用公式表示就是

MultiHead(Q,K,V)=Contact(head1,...,head2)WOwhere headi=Attention(QWiQ,KWiK,VWiV)\begin{aligned} &\text{MultiHead}(Q,K,V)=\text{Contact}(\text{head}_1,...,\text{head}_2)W^O\\ &\quad\quad \text{where}\ \text{head}_i=\text{Attention}(QW^Q_i,KW^K_i,VW^V_i) \end{aligned}​MultiHead(Q,K,V)=Contact(head1​,...,head2​)WOwhere headi​=Attention(QWiQ​,KWiK​,VWiV​)​

上面讲的是理论和细节,现在从直觉上理解为什么需要multi-headed Attention。

下图是有八个Attention,先看右图,这八个Attention用八种不同的颜色表示,从蓝色到灰色。然后我们可以看到一个单词,在这八个Attention上对句子里每个单词的权重,颜色越深,代表权重越大。我们只挑出橙色和绿色(即第二个和第三个色块),看它们分别是怎样的注意力。然后把橙色和绿色的色块拉长就得到了左边这个图。

我们现在看左边,先看橙色部分,单词it连接的权重最重的是animal,这是从某一个侧面来看,那从另一个侧面来看,看绿色部分,it最关注的是tired。橙色的注意力主要表明it是个什么东西,从东西的角度说明它是一种动物,而不是苹果或者香蕉。如果我们从状态这个层面来看,it这个动物现在是在怎么样的一个状态,它的状态是tired,而不是兴奋。所以不同的Self-Attention Head是不同方面的理解。

词向量Embedding输入

Encoder输入的是单词xxx的embedding,通常有两种选择:

  1. 使用Pre-trained的embeddings并固化,这种情况下实际就是一个Lookup Table。

  2. 对其进行随机初始化(当然也可以选择Pre-trained的结果),但设为Trainable。这样在training过程中不断地对embeddings进行改进。 即End2End训练方式。

Transformer选择后者。

位置编码

输入的时候,不仅有单词的向量xxx,还要加上Positional Encoding,即输入模型的整个Embedding是Word Embedding与Positional Embedding直接相加之后的结果。这是想让网络知道这个单词所在句子中的位置是什么,是想让网络做自注意力的时候,不但要知道注意力要聚焦在哪个单词上面,还想要知道单词之间的互相距离有多远。

为什么要知道单词之间的相对位置呢?因为Transformer模型没有用RNN也没有卷积,所以为了让模型能利用序列的顺序,必须输入序列中词的位置。所以我们在Encoder模块和Decoder模块的底部添加了位置编码,这些位置编码和输入的xxx向量的维度相同,所以可以直接相加,从而将位置信息注入。

想要知道单词之间的距离,就得知道单词的坐标。有很多不同衡量距离的方式,

这里使用不同频率的sinsinsin和coscoscos函数:

PE(pos,2i)=sin(pos100002i/dmodel)PE(pos,2i+1)=cos(pos100002i/dmodel)\begin{aligned} PE_{(pos,2i)}&=sin(\frac{pos}{10000^{2i/d_{model}}})\\ PE_{(pos,2i+1)}&=cos(\frac{pos}{10000^{2i/d_{model}}}) \end{aligned}PE(pos,2i)​PE(pos,2i+1)​​=sin(100002i/dmodel​pos​)=cos(100002i/dmodel​pos​)​

下面举例说明该公式的用法。

为什么这样做呢?用图形的方式可以直觉上理解。下图为一个长度为50,维度是128的句子的Positional Encoding(每一行为一个Encoding向量)。下图中一行就是一个单词的Positional Encoding。

上图可以看出,不同位置的Positional Encoding是独特的。但是计算Positional Encoding的方式不是唯一的,甚至Positional Encoding也可以是train出来的,并不是必须用作者说的sin cos。只要能相互计算距离就可以。但是训练出来的不鲁棒,选择正弦曲线版本是因为它可以使模型外推到比训练过程中遇到的序列更长的序列长度。

Positional Encoding的物理意义是:把50个Positional Encoding两两互相做点击,看相关性。其特点是Encoding向量的点积值对称,随着距离增大而减小。

skip connection和Layer Normalization

LayerNorm(x+Sublayer(x))\text{LayerNorm}(x+\text{Sublayer}(x))LayerNorm(x+Sublayer(x))

,其中Sublayer(x)\text{Sublayer}(x)Sublayer(x)为子模块的输出。

skip connection最早是在计算机视觉的ResNet里面提到的,是微软亚洲研究院的何凯明做的,主要是想解决当网络很深时,误差向后传递会越来越弱,训练就很困难,那如果产生跳跃连接,如果有误差,可以从不同路径传到早期的网络层,这样的话误差就会比较明确地传回来。这就是跳跃层的来历。

跳跃层不是必须的,但在Transformer中,作者建议这样做,在Selft-Attention的前后和每一个Feed Forwar前后都用了跳跃层,如下图中的虚线所示。

Layer Normalize就是对每一层ttt的所有向量进行求均值ulu^lul和方差σl\sigma^lσl,然后归一化到正态分布后,再学习到合适的均值bbb和方差ggg进行再次缩放,即

μt=1H∑i=1Hait,σt=1H∑i=1H(ait−ut)2ht=f[gσt⊙(at−μt)+b]\begin{aligned} & \mu^t=\frac{1}{H}\sum^H_{i=1}a^t_i,\quad \sigma^t=\sqrt{\frac{1}{H}\sum_{i=1}^H(a^t_i-u^t)^2}\\ &h^t=f\left[\frac{g}{\sigma^t}\odot \left(a^t-\mu^t\right)+b\right] \end{aligned}​μt=H1​i=1∑H​ait​,σt=H1​i=1∑H​(ait​−ut)2​ht=f[σtg​⊙(at−μt)+b]​

Layer Normalize和Batch Normalize唯一的区别就是不考虑其他数据,只考虑自己,这样就避免了不同batch size的影响。

下图给出一个对不同样本做Layer Normalization的实例。

Encoder模块汇总

Encoder模块各部分及相关流程如下所示。

Decoder模块

接下来看Decoder模块。论文中Decoder也是N=6层堆叠的结构。被分为3个SubLayer,Encoder与Decoder有三大主要的不同:

  1. Decoder SubLayer-1使用的是“Masked” Multi-Headed Attention机制,防止为了模型看到要预测的数据,防止泄露。

  2. SubLayer-2是一个Encoder-Decoder Multi-head Attention。

  3. LinearLayer和SoftmaxLayer作用于SubLayer-3的输出后面,来预测对应的word的probabilities 。

Decoder的Mask-Multi-Head-Attention输入端

模型训练阶段:

  • Decoder的初始输入:训练集的标签YYY,并且需要整体右移(Shifted Right)一位

  • Shifted Right的原因:T-1时刻需要预测T时刻的输出,所以Decoder的输入需要整体后移一位

举例说明:我爱中国 → I Love China

位置关系:

0-“I”
1-“Love”
2-“China”

操作:整体右移一位(Shifted Right)

0-</s>【起始符】目的是为了预测下一个Token
1-“I”
2-“Love”
3-“China”

具体步骤

  • Time Step 1

    • 初始输入: 起始符</s> + Positional Encoding

    • 中间输入:(我爱中国)Encoder Embedding

    • Decoder:产生预测I

  • Time Step 2

    • 初始输入:起始符</s> + I + Positonal Encoding

    • 中间输入:(我爱中国)Encoder Embedding

    • Decoder:产生预测Love

  • Time Step 3

    • 初始输入:起始符</s> + I + Love + Positonal Encoding

    • 中间输入:(我爱中国)Encoder Embedding

    • Decoder:产生预测China

Transformer Decoder的输入:

  • 初始输入:前一时刻Decoder输入+前一时刻Decoder的预测结果 + Positional Encoding

  • 中间输入:Encoder Embedding

什么是Mask

mask表示掩码,它对某些值进行掩盖,使其在参数更新时不产生效果。Transformer模型里面涉及两种mask,分别是 padding mask和sequence mask。 其中,padding mask在所有的scaled dot-product attention 里面都需要用到,而sequence mask只有在Decoder的Self-Attention里面用到。

Padding Mask

什么是padding mask呢?因为每个批次输入序列长度是不一样的也就是说,我们要对输入序列进行对齐。具体来说,就是给在较短的序列后面填充0。但是如果输入的序列太长,则是截取左边的内容,把多余的直接舍弃。因为这些填充的位置,其实是没什么意义的,所以我们的Attention机制不应该把注意力放在这些位置上,所以我们需要进行一些处理。

具体的做法是,把这些位置的值加上一个非常大的负数(负无穷),这样的话,经过softmax,这些位置的概率就会接近0! 而我们的padding mask 实际上是一个张量,每个值都是一个Boolean,值为false的地方就是我们要进行处理的地方。

Sequence mask

文章前面也提到,sequence mask是为了使得Decoder不能看见未来的信息。也就是对于一个序列,在time_step为t的时刻,我们的解码输出应该只能依赖于t时刻之前的输出,而不能依赖t之后的输出。因此我们需要想一个办法,把t之后的信息给隐藏起来。 那么具体怎么做呢?也很简单:产生一个上三角矩阵,上三角的值全为0。把这个矩阵作用在每一个序列上,就可以达到我们的目的。

sequence mask的目的是防止Decoder “seeing the future”,就像防止考生偷看考试答案一样。这里mask是一个下三角矩阵,对角线以及对角线左下都是1,其余都是0。下面是个10维度的下三角矩阵:

[[1, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 [1, 1, 0, 0, 0, 0, 0, 0, 0, 0],
 [1, 1, 1, 0, 0, 0, 0, 0, 0, 0],
 [1, 1, 1, 1, 0, 0, 0, 0, 0, 0],
 [1, 1, 1, 1, 1, 0, 0, 0, 0, 0],
 [1, 1, 1, 1, 1, 1, 0, 0, 0, 0],
 [1, 1, 1, 1, 1, 1, 1, 0, 0, 0],
 [1, 1, 1, 1, 1, 1, 1, 1, 0, 0],
 [1, 1, 1, 1, 1, 1, 1, 1, 1, 0],
 [1, 1, 1, 1, 1, 1, 1, 1, 1, 1]]

对于Decoder的Self-Attention,里面使用到的scaled dot-product attention,同时需要padding mask和sequence mask作为attn_mask,具体实现就是两个mask相加作为attn_mask。

其他情况,attn_mask一律等于padding mask。

举个例子:

假设最大允许的序列长度为10,先令padding mask为

[0 0 0 0 0 0 0 0 0 0]

然后假设当前句子一共有5个单词(加一个起始标识),在输入第三个单词的时候,前面有一个开始标识和两个单词,则此刻的sequence mask为

[1 1 1 0 0 0]

然后padding mask和sequence mask相加,得

[1 1 1 0 0 0 0 0 0 0]

Decoder的Encode-Decode注意力层

Attention的预测流程和和普通的Encoder-Decoder的模式是一样的,只是用Self-Attention替换了RNN。

在这一层(Decoder中的第二个注意力层),输入不仅有前一层的输出xxx,还有来自Encoder的输出mmm(不然Encoder辛辛苦苦做的输出就没用了),然后把Encoder产生的向量mmm作为Decoder的key和value,Decoder的xxx作为query,然后进行Self-Attention。相当于是,Encoder告诉我key和value是什么,我现[]在要做的就是产生query。即有

q=xWQk=mWKv=mWV\begin{aligned} q&=xW^Q\\ k&=mW^K\\ v&=mW^V \end{aligned}qkv​=xWQ=mWK=mWV​

Decoder的输出

从上图可以看出,Decoder和Encoder唯一的区别就是多了一个Encode-Decode注意力层,然后最后一层接了个linear+softmax层,损失函数就是交叉熵损失。

Decoder的最后一个部分是过一个linear layer将decoder的输出扩展到与vocabulary size一样的维度上。经过softmax 后,选择概率最高的一个word作为预测结果。假设我们有一个已经训练好的网络,在做预测时,步骤如下:

  1. 给Decoder输入Encoder对整个句子embedding的结果和一个特殊的开始符号</s>。Decoder 将产生预测,在我们的例子中应该是 ”I”。

  2. 给Decoder输入Encoder的embedding结果和</s> I,在这一步Decoder应该产生预测 am。

  3. 给Decoder输入Encoder的embedding结果和</s> I am,在这一步Decoder应该产生预测a。

  4. 给Decoder输入Encoder的embedding结果和</s> I am a,在这一步Decoder应该产生预测student。

  5. 给Decoder输入Encoder的embedding结果和</s> I am a student, Decoder应该生成句子结尾的标记,Decoder 应该输出</eos>。

  6. 然后Decoder生成了</eos>,翻译完成。

这里有两个训练小技巧,第一个是label平滑,第二个就是学习率要有个worm up过程,然后再下降。

1、Label Smoothing(regularization)

由传统的

Pi={1, if(i=y)0, if(i≠y)\begin{aligned} P_i=\left\{\begin{matrix} 1,\ \text{if}(i=y)\\ 0,\ \text{if}(i\neq y) \end{matrix}\right. \end{aligned}Pi​={1, if(i=y)0, if(i=y)​​

变为

Pi={(1−ϵ), if(i=y)ϵK−1, if(i≠y)\begin{aligned} P_i=\left\{\begin{matrix} (1-\epsilon),\ \text{if}(i=y)\\ \frac{\epsilon}{K-1},\ \text{if}(i\neq y) \end{matrix}\right. \end{aligned}Pi​={(1−ϵ), if(i=y)K−1ϵ​, if(i=y)​​

注:KKK表示多分类的类别总数,ϵ\epsilonϵ是一个较小的超参数。

学习率不按照这样可能就得不到一个好的Transformer。

lr=dmodel−0.5⋅min(step_num−0.5, step_num⋅warmup_steps−1.5)lr=d^{-0.5}_{\text{model}}\cdot min(step\_num^{-0.5},\ step\_num \cdot warmup\_steps^{-1.5})lr=dmodel−0.5​⋅min(step_num−0.5, step_num⋅warmup_steps−1.5)

Transformer动态流程图

Encoder通过处理输入序列开启工作。Encoder顶端的输出之后会变转化为一个包含向量KKK(键向量)和VVV(值向量)的注意力向量集 ,这是并行化操作。这些向量将被每个Decoder用于自身的“Encoder-Decoder注意力层”,而这些层可以帮助Decoder关注输入序列哪些位置合适:

在完成Encoder阶段后,则开始Decoder阶段。Decoder阶段的每个步骤都会输出一个输出序列(在这个例子里,是英语翻译的句子)的元素。接下来的步骤重复了这个过程,直到到达一个特殊的终止符号,它表示Transformer的解码器已经完成了它的输出。每个步骤的输出在下一个时间步被提供给底端Decoder,并且就像Encoder之前做的那样,这些Decoder会输出它们的Decoder结果 。

Transformer特点

  • 优点

    • 每层计算复杂度比RNN要低。

    • 可以进行并行计算。

    • 从计算一个序列长度为n的信息要经过的路径长度来看, CNN需要增加卷积层数来扩大视野,RNN需要从1到n逐个进行计算,而Self-attention只需要一步矩阵计算就可以。Self-Attention可以比RNN更好地解决长时依赖问题。当然如果计算量太大,比如序列长度N大于序列维度D这种情况,也可以用窗口限制Self-Attention的计算数量。

    • 从作者在附录中给出的栗子可以看出,Self-Attention模型更可解释,Attention结果的分布表明了该模型学习到了一些语法和语义信息。

  • 缺点,在原文中没有提到缺点,是后来在Universal Transformers中指出的,主要是两点:

    • 有些RNN轻易可以解决的问题Transformer没做到,比如复制String,或者推理时碰到的sequence长度比训练时更长(因为碰到了没见过的position embedding)

    • 理论上:transformers不是computationally universal(图灵完备),而RNN图灵。完备,这种非RNN式的模型是非图灵完备的的,无法单独完成NLP中推理、决策等计算问题(包括使用transformer的bert模型等等)。

代码实现

  • 哈佛大学自言语言处理组的notebook,很详细文字和代码描述,用pytorch实现

  • Google的TensorFlow官方的,用tf keas实现

参考资料

本文主要内容是这个视频课程的笔记。

本文的整体架构参考了此博客。

很多资料上的图都是来自于这个英文博客。

“mask”部分参考了此博客。

===

pdf:

Transformer模型在论文《》中被提出,利用Attention,去掉RNN。这篇论文的题目想说的是:你只需要用到Attention机制,完全不需要再用到RNN,就能解决很多问题。Transformer没有用到RNN,而且它的效果很好。

self-attention-gpu

Add & Norm模块接在Encoder端和Decoder端每个子模块的后面,其中Add表示残差连接,Norm表示LayerNorm,残差连接来源于论文,LayerNorm来源于论文,因此Encoder端和Decoder端每个子模块实际的输出为:

如上图所示,同时,还用了Normalize,用的是一种新的,不是常用的Batch Normalize。是一种正则化的策略,避免网络过拟合。

Layer Normalization的方法可以和Batch Normalization对比着进行理解,因为Batch Normalization不是Transformer中的结构,这里不做详解,详细清楚的解释请看这里:。

transformer-process

2、

Attention Is All You Need
Attention Is All You Need
Deep Residual Learning for Image Recognition
Layer Normalization
Layer Normalize
NLP中 batch normalization与 layer normalization
Noam Learning Rate Schedule
https://nlp.seas.harvard.edu/2018/04/03/attention.html
https://www.tensorflow.org/tutorials/text/transformer
贪心科技“ 共同战疫” NLP系列专题直播
深入理解Transformer及其源码
The Illustrated Transformer
Transformer模型详解
Transformer学习总结——原理篇
Transformer模型中,decoder的第一个输入是什么?
transformer的细节到底是怎么样的?
B站李宏毅深度学习Transformer2019
通俗易懂!使用Excel和TF实现Transformer
小强公众号: Self-Attention与Transformer
transformer中为什么使用不同的K 和 Q, 为什么不能使用同一个值?
放弃幻想,全面拥抱Transformer:自然语言处理三大特征抽取器(CNN/RNN/TF)比较
返回顶层目录
返回上层目录
模型的思想
RNN的缺陷
Transformer为何优于RNN
Transformer模型架构
Encoder模块
Self-Attention机制
multi-headed Attention
词向量Embedding输入
位置编码
skip connection和Layer Normalization
Encoder模块汇总
Decoder模块
Decoder的Mask-Multi-Head-Attention输入端
Decoder的Encode-Decode注意力层
Decoder的输出
Transformer动态流程图
Transformer特点
代码实现
paper
encoder-decoder
rnn-vanishing-gradient
transformer-model-architecture
transformer-encoder-decoder
transformer-encoder-decoder-simplify
encoder-introduction
self-attention-intuiation
self-attention
multi-head-attention
multi-head-attention-2
multi-headed-attention-3
multi-headed-attention-4.jpg
multi-headed-attention-5
positional-encoding
positional-encoding-2
positional-encoding-3
positional-encoding-4
skip-connection-and-layer-normalization
layer-normalize
layer-normalize-2
encoder-part
transformer-process-2
transformer-process-2
encoder-decoder-2.jpg
encoder-output
lr-worm-up
transformer-process-1
transformer-process-2