深度学习:前沿技术-Tranformer-XL
欢迎转载,作者:Ling,注明出处:深度学习:前沿技术-Tranformer-XL
简介
Transformer-XL架构在vanilla Transformer的基础上引入了两点创新:循环机制(Recurrence Mechanism)和相对位置编码(Relative Positional Encoding),以克服vanilla Transformer的缺点。与vanilla Transformer相比,Transformer-XL的另一个优势是它可以被用于单词级和字符级的语言建模。
详解
循环机制(Recurrence Mechanism)
Vanilla Transformer在训练语言模型时,引入段(Segment),进行分段训练,但是段与段之间缺乏依赖,丢失了信息。Transformer-XL引入了段与段之间的循环机制,使得当前段在建模的时候能够利用之前段的信息来实现长期依赖性。如下图所示:
训练阶段:每个隐藏层都会接收两个输入
- 该段的前面(下面)隐藏层的输出,与Vanilla Transformer相同(上图的灰色线)。
- 前面段的隐藏层的输出(上图的绿色线),可以使模型创建长期依赖关系。
这两个输入会被拼接,然后用于计算当前段的Key和Value矩阵。对于某个段的某一层的具体计算公式如下:
公式解释:
\tau
表示第几段,n
表示第几层,h
表示隐层的输出。SG(⋅)
表示停止计算梯度。[h_u \circ h_v]
表示在长度维度上的两个隐层的拼接,W
是模型参数。- 乍一看与Transformer中的计算公式很像,唯一关键的不同就在于Key和Value矩阵的计算上,即
k_{\tau+1}^n
和v_{\tau + 1}^n
,它们基于的是扩展后的上下文隐层状态\tilde{h}_{\tau+1}^{n-1}
进行计算,{h}_{\tau}^{n-1}
是之前段的缓存。原则上只要GPU内存允许,该方法可以利用前面更多段的信息,测试阶段也可以获得更长的依赖。
测试阶段:更长的上下文信息
利用之前段的数据来预测当前段的输出。
相对位置编码(Relative Positional Encoding)
在Transformer中,一个重要的地方在于其考虑了序列的位置信息。在分段的情况下,如果仅仅对于每个段仍直接使用Transformer中的位置编码,即每个不同段在同一个位置上的表示使用相同的位置编码,就会出现问题。比如,第i-2
段和第i-1
段的第一个位置将具有相同的位置编码,但它们对于第i
段的建模重要性显然并不相同(例如第i−2
段中的第一个位置重要性可能要低一些)。因此,需要对这种位置进行区分。
论文对于这个问题,提出了一种新的位置编码的方式,即会根据词之间的相对距离而非像Transformer中的绝对位置进行编码。在Transformer中,第一层的计算查询q_i^T
和键k_j
之间的attention分数的方式为:
公式解释:
E_{x_i}
是词i的embedding。E_{x_j}
是词j的embedding。U_i
和U_j
是位置向量。- 这个式子实际上是
(W_q(E_{x_i}+U_i))^T·(W_k(E_{x_j}+U_j))
的展开,就是Transformer中的标准格式。
在Transformer-XL中,对上述的attention计算方式进行了变换,转为相对位置的计算,而且不仅仅在第一层这么计算,在每一层都是这样计算。
三点不同:
- 在(b)和(d)这两项中,将所有绝对位置向量
U_j
都转为相对位置向量R_{i-j}
,与Transformer一样,这是一个固定的编码向量,不需要学习。 - 在(c)这一项中,将查询的
U_i^TW_q^T
向量转为一个需要学习的参数向量u
,因为在考虑相对位置的时候,不需要查询的绝对位置i
,因此对于任意的i
,都可以采用同样的向量。同理,在(d)这一项中,也将查询的U_i^TW_q^T
向量转为另一个需要学习的参数向量v
。 - 将键的权重变换矩阵
W_k
转为W_{k, E}
和W_{k, R}
,分别作为content-based key vectors和location-based key vectors。
四个部分:
- 基于内容的“寻址”,即没有添加原始位置编码的原始分数。
- 基于内容的位置偏置,即相对于当前内容的位置偏差。
- 全局的内容偏置,用于衡量key的重要性。
- 全局的位置偏置,根据query和key之间的距离调整重要性。
总结
结合上面两个创新点,将Transformer-XL模型的整体计算公式整理如下,这里考虑一个N层的只有一个注意力头的模型:
其中,\tau
代表第几段,n
代表第几层,h_\tau^0 := E_{s_\tau}
定义为第\tau
段的词向量序列。值得一提的是,计算A
矩阵的时候,需要对所有的i-j
计算W_{k,R}^nR_{i-j}
,如果直接按照公式计算的话,计算时间是O(length)^2
,而实际上i-j
的范围只从0 ~ length,因此可以先计算好这length个向量,然后在实际计算A
矩阵时直接取用即可。
具体的,设M
和L
分别为memory和当前段序列的长度,则i-j
的范围也就为0 ~ M + L - 1。下面的Q矩阵中的每一行都代表着W_{k,R}R_{i-j}
中一个i-j
的可能性,即Q_k = W_{k, R} R_{M+L-1-k}
。
则对于上面公式中的(b)项,即q_i^TW_{k,R}R_{i-j}
,其构成的所有可能向量的矩阵为B
矩阵,其形状为L * (M + L),这是我们最终需要的(b)项的attention结果。
我们进一步定义\tilde{B}
可见,需要的B矩阵的每一行只是\tilde{B}
的向左shift而已。因此,可以直接利用矩阵乘法计算\tilde{B}
即可。设R_{i-j}
的维度为d_R
,q_i
的维度为d_q
,W_{k,R}
矩阵的维度为d_q * d_R
,则直接计算矩阵B的时间复杂度为2* d_q * d_R * L * (M+L)
,而计算\tilde{B}
的时间复杂度为L * d_q * (M + L) + d_q * d_R * (M + L)
,计算量明显不是一个量级(后者要快很多)。
同理,对于(d)项来说,可以对所有的i-j定义需要的矩阵D为$L * (M+L)$:
可以用如下的\tilde{d}
来进行shift得到:
其中Q矩阵已经计算过了,也可以在这一步减少计算量。
参考
Transformer-XL: Attentive Language Models Beyond a Fixed-Length Context