Transformer
是谷歌 2017
年发表在 NeurlIPS
上的文章 Attention is all you need
中提出的模型。 Transformer
模型仅基于注意力机制,能够有效捕捉输入序列中的长距离依赖关系,完全不涉及循环和卷积,解决了传统的序列到序列( Seq2Seq
)模型处理可变长序列时存在的问题( RNN
处理长序列时易出现梯度消失或爆炸,不能并行计算,难以捕捉长距离依赖关系。 CNN
卷积操作的输入需要具有固定尺寸,处理可变长序列时为使序列长度相同需要填充短序列因而效率较低)。实验表明其在质量上更优越,更易于并行化,训练时间也大大减少。
Transformer
模型
注意力的直观理解
例 1
:一个海边的画面,其中包含 Elements = ['海鸥', '沙滩', '落日', '礁石', '天空']
等要素,我们看到这个画面时对这些要素的印象和关注度有不同的程度,在不同物体上分配的注意力也有所不同,假如自然情况下看到画面后在各个要素上的注意力为 [30, 15, 20, 50, 25]
。现在我们额外给出一个条件 '动物'
,则对各要素的注意力会发生相应变化,假设变成了 [80, 10, 5, 20, 15]
。那么这里 Q = '动物'
做查询(与 K
进行匹配,以确定哪些信息是重要的), alpha = [80, 10, 5, 20, 15]
是对各要素的注意力权重分配。在提出条件前我们对全部要素有一个天然的注意力分配权重,就是 K = [30, 15, 20, 50, 25]
, K
称为键(与Q进行匹配,用于计算注意力权重)。新的注意力分配 alpha = [80, 10, 5, 20, 15]
实际上是根据 Q
对 K
进行调整得到的,即 alpha = f(Q,K)
。我们不能直接将语言词汇交给机器,而是先将其转化成数值,假设要素 Elements
的对应数值为 V = [v1, v2, v3, v4, v5]
, V
称为值(实际的信息内容)。我们最终获得的脑海中的印象是 y = alpha*V = alpha_1*v1+alpha_2*v2+...+alpha_5*v5
。
例 2
:文本翻译中我们对原句 Text = 'He is a student.'
进行逐字翻译,翻译每个字的时候其对原句 Text
中的每个词的注意力是不同的。实际过程中我们先输入一个文本句子 Text
,用分词器将其分词得到 Elements = ['He', 'is', 'a', 'student']
,再将分词转化成数值(词向量) X = [x1, x2, x3, x4, x5]
,其中 xi
是数值向量。任意数值向量 xi
经过一个全连接层(即线性变化)得到 vi
, xi
经过另一个全连接层(即线性变化)得到 ki
。这样就得到了 X
的键 K = [k1, k2, k3, k4, k5]
和值 V = [v1, v2, v3, v4, v5]
。同样的,对一个查询的原分词 'somequery'
,词向量为 xq
, xq
经过另一个全连接层(线性变换)得到查询 q
, q
和 ki
作用得到对 xi
的注意力分配权重 alpha_i = f(q,ki)
,最终计算结果为 alpha_1*v1+...+alpha_5*v5
。
模型结构
如图所示,左侧为编码器( encoder
),右侧为解码器( Transformer
),编码器负责将输入序列转换成适合后续处理的表示形式,解码器根据这种表示形式生成目标序列。
编码器方框内的结构由 N
个相同的层组成(文中取 N=6
),每层由两个子层组成,分别为多头自注意力机制( Multi-head self-attention mechanism
)和逐位置全连接层( position-wise fully connected feed-forward network
),每个子层添加残差连接( residual connection
),残差连接后进行层规范化( layer normalization
)。
解码器同样由 N
个相同的层组成,每层包含三个子层,第一和第三个子层是多头注意力机制和逐位置全连接层,第二个子层用于对编码器的输出实施多头注意力。我们对每个子层添加残差连接然后层规范化。为了确保一个词的生成只能依赖它之前的词,我们对解码器中的自注意力子层进行一定修改,引入遮蔽( Masking
),遮蔽通过对自注意力矩阵中的某些元素进行掩码(即设置为负无穷大或一个非常小的值,这样在后续的 softmax
操作中这些元素的影响将被忽略)来实现。具体来说,对于每个位置 i
,遮蔽会确保位置 i
不能“注意到”任何位置 j
(其中 j>i
)的信息,即位置 i
的生成只能依赖于它之前的所有位置。此外输出嵌入是偏移一个位置的:在训练过程中,解码器的输入通常包括目标序列(即我们想要模型学习的输出序列)的左移版本,这意味着在生成第 i
个位置的词时,解码器的输入实际上是目标序列的第 i-1
个词(如果 i=0
,则通常是一个特殊的开始符号),这样做是为了在解码过程中保持与自注意力遮蔽的一致性,即确保模型在生成第 i
位置的词时,只能看到到目前为止已经生成的词(即位置小于 i
的词)。
解码器最后的全连接层 Linear
的输出神经元个数等于字典中词汇总数,然后经过 Softmax
层就得到了每个词的概率,选取概率最大的那个词汇作为结果。
数据进入 Transformer
模型后的处理过程
以文本翻译为例,现有输入序列数据(例如 'He is a student.'
),编码器负责充分理解这句话,解码器负责处理翻译任务。
编码器部分:原始数据 Inputs = 'He is a student.'
首先经过分词(变成 X = ['He', 'is', 'a', 'student