一、优点与时间复杂度比较
自注意力网络能够捕捉到比LSTM更长的上下文依赖关系,由此也打破固定窗口内的上下文信息距离限制,虽然这一定程度上造成了时间复杂度的损失:
我们假设是序列长度,是输入向量的维度,是隐藏层的大小,那么对4个门控单元(输入门、遗忘门、输出门、候选记忆单元)的时间复杂度为(4倍可忽略),因为涉及到输入向量和隐藏状态的矩阵乘法。因此顺序处理的整个复杂度为:
对于transformer,假设模型有层,那么总的复杂度为
但是自注意力通过掩码(mask,遮盖住句子内该字的后文信息)和一定程度的Teacher-Foring思想(采用标签生成下一个词,而不是上一个输出)可以在同一时间内对整个序列进行计算,没有时间步之间的依赖关系,因此这种并行计算能力可以极大地提高训练和推理速度。
二、Q、K、V矩阵的理解
在其它的资料中,成Q为查询矩阵,K为键矩阵,V为值矩阵,但事实上这样的命名方式并不导致三者用不同的训练方式训练,命名是根据再使用时的差异而带来的,因此网上有诸多理解。而三者的计算过程如下:
假设输入序列为矩阵,包含个词,每个词的表示为一个维向量,那么它就是一个维的矩阵。
第一步进行线性变换,对输入序列的每个词,我们通过三组不同的权重矩阵将其变换为查询矩阵Q,键矩阵K和值矩阵V:
这里面的三种权重矩阵都是(一般Q,K取相同维度列,记为)维,乘完后的矩阵大小都是行的。
里面的参数都是可以在后期优化的。引入权重矩阵的目的是哪怕每个词的维向量仅仅能起到不重复,不存在相近的词在空间上的距离更近的性质,也能通过各自的权重矩阵进行调整,也就是赋予三个自注意力矩阵各自的功能性。(都是下角标)
第二步计算注意力得分,公式为:
其中,的形状为,的形状为,因此的形状为,点积后的结果为。
此时理论上我们就建立出了词与词的相互关系矩阵,换句话说如果点乘后的结果值较高,说明模型“注意到”句子中第个位置的词和第个位置的词有一定关系。这似乎解决了两个问题:
Q:为什么要用转置表示?
A:可能是为了结构的统一和大小表示的便利,因为似乎一开始就指定K是转置的也能行得通;
Q:为什么网上有对、矩阵的多种解释?
A:训练方式都一样,所以纯靠自己理解就有了多种解释。我倾向于一种解释是提供了行信息所以起到定位到哪一行称之为查询,然后确定为具体的哪一列所以为Key。
此时的只表示各个token之间的相关性,不包含语义信息和序列信息。
第三步是进行缩放控制,公式是:
(这里的k是下角标不是k次方)
就是为了缩放防止数值过大,使训练更稳定。
第四步加权求和值,公式如下:
网上将解释为查询得到的值,注意这里也是乘过权重矩阵的,我理解为因此更能体现出token本身的一些性质。
此时回顾论文里的图:
这里面的MatMul表示矩阵相乘,Scale是进行缩放,而Mask是一个可选项,作用是在某些特定情况下忽略这里的计算,主要有两种情况:
第一种是序列掩码,我们会使用填充标记(如)填充较短序列到相同长度,计算这里的注意力显然是没有意义的,因此算权重时会把该部分置为负无穷,使得softmax趋为0,防止影响注意力分布。
第二种是未来掩码,用于在自回归模型(如语言模型)中,避免模型在预测当前词块时看到未来的词块信息。通常用于解码器中的自注意力计算,以确保模型只能看到当前位置及其之前的词块,而不能看到之后的词块。其形状可以参考下图:
与其相乘后对应无穷大位置的信息会缺失,也就是无法看到未来的词。
三、多头注意力网络
为了增强拟合能力,我们可以多训练几组注意力头,使其各自的权重中注意到矩阵中更多的不同信息。具体实现方式是假如我有6个自注意力头,各自训练好后进行拼接(Concat),得到一个的矩阵,再使用线性变换降为到原来想要的维度。
上图是论文中多头自注意力的示意图。
四、位置编码
在前文中我们提到了此时输入的是缺乏位置信息的,而transformer用位置编码的方式将位置信息嵌入进入:
其中,是词块的位置,是维度索引,仍然是输入向量的维度。
一般认为使用正余弦函数的原因是因为他们连续且平滑,因此模型能捕捉到相邻位置之间的关系;而周期性的特征也使即使较远距离之间的关系也可以后面通过权重矩阵捕捉到,不会相差太多;同时如果使用不同频率的正弦和余弦函数,位置编码能够捕捉到不同尺度的相对位置信息。高频部分可以捕捉到局部的信息,低频部分可以捕捉到全局的信息。此外还可以使用三角函数的和差化积简化运算。
而分母现在10000是一个经验选择,一方面是能覆盖足够宽的频率范围,也使得足够区分较长序列。
得到位置编码后,就能得到最终的输入矩阵:
后者是前文使用的只有嵌入表示信息的;也都是下标。
五、Transformer完整模型
1、Add&Norm层
Add类似于ResNet的残差网络,通过跳跃连接在输入和输出间添加一个短路路径,直接将输入与该层输出相加,用于防止梯度消失。
Norm是层归一化,用来提高训练的稳定性和速度,其公式如下:
其中,是均值,是标准差,和是可学习参数,是个很小的常数防止除零错误。
2、Feed Forward层
Feed Forward 层是一个位置无关的全连接网络,它对每个位置的向量独立进行相同的线性变换和非线性变换。具体来说,Feed Forward 层包括一个线性变换和一个ReLu激活函数,再叠加一个线性变换。公式如下:
3、Transformer结构图
此时完整结构图基本都够看懂,左半部分被N框住的部分表示Encoder Block,可以任意叠加多层,右部分被N框住的则是Deocder Block,差别在于:
Encoder Block只有一个 Multi-Head Attention 层,而 Deocder Block包含两个 Multi-Head Attention 层。其中第一个 Multi-Head Attention 层需要采用 Mask 操作用于遮挡未来掩码。第二个 Multi-Head Attention 层的 和 矩阵使用 Encoder 的编码信息矩阵 (也就是 Encoder Block 的输出矩阵),而 使用上一个 Decoder Block 的输出。