Transformer模型详细介绍

简介

Transformer出自于Google于2017年发表的论文《Attention is all you need》,最开始是用于机器翻译,并且取得了非常好的效果。但是自提出以来,Transformer不仅仅在NLP领域大放异彩,并且在CV、RS等领域也取得了非常不错的表现。尤其是2020年,绝对称得上是Transformer的元年,比如在CV领域,基于Transformer的模型横扫各大榜单,完爆基于CNN的模型。为什么Transformer模型表现如此优异?它的原理是什么?它成功的关键又包含哪些?本文将简要地回答一下这些问题。

Transformer总览

我们知道Transformer模型最初是用于机器翻译的,机器翻译应用的输入是某种语言的一个句子,输出是另外一种语言的句子。如下图:
机器翻译应用

将中间的Transformer模块进一步拆开,可以看到它主要包含Encoders和Decoders两个部分,加了s代表它包含多个encoder和decoder。如下:
如果再进一步拆解开来,在原始的Transformer模型中,Encoders和Decoders部分中都分别包含6个encoder和decoder。
其中每一个encoder和decoder结构都是一样的,这里只是单纯地叠加起来而已。我们主要要关注的是单个encoder和decoder的内部结构,先将encoder的结构展示如下:
encoder结构

encoder的一共包含2层,分别是Self-Attention(SA)层和Feed Forward Neural Network(FFN)层,SA层的作用是在对输出序列中的每个词编码的时候,让编码信息中包含序列中的其他单词的信息,即保存了当前单词与其余单词之间的关系。FFN层就是普通的前向网络,对SA层的输出进行近一步的特征提取。

Self-Attention层

我们现在了解了Transformer模型的整体结构,其实并不复杂。这节主要要介绍其中的Self-Attention层,这也是困扰诸多初学者的部分。相信很多人都是第一次听说self-attention这个词,那么它的工作原理究竟是什么呢?接下来我们一步一步地将它分解开来。
首先我们知道encoder的输入是序列,也就是词向量,也叫做token。毕竟原始的句子,比如英文,是无法直接输入到模型的,我们需要使用类似Word Embedding等方式,将单词转换成一个个固定长度的词向量,比如512维。将词向量序列直接输入encoder,即依次经过SA层和FNN层,如下:

encoder
以上图为例,读者不要被图中的箭头迷惑了,认为z_i只与x_i有关,实际上在SA层的内部,每一个z_i的输出都需要依赖所有的输入x_i,即所谓注意力机制。

Self-Attention的实现细节

这一节通过实际的例子来剖析SA层的实现细节,首先是如何基于向量来计算注意力,然后我们看一下它在实际应用中是如何基于矩阵进行加速的。整个Self-Attention过程可以分为6步,接下来我们来一探究竟。

一、 创建Q、K、V矩阵

首先我们需要为每个输入向量(也就是词向量)创建3个向量,分别叫做Query、Key、Value。那么如何创建呢?我们可以对输入词向量分别乘上3个矩阵来得到Q、K、V向量,这3个矩阵的参数在训练的过程是可以训练的。注意Q、K、V向量的维度是一样的,但是它们的维度可以比输入词向量小一点,比如设置成64,其实这步也不是必要的,这样设置主要是为了与后面的Mulit-head注意力机制保持一致(当使用8头注意力时,单头所处理的词向量维度为512/8=64,此时Q、K、V向量与输入词向量就一致了)。我们假设输入序列为英文的"Thinking Machines",那么对应的Q、K、V向量的计算示例图如下:

Q、K、V向量的计算示意图
计算完成后,对于每一个输入词向量,都有3个Q、K、V向量。比如对于输入向量X_1,对应的QKV向量为q_1, k_1, v_1

但是究竟什么是Q、K、V向量呢?它们的具体含义是什么?如何理解记忆呢?首先Query、Key、Value这个概念出自于信息检索系统,我们以在Youtube上搜索视频为例来具体说明一下它的工作流程。
当你搜索(query)一个特定的视频的时候,搜索引擎会将你的query映射到一组keys(比如视频标题、描述等等)上去,然后去找与这些keys最匹配的视频,也就是values。这就是基于特征的查询的基本原理。整体流程如下:

二、 计算Score

得到Q、K、V矩阵之后,第一步是计算Self-Attention中的score,具体做法如下。以输入序列的第一个单词"Thinking"为例,我们需要计算这个单词与输入序列的所有单词之间的score。当我们在某个位置对单词进行编码时,这个score其实决定了将多少注意力放在输入句子的其他部分上。
score的计算是取当前被计算单词的query向量,以及所有的单词的key向量,取两者的点积来当做当前单词的score。比如我们对输入序列的第一个单词“Thinking”计算score,由于整个序列长度为2,那么第一个score的计算使用q_1k_1的点积,第二个score使用q_1k_1的点积。如下图:

score的计算过程

三、 Softmax

接下来,我们首先将上一步得到的score除以8,为什么是8,因为在第一步中,我们定义了Q、K、V矩阵的维度为64,64开根号为8。这么做的原因是为了保证更加稳定的梯度。然后将结果通过一个Softmax函数,Softmax函数会将scores归一化,使其全部都是整数,并且累加和为1。
Softmax

经过Softmax函数后的score决定了当前单词对每个位置的单词的影响程度。很显然当前单词对当前位置的影响程度一般是最大的。

四、将socre乘以values

接下来,将softmax后的scores乘以values向量,这么做的目的是为了保证我们需要关注的values向量的完整性,并且忽略掉不相关的values向量。例如对不相关的values向量乘以一个0.001,使其变得微不足道。

五、将values累加起来

这一步就很简单,将上一步得到的各个values向量累加起来就得到当前输入词向量的输出向量了。将四五步结合起来看,其实就相当于是一个加权求和操作,其中的权重就是第三步计算出来的scores,整个过程示意图如下:

这就是Self-Attention层的整体计算过程。这个输出向量就是我们需要进一步送往前馈神经网络中的。但是在实际的计算中,为了加快计算速度,我们通常会使用矩阵运算,接下来我们看下如何使用矩阵运算来简化和加速上述的计算步骤。

Self-Attention矩阵计算

第一步是计算Query, Key,和Value向量,我们先将所有的输入词向量拼成一个矩阵X,然后乘以已经训练好的权重矩阵(W^Q,W^K,W^V)

计算QKV矩阵

注意输入矩阵X中的每一行都代表了输入序列中的一个词向量。

剩下的步骤其实就是计算scores,通过softmax函数,再乘以矩阵V,我们可以用一下公式来表示:

多头注意力机制

上面提到的Self-Attention层可以认为是单头的,那什么叫多头注意力机制呢?其实也非常简单,就是对于输入词向量矩阵, 不再只是拥有一组(W^Q,W^K,W^V)权重矩阵,而是拥有多组。这样做主要会带来一下2个好处:

  • 它扩展了模型专注于不同位置的词向量的能力
  • 它给予了attention层多种表示子空间,即拥有多组(W^Q,W^K,W^V)权重矩阵,这样可以将输入词向量映射到不同的特征子空间。
    两头注意力机制

    如果我们将Self-Attention的计算重复8次,每次使用不同的权重矩阵,那么我们就得到了8头注意力机制,论文中的Transformer实现就是8头的。同理,我们也会得到8个不同的输出矩阵z
    但是这会引发一个问题,8个输出矩阵无法输入到encoder下一层的FNN层,所以我们需要设计一种方式来讲这8个输出矩阵聚合成单个矩阵。
    怎么做呢?我们可以首先将这8个矩阵concat起来,然后乘以一个额外的权重矩阵W^O,这样就可以得到与输入词向量一样大小的输出向量,然后再传入FNN层。
    下面是多头注意力机制的整体计算过程图:
    多头注意力机制

Positional Encoding

到目前为止,我们都还没有考虑输入序列的顺序问题。然后对于一句话而言,词的顺序直接影响到了整句话的意思,所以顺序非常重要。Transformer使用了Positional Encoding来解决这个问题,即给每个输入词向量都加上一个位置向量。这些位置向量可以决定每个单词在句子中的位置,或者说可以指示句子中不同单词之间的相对位置。
位置编码

假如输入词向量的维度为4,那么实际的位置编码向量可能是这样的:
位置向量

残差连接

encoder中的SA层基本就讲完了,FFN层其实没有什么特别好说的,就是普通的全连接层。有一点要注意的是,为了解决深度学习中的退化问题,encoder中的SA层和FFN层都采用了残差连接。如下图中虚线部分
残差连接

如果将上图再细化一下,可以得到如下的结构图:
encoder

这便是encoder的整体计算流程图了,Transformer模型中堆叠了多个这样的encoder,无非就是输出连接输入罢了,常规操作。

最后再附上一个Transformer的代码实现,读者有兴趣可以跟着自己复现一下Transformer模型的代码。

参考

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,047评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,807评论 3 386
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,501评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,839评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,951评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,117评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,188评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,929评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,372评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,679评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,837评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,536评论 4 335
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,168评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,886评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,129评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,665评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,739评论 2 351

推荐阅读更多精彩内容