详解Transformer(Attention Is All You Need)

发布于:2023-01-11 ⋅ 阅读:(680) ⋅ 点赞:(0)

详解Transformer(Attention Is All You Need)

简介

Attention机制由Bengio团队于2014年提出,并广泛应用于深度学习的各个领域。然而真正使其广泛应用是在2018年谷歌团队提出了BETR算法,其在NLP的 11 11 11项任务中取得了惊人的效果,而BETR算法的核心就是Transformer机制。

论文地址: https://arxiv.org/abs/1706.03762?amp=1

源码地址https://github.com/jadore801120/attention-is-all-you-need-pytorch

核心思想

Transformer中抛弃了传统的CNNRNN,整个网络结构完全是由Attention机制组成。更准确地讲,Transformer由且仅由self-AttenionFeed Forward Neural Network组成。一个基于Transformer的可训练的神经网络可以通过堆叠Transformer的形式进行搭建,作者的实验是通过搭建编码器和解码器各 6 6 6层,总共 12 12 12层的Encoder-Decoder,并在机器翻译中取得了BLEU值得新高。

原文中,对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.

Transformer详解

1. 从整体看Transformer结构

作者论文中是在machine translation中对Transformer进行介绍的,在这里我也从这个领域进行介绍。

首先, 我们可以将整个Transformer视为一个黑盒子,那么我们的输入就是一种语言,输出就是另一种语言,如下图。


视为黑盒子的Transformer

打开黑盒子,我们可以看到一个编码器和一个解码器,以及他们中间的连接


编码器-解码器结构

继续看编码器和解码器,就会发现编码器由 6 6 6个编码block组成,解码器同样由 6 6 6个解码block组成。


Transformer的Encoder和Decoder均由6个block组成

编码器的结构都是相同的(但他们不共享权重)。每一个被分解成两个子层——Self-Attention 和 Feed Forward Neural Network


编码器由Self-Attention和Feed Forward Neural Network组成

解码器包含编码器的两个结构,同时两者之间还有一个 Encoder-Decoder Attention结构,也被称为 Cross-Attention结构


解码器由Self-Attention、Encoder-Decoder Attention(Cross Attention)和Feed Forward Neural Network组成

因此整体来看,网络结构则如下所示:

Transformer

2. 输入编码

讲完Transformer的主要组件模型后,就详细的从输入部分开始逐个解析。

跟正常的NLP算法相同,首先是通过Word2Vec等嵌入方法,将输入的语料转换为特征向量,原文中使用的词嵌入的维度为 d m o d e l = 512 d_{model} = 512 dmodel=512


单词的输入编码。每个单词都被编码为512的特征向量

嵌入(embedding) 只发生在最底层的编码器block中,编码器其余block的输入是其正下面的block的输出。不过相同的是,他们都是接到一个长度为 512 512 512的特征向量。


输入编码作为一个tensor输入到Encoder中

3. Self-Attention

宏观理解

Self-AttentionTransformer最核心的内容之一。可能大家很多人感觉这个词很熟悉,但其实对我个人而言,在接触到Transformer之前并没有接触过这个概念。所以我首先从宏观角度来解释一下什么是Self-Attention

比如说,我们要翻译下面这个句子

The animal didn't cross the street because it was too tired.

上面的it指的是什么呢?是animal还是street呢?

这对我们人而言是个很简单的问题,但是对于机器或者算法来说就并不是那么简单了。

当模型在处理it的时候,Self-Attention会将itanimal关联起来。

整体来看就是:当模型在处理每个词(输入序列中每个位置)时,Self-Attention使得其可以查看输入序列中的其他位置,以助于为这个词寻找更好的编码。


Attention示例:当我们在编码器的5号block(最顶端的block)中对“it”进行编码时,“Self-Attention”机制将“The Animal”与其进行关联,并且将“The Animal”的一部分特征赋予“it”

细节阐述

我在这里先简化一下Self-Attention的计算,先用向量的方式来进行计算,后续再使用更复杂的矩阵的方式进行计算。

向量计算Self-Attention

计算Self-Attention的步骤:

(1) 首先使用每个输入向量 X X X(在上述例子中是每个词进行编码后的特征向量)乘以三个不同的权重矩阵 W Q , W K , W V W^Q, W^K, W^V WQ,WK,WV,创建三个向量—— Query向量( q q q ),Key向量( k k k )和Value向量( v v v )。

其中,

q , k , v q, k, v q,k,v向量——长度均为 64 64 64

W Q , W K , W V W^Q, W^K, W^V WQ,WK,WV向量——均为 512 × 64 512 \times 64 512×64


Q、K、V计算示意图

(2) 为每一个词向量 X X X计算一个 s c o r e score score,其计算方式如下:

s c o r e = q ⋅ k score = q \cdot k score=qk


score计算示意图

(3) s c o r e score score除以 d k \sqrt{d_k} dk ,即进行计算: s c o r e d k \frac{score}{\sqrt{d_k}} dk score。这使得在训练过程中梯度更加稳定

其中,

d k d_k dk——词向量 k k k隐藏层的维度,在论文中是 64 64 64

(4) 对上述结果进行 s o f t m a x softmax softmax,即进行归一化操作。


(5) s o f t m a x softmax softmax的结果点乘向量 v v v,得到加权后的每个输入向量的评分 v v v

这一步的作用:保持我们关注词向量的特征,并且消除不关注词向量的特征(如将其乘以 0.0001 0.0001 0.0001这样一个极小的值)

(6) 对上述结果求和,这样就得到了Self-Attention中一个单词的输出。


Self-Attention的整体计算过程

这样就结束了Self-Attention的计算过程,并将输出的特征向量 z z z输入到后续的Feed Forward Neural Network

矩阵计算Self-Attention

在实际网络运算过程中,并不是以向量为单位,而是以矩阵为单位进行运算

(1) 计算 Q, K, V \text{Q, K, V} Q, K, V矩阵:通过对矩阵 X \text{X} X点乘训练的权重矩阵 W Q , W K , W V \text{W}^\text{Q},\text{W}^\text{K},\text{W}^\text{V} WQ,WK,WV得到。


Q、K、V计算,每一行的X都代表一个单词

(2)-(6) 之后的计算与向量计算相同,如下所示:


Self-Attention的矩阵形式计算

Self-Attention整体计算过程

(1) 将输入单词转化成嵌入向量

(2) 根据嵌入向量得到 q , k , v q, k, v q,k,v 三个向量

(3) 为每个向量计算一个 s c o r e score score s c o r e = q ⋅ k score = q \cdot k score=qk

(4) 为了梯度的稳定,将 s c o r e score score除以 d k \sqrt[]{d_k} dk

(5) s c o r e score score进行 s o f t m a x softmax softmax激活函数,使得其归一化

(6) s o f t m a x softmax softmax操作后的结果点乘 v v v向量,得到加权的每个输入向量的评分 v v v

(7) 对结果累加,得到最终结果 z = ∑ v z=\sum{v} z=v

Self-Attention中的Short-cut结构

需要注意的是,Self-Attention的输出,并不是直接输入到后续的Feed Forward Neural Network中,而是先输入到一个Layer Normalization层,再向后面层继续传播。

在这里插入图片描述

如果我们将LN层可视化的展示出来,即为:


LN层可视化展示

这样就通过一个LN层,构成了ResNet的残差结构

4. Multi-Head Attention

Multi-Head Attention相当于 h h hSelf-Attention的集成,在原文中使用的是 h = 8 h=8 h=8

在这种机制下,我们有多组 Q , K , V \text{Q}, \text{K}, \text{V} Q,K,V权重矩阵,每一组都是随机初始化的。在训练的时候,每一组代表输入的 X \text{X} X到不同子空间的映射。


Multi-Head Attention的多组权重矩阵

通过这样的方式,我们就可以得到 8 8 8个最终输出的 Z \text{Z} Z矩阵。

在这里插入图片描述

但是下一层的Feed Forward Neural Network并不需要 8 8 8 Z \text{Z} Z矩阵,而是仅需要一个 Z \text{Z} Z矩阵,因此我们需要对输出的 8 8 8个进行处理。

我们将这 8 8 8个矩阵全部concat到一起,并乘以一个单独的权重矩阵 W o \text{W}^{\text{o}} Wo

在这里插入图片描述

这样,我们的整体过程就如下所示:


Multi-Head Attention的全过程

此时,我们尝试用Multi-Head Attention机制重新回顾我们最开始的例子,假设有 2 2 2个注意力头,it这时候的注意力则变为:


在Multi-Head Attention中,注意力关注的点有“The Animal”和“tried”两个,模型对“it”的表征两者都有一些

如果我们把所有的( 8 8 8个)注意力头全部加入进来,则会变为:


8个Self-Attention的结果

5. Encoder-Decoder Attention(Cross Attention)

在解码器中,每个block中比编码器中多一个Encoder-Decoder AttentionCross Attention)。在Cross Attention中, Q \text{Q} Q来自于解码器的上一个输出, K \text{K} K V \text{V} V来源于编码器的输出。其计算过程则与Self-Attention完全相同。
需要特别注意的是,最初始Decoder的输入,也就是上图中的Output Embedding起始符 < / s > </s> </s>,并不包含任何语义信息,仅仅是在第一步的时候用于输入。同样,最后也以一个特殊的结尾符 < B O S > <BOS> <BOS>结束.

由于在机器翻译中,解码过程是一个顺序操作的过程,也就是当解码第 k k k个特征向量时,为我们只能看到 k − 1 k-1 k1及其之前的解码结果,论文中把这种情况下的Multi-Head Attention叫做Masked Multi-Head Attention

6. Loss

这一块就不多说了,损失大家懂的都懂,不懂的短时间内也讲不明白,直接放结果。

原文中用到的Loss主要有 2 2 2

  • CE Loss
  • Kullback-Leibler散度

7. 位置编码

截止到现在,我们对Transformer的描述还缺少一个部分,那就是对输入序列中单词顺序的表征方法,即我们常说的Position Encoding,或者说位置编码。

具体来说,Position Encoding在编码词向量中加入了单词的位置信息,这样Transformer就能区分不同位置的单词了。

通常情况下,位置编码方式有两种

  • 根据数据学习
  • 设计编码规则,按照编码规则来确定位置编码

原文中作者使用第二种方法来进行位置编码。通常位置编码是一个与输入的 X \text{X} X向量等长的特征向量,论文中设其为 d m o d e l d_{model} dmodel,这样有利于和词向量进行单位加操作。


Position Encoding

原文中给出的位置编码公式如下:

P E ( p o s , 2 i ) = sin ⁡ ( p o s 1000 0 2 i d m o d e l ) PE(pos, 2i) = \sin(\frac{pos}{10000^{\frac{2i}{d_{model}}}}) PE(pos,2i)=sin(10000dmodel2ipos)

P E ( p o s , 2 i + 1 ) = cos ⁡ ( p o s 1000 0 2 i d m o d e l ) PE(pos, 2i+1) = \cos(\frac{pos}{10000^{\frac{2i}{d_{model}}}}) PE(pos,2i+1)=cos(10000dmodel2ipos)

其中,

p o s pos pos——单词位置

i i i——单词的维度

d m o d e l d_{model} dmodel——输入词向量长度

关于位置编码的实现,可以在Google开源的算法get_timing_signal_1d()函数中找到对应的代码。

作者这样设计的原因主要是考虑到,在NLP任务中,除了单词的绝对位置,单词的相对位置也非常重要。

根据公式 sin ⁡ ( α + β ) = sin ⁡ α cos ⁡ β + cos ⁡ α sin ⁡ β \sin(\alpha + \beta) = \sin\alpha\cos\beta + \cos\alpha\sin\beta sin(α+β)=sinαcosβ+cosαsinβ,和 cos ⁡ ( α + β ) = cos ⁡ α cos ⁡ β − sin ⁡ α sin ⁡ β \cos(\alpha + \beta) = \cos\alpha\cos\beta - \sin\alpha\sin\beta cos(α+β)=cosαcosβsinαsinβ,这表明位置 k + p k+ p k+p的位置向量可以表示为位置 k k k特征向量的线性变换,这为模型捕捉单词之间的相对位置关系提供了很大的便利。

优缺点

优点

  • 虽然Transformer最终也没有摆脱深度学习的套路,仅仅是一个全连接(或者一维卷积)+Attention的结合,但是其完全抛弃掉在NLP中最根本的RNNCNN,并且取得了很不错的效果。
  • Transformer的独特设计,带来极大性能提升的关键是将任意两个单词的距离是 1 1 1,这对解决NLP中棘手的长期依赖问题非常有效
  • Transformer机制不仅仅可以应用于NLP领域,有很大的扩展空间
  • 算法的并行性非常好,目前的硬件条件完全可以进行相应训练。

缺点

  • 直接抛弃掉RNNCNN虽然创新性很高,但使得模型丧失了捕捉局部特征的能力,互相结合的策略可能会带来更好的结果
  • Transformer机制使得其失去了位置信息,这在NLP中非常重要,而论文中虽然在特征向量中加入了位置编码,但这属于一个权宜之计,并没有改变Transformer在结构上的固有缺陷。

常见问题

1. Q \text{Q} Q K \text{K} K关联性计算的问题

(1)什么是 Q \text{Q} Q K \text{K} K

Q \text{Q} Q:Queries,表示查询
K \text{K} K:Key,表示关键词

这种说法主要借鉴推荐系统中的含义,根据 Q \text{Q} Q K \text{K} K计算关联性,然后推荐 V \text{V} V(但是Self-Attention的目的不是单纯的推荐 V \text{V} V

(2)为什么 Q ⋅ K \text{Q} \cdot \text{K} QK表示计算关联性

首先我们要明确,内积的意义是什么?
内积就是在求取一个向量在另一个向量上的投影长度,其表征的意义就在于 两个向量之间的关联性

(3)既然是计算关联性,为什么不用 X ⋅ X T \text{X} \cdot \text{X}^T XXT

主要有以下两个好处:

  • X \text{X} X通过与权重矩阵点乘,将输入分别变换为 Q ⋅ K \text{Q} \cdot \text{K} QK,解决了可能存在的长度不一致问题
  • 通过中间层,学习到了非线性特征

2. 为什么要在 s o f t m a x softmax softmax之前,除以 d k \sqrt{d_k} dk

  • 论文中提出的观点是:加性注意力Self-Attention机制学习维度较小的时候效果优于点积注意力
  • 个人观点
    • 首先要明确一点: d k d_k dk是词向量隐藏层的维度
    • s o f t m a x softmax softmax之前,肯定要除以一个数,防止输入 s o f t m a x softmax softmax的值过大,导致导数趋近于 0 0 0
    • 选择 d k \sqrt{d_k} dk 是因为:假设 Q , K \text{Q}, \text{K} Q,K是均值为 0 0 0,方差为 1 1 1的分布,则他们的点积: Q ⋅ K T = ∑ i = 1 d k q i k i \text{Q} \cdot \text{K} ^T= \sum_{i=1}^{d_k}q_ik_i QKT=i=1dkqiki的分布是 期望为 0 0 0,方差为 d k \sqrt{d_k} dk 。而此时除以 d k \sqrt{d_k} dk ,则相当于最终结果为期望为 0 0 0方差为 1 1 1的分布,类似于归一化

3. 把自身作为 Q , K \text{Q}, \text{K} Q,K之后为什么还要点乘 V \text{V} V

其实在点乘 V \text{V} V之前的操作,也就是 s o f t m a x ( Q ⋅ K T d k ) softmax(\frac{Q \cdot K^T}{\sqrt{d_k}}) softmax(dk QKT)是在求取一个 s c o r e score score,或者通俗点说就是在求取与一个权重分布,来表示相关性。
而这个权重分布最终还是要反映到初始特征空间中,也就是 V \text{V} V中的。
所以整体来看,其实之前点乘 V \text{V} V之前主要是在的到在 V \text{V} V上的权重分布,最后通过点乘 V \text{V} V得到加权后的值。

本文含有隐藏内容,请 开通VIP 后查看

网站公告

今日签到

点亮在社区的每一天
去签到