基于RNN和CNN的翻译模型,在处理文字序列时有个问题:它们对序列中不同位置之间的依赖关系的建模并不直接。以CNN的为例,如果要对长距离依赖进行描述,需要多层卷积操作,而且不同层之间信息传递也可能有损失,这些都限制了模型的能力。
为了更好地描述文字序列,研究人员提出了一种新的模型 Transformer。 Transformer 并不依赖任何循环单元或者卷积单元,而是使用一种被称作自注意力网络的结构来对序列进行表示。自注意力可以非常高效的描述任意距离之间的依赖关系,因此非常适合处理语言文字序列。
Transformer 一经提出就受到了广泛关注,现在已经成为了机器翻译中最先进的架构之一。
一、自注意力机制
在RNN中处理文字序列,如果想建立wm 和 w1 之间的关系,需要 m−1 次信息传递。对于长序列来说,词汇之间信息传递距离过长会导致信息在传递过程中丢失,同时这种按顺序建模的方式也使得系统对序列的处理十分缓慢。
自注意力机制直接建立单词 wm与前 m−1 个单词之间的关系,即 wm 与序列中所有其他单词的距
离都是 1。这种方式很好地解决了长距离依赖问题,同时由于单词之间的联系都是相互独立的,因此也大大提高了模型的并行度。
自注意力机制也可以被看作是一个序列表示模型。
比如,对于每个目标位置 j,都生成一个与之对应的源语言句子表示,它的形式如下:
Cj = Sum(αi,jhi) 。其中,hi 为源语言句子每个位置的表示结果, αi,j 是目标位置 j 对 hi 的注意力权重。
以源语言句子为例,自注意力机制将序列中每个位置的表示 hi 看作 query(查询),并且将所有位置的表示看作 key(键)和 value (值)。自注意力模型通过计算当前位置与所有位置的匹配程度,也就是在注意力机制中提到的注意力权重,来对各个位置的 value 进行加权求和。得到的结果可以被看作是在这个句子中当前位置的抽象表示。
这个过程,可以叠加多次,形成多层注意力模型,对输入序列中各个位置进行更深层的表示。
在自注意力机制中,并不是使用类似RNN的记忆能力去访问历史信息。序列中所有单词之间的信息都是通过同一种操作(query 和 key 的相关度)进行处理。这样,表示结果 h˜(他) 在包含"他"这个单词的信息的同时,也包含了序列中其他词的信息。
也就是,序列中每一个位置的表示结果中,都包含了其他位置的信息。从这个角度说, h˜(他) 已经不再是单词"他"自身的表示结果,而是一种在单词"他"的位置上的全局信息的表示。
通常,也把生成 h˜(wi) 的过程看作特征提取,而实现这个过程的模型被称为特征提取器。
二、Transformer架构
2.1 Transformer优势
Transformer 模型仅仅使用自注意力机制和标准的前馈神经网络,完全不依赖任何循环单元或者卷积操作。很好地解决了单词间长距离依赖的问题。自注意力机制非常适合在 GPU 上进行并行化,因此模型训练的速度更快。
Transformer 也可以当作一种表示模型,被大量地使用在NLP的其他领域,甚至图像处理和语音处理中也能看到它的影子。比如,目前非常流行的 BERT 等预训练模型就是基于 Transformer。
Transformer 在 WMT英德和英法机器翻译任务上的性能。它能用更少的计算量(FLOPs)达到比其他模型更好的翻译品质。
Transformer 并不简单等同于自注意力机制。 Transformer 模型还包含了很多优秀的技术,比如:多头注意力、新的训练学习率调整策略等等。这些因素一起组成了真正的 Transformer。
2.2 总体结构
自注意力子层(Self-Attention Sub-layer):使用自注意力机制对输入的序列进行新的表示;
前馈神经网络子层(Feed-Forward Sub-layer):使用全连接的前馈神经网络对输入向量序列进行进一步变换;
残差连接(标记为"Add"):对于自注意力子层和前馈神经网络子层,都有一个从输入直接到输出的额外连接,也就是一个跨子层的直连。残差连接可以使深层网络的信息传递更为有效;
层标准化(Layer Normalization):自注意力子层和前馈神经网络子层进行最终输出之前,会对输出的向量进行层标准化,规范结果向量取值范围,这样易于后面进一步的处理。
以上操作就构成了 Transformer 的一层,各个模块执行的顺序可以简单描述为:
Self-Attention → Residual Connection → Layer Normalization → Feed Forward Network → Residual Connection → Layer Normalization。
解码器中引入了一个额外的编码-解码注意力子层(EncoderDecoder Attention Sub-layer)。这个新的子层,可以帮助模型使用源语言句子的表示信息生成目标语言不同位置的表示。编码-解码注意力子层仍然基于自注意力机制,因此它和自注意力子层的结构是相同的,只是 query、 key、 value 的定义不同。
2.3 位置编码
采用自注意力机制对源语言和目标语言序列进行处理时,直接对当前位置和序列中的任意位置进行建模,忽略了词之间的顺序关系。为了解决这个问题,Transformer 在原有的词向量输入基础上引入了位置编码,来表示单词之间的顺序关系。它是Transformer 成功的一个重要因素。
位置编码的计算方式有很多种, Transformer 使用不同频率的正余弦函数,式中 PE(·) 表示位置编码的函数, pos 表示单词的位置, i 代表位置编码向量中的第几维, dmodel 是 Transformer 的一个基础参数,表示每个位置的隐层大小。
在Transformer 中,位置编码的维度和词嵌入向量的维度相同(均为 dmodel),模型通过
将二者相加作为模型输入。
为什么通过这种计算方式可以很好的表示位置信息?有几方面原因。
首先,正余弦函数是具有上下界的周期函数,用正余弦函数可将长度不同的序列的位置编
码的范围都固定到 [−1,1],这样在与词的编码进行相加时,不至于产生太大差距。
另外位置编码的不同维度对应不同的正余弦曲线,这为多维的表示空间赋予一定意义。
最后,根据三角函数的性质,对于任意固定的偏移量 k, PE(pos + k) 能被表示成 PE(pos) 的线性函数,换句话说,位置编码可以表示词之间的距离。
在实践中发现,位置编码对 Transformer 系统的性能有很大影响。对其进行改进也会带来进一步的性能提升。
2.4 基于点乘的多头注意力机制
Transformer 模型摒弃了循环单元和卷积等结构,完全基于注意力机制来构造模型,其中包含着大量的注意力计算。比如,可以通过自注意力机制对源语言和目标语言序列进行信息提取,并通过编码-解码注意力对双语句对之间的关系进行建模。而这些模块都是由基于点乘的多头注意力机制实现的。
2.4.1 点乘注意力机制
自注意力机制中至关重要的是获取相关性系数,也就是在融合不同位置的表示向量时各位置的权重。 Transformer 模型采用了一种基于点乘的方法来计算相关性系数。这种方法也称为缩放的点乘注意力(Scaled Dot-product Attention)机制。
在注意力机制的计算过程中,包含三个重要的参数,分别是 query,key 和 value。将目标语言每个位置的表示视为编码-解码注意力机制的 Q,源语言句子的表示视为 K 和V。在得到 Q, K 和 V 后,便可以进行注意力的运算,这个过程可以被形式化为:
通过对 Q 和 K 的转置进行矩阵乘法操作,计算得到一个维度大小为 L × L 的相关性矩阵,即 QK_T,它表示一个序列上任意两个位置的相关性。再通过系数 1/√dk进行放缩操作,放缩可以减少相关性矩阵的方差,具体体现在运算过程中实数矩阵中的数值不会过大,有利于模型训练。在此基础上,通过对相关性矩阵累加一个掩码矩阵 Mask,来屏蔽掉矩阵中的无用信息。
然后使用 Softmax 函数对相关性矩阵在行的维度上进行归一化操作,这可以理解为对第 i 行进行归一化,结果对应了 V 中不同位置上向量的注意力权重。对于 value的加权求和,可以直接用相关性系数和 V 进行矩阵乘法得到,即 Softmax(√QKdkT +Mask)和 V 进行矩阵乘。最终得到自注意力的输出,它和输入的 V 的大小是一模一样的。
2.4.2 多头注意力机制 (Multi-head Attention)
"多头"可以理解成将原来的 Q、 K、 V 按照隐层维度平均切分成多份。假设切分 h份,那么最终会得到 Q = {Q1,...,Qh}, K = {K1,...,Kh}, V = {V1,...,Vh}。多头注意力就是用每一个切分得到的 Q, K, V 独立的进行注意力计算,即第 i 个头的注意力计算结果 headi = Attention(Qi,Ki,Vi)。
多头注意力的计算过程:
多头注意力机制的好处是允许模型在不同的表示子空间里学习。在很多实验中发现,不同表示空间的头捕获的信息是不同的,比如,在使用 Transformer 处理自然语言时,有的头可以捕捉句法信息,有的头可以捕捉词法信息。
2.4.3 掩码操作
掩码(Mask)的目的是对向量中某些值进行掩盖,避免无关位置的数值对运算造成影响。 Transformer 中的掩码主要应用在注意力机制中的相关性系数计算,具体方式是在相关性系数矩阵上累加一个掩码矩阵。该矩阵在需要掩码的位置的值为负无穷 −inf(具体实现时是一个非常小的数,比如 −1e9),其余位置为 0,这样在进行了 Softmax 归一化操作之后,被掩码掉的位置计算得到的权重便近似为 0,也就是说对无用信息分配的权重为 0,从而避免了其对结果产生影响。
Transformer 包含两种掩码:
a.句长补全掩码(Padding Mask)
训练样本中每个批次内序列的长度不一样,为了方便对批次内序列进行矩阵表示,需要进行对齐操作,即在较短的序列后面填充 0 来占位(padding 操作)。
b.未来信息掩码(Future Mask)
对于解码器来说,由于在预测的时候是自左向右进行的,即第 t 时刻解码器的输出只能依赖于 t 时刻之前的输出。且为了保证训练解码一致,避免在训练过程中观测到目标语言端每个位置未来的信息,因此需要对未来信息进行屏蔽。
具体的做法是:构造一个上三角值全为-inf 的 Mask矩阵。即在解码器计算中,在当前位置,通过未来信息掩码把序列之后的信息屏蔽掉了,避免了 t 时刻之后的位置对当前的计算产生影响。
2.5 残差网络和层标准化
在 Transformer 的训练过程中,为了避免产生梯度爆炸或者消失,引入了残差操作,将前面所有层的输出加到一起。但为了避免不同层(或子层)的结果之间的差异性较大,造成训练过程不稳定、训练时间较长,在每层中加入了层标准化操作。
在 Transformer 中经常使用的层标准化操作有两种结构,分别是后标准化(Post norm)和前标准化(Pre-norm)。后标准化中先进行残差连接再进行层标准化,而前标准化则是在子层输入之前进行层标准化操作。在很多实践中已经发现,前标准化的方式更有利于信息传递,因此适合训练深层的 Transformer 模型。
2.6 前馈全连接网络子层
Transformer 全连接网络的作用主要体现在将经过注意力操作之后的表示映射到新的空间中,新的空间会有利于接下来的非线性变换等操作。实验证明,去掉全连接网络会对模型的性能造成很大影响。 Transformer 的全连接前馈神经网络包含两次线性变换和一次非线性变换(ReLU 激活函数:ReLU(x) = max(0,x)),每层的前馈神经网络参数不共享。
通常情况下,前馈神经网络的隐层维度要比注意力部分的隐层维度大,而且研究人员发现这种设置对 Transformer 是至关重要的。比如,注意力部分的隐层维度为 512,前馈神经网络部分的隐层维度为 2048。继续增大前馈神经网络的隐层大小,比如设为 4096,甚至 8192,还可以带来性能的增益,但是前馈部分的存储消耗较大,需要更大规模 GPU 设备的支持。因此在具体实现时,往往需要在翻译准确性和存储/速度之间找到一个平衡。
2.7 训练
2.7.1 训练优化器配置
在训练优化器方面,需要注意以下几点:
• Transformer 使用 Adam 优化器优化参数,并设置 β1 = 0.9, β2 = 0.98, ϵ = 10−9
• Transformer 在学习率中同样应用了学习率预热(Warmup)策略。
• 小批量训练(Mini-batch Training):每次从样本中选择一小部分数据进行训练。这种方法的收敛较快,同时易于提高设备的利用率。批次大小通常设置为 2048 或 4096。每一个批次中的句子并不是随机选择的,模型通常会根据句子长度进行排序,选取长度相近的句子组成一个批次。这样做可以减少 padding 数量,提高训练效率。
• Dropout:为了避免过拟合,Transformer 加入了 Dropout 操作。这四个地方用到了Dropout:词嵌入和位置编码、残差连接、注意力操作和前馈神经网络。 Dropout比例通常设置为 0.1。
• 标签平滑(Label Smoothing):简单的说就是给正确答案以外的类别分配一定的概率,而不是采用非 0 即 1 的概率。这样,可以学习一个比较平滑的概率分布,从而提升泛化能力。
2.7.2 模型具体配置
常见的 Transformer 模型有 TransformerBase、 Transformer Big 和 Transformer Deep,具体设置如下:
• Transformer Base:标准的 Transformer 结构,解码器编码器均包含 6 层,隐层维度为 512,前馈神经网络维度为 2048,多头注意力机制为 8 头, Dropout 设为 0.1。
• Transformer Big:为了提升网络的容量,使用更宽的网络。在 Base 的基础上增大隐层维度至 1024,前馈神经网络的维度变为 4096,多头注意力机制为 16 头,Dropout 设为 0.3。
• Transformer Deep:加深编码器网络层数可以进一步提升网络的性能,它的参数设置与 Transformer Base 基本一致,但是层数增加到 48 层,同时使用 Pre-Norm作为层标准化的结构。
2.8 推断
Transformer 解码器生成译文词序列的过程和其它神经机器翻译系统类似,都是从左往右生成,且下一个单词的预测依赖已经生成的单词。
Transformer 在推断阶段无法对所有位置进行并行化操作,因为对于每一个目标语言单词都需要对前面所有单词进行注意力操作,因此它推断速度非常慢。可以采用的加速手段有: Cache(缓存需要重复计算的变量)、低精度计算、共享注意力网络等。