美文网首页
Transformer模型详细介绍

Transformer模型详细介绍

作者: HaloZhang | 来源:发表于2021-07-15 20:50 被阅读0次

    简介

    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模型的代码。

    参考

    相关文章

      网友评论

          本文标题:Transformer模型详细介绍

          本文链接:https://www.haomeiwen.com/subject/ilszoktx.html