深度解析 XLNet
作者: 追一科技 AI Lab 研究员 Tony
在预训练语言模型 BERT 对自然语言处理的冲击还未平息时,CMU 和 Google 的研究员又放出了一个猛料:在 20 多项任务上全线碾压 BERT 的 XLNet。本文将回顾 XLNet 背后语言表征学习的思想演进,并拆解 XLNet 模型设计的巧妙之处。
1. 语言表征学习
深度学习的基本单元是向量。我们将建模对象对应到各自的向量 x \mathbf{x} x (或者一组向量 x 1 , x 2 , . . . , x n \mathbf{x}_1, \mathbf{x}_2, ..., \mathbf{x}_n x1,x2,...,xn),然后通过变换、整合得到新的向量 h \mathbf{h} h,再基于向量 h \mathbf{h} h 得到输出的判断 y \mathbf{y} y。这里的 h \mathbf{h} h 就是我们说的表征(Representation),它是一个向量,描述了我们的建模对象。而语言表征学习就是解决怎么样将一个词、一句话、一篇文章通过变换(Transformation)和整合(Aggregation)转化成对应的向量 h \mathbf{h} h 的问题。
深度学习解决这个问题的办法是人工设计一个带有可调参数的模型,通过指定一系列的输入输出对 ( x i → y i ) (\mathbf{x}^i \to \mathbf{y}^i) (xi→yi),让模型学习得到最优的参数。当参数确定之后,模型除了可以完成从 x \mathbf{x} x 预测 y \mathbf{y} y 的任务之外,其中间把 x \mathbf{x} x 变换成 h \mathbf{h} h 的方法也是可以用到其他任务的。这也是我们为什么要做表征学习。
所以我们要解决的问题便是
- 怎么确定输入输出对,即模型的预测任务
- 这个模型怎么设计
2. 分布式语义假设(Distributional Hypothesis)
任何任务都可以用来做表征学习:情感分析(输入句子,判断句子是正向情感还是负向情感),机器翻译(输入中文,输出英文)。但是这些任务的缺点是需要大量的人工标注,这些标注耗时耗力。当标注量不够时,模型很容易学出"三长一短选最短"的取巧方案 – 但我们想要的是真正的语言理解。
所幸语言学的研究中有一个重要的假设 – 分布式语义假设(Distributional Hypothesis):
One shall know a word by the company it keeps.[1]
我们可以通过一个词出现的语境知道这个词的意思。
所以我们可以将输入 x \mathbf{x} x 定为目标词的语境,输出 y \mathbf{y} y 定为目标词。这个任务的优点是我们并不需要人工标注的数据,只需要许多有意义的语段就可以了 – 而在信息爆炸的互联网时代,这种数据是取之不尽的。
如何更精细地建模语境,得到其对应的表征向量 h \mathbf{h} h?对这个问题的解答贯穿了语言表征学习的发展历程。我们希望能够做到:
- 语境要包含所有区分目标词的信息。只有这样才不会有歧义的出现,比如给定语境 “我 今天 很”,目标词(下一个词) 既可以是 “开心”,也可以是"伤心",所以模型学不到 “开心” 和 “伤心” 的区别。语境要足够大,如对于一篇文章中的一个目标词,理想的语境是文章中除了目标词的所有词。
- 建模语境中词的相互依赖关系。除了词本身的性质外(这决定了词的依赖关系,比如形容词可以修饰名词短语,猫一般不会用巍峨来修饰),在大部分语言(如中文,英文)中,词的相对位置也决定了词间的依赖关系。
下文开始我们会围绕这个句子展开讨论:
我 1 今 天 2 很 3 开 心 4 , 5 因 为 6 我 7 中 8 了 9 彩 票 10 我_1 今天_2 很_3 开心_4 ,_5因为_6 我_7 中_8 了_9 彩票_{10} 我1今天2很3开心4,5因为6我7中8了9彩票10
下标代表词在句子中的位置编号。 我 1 我_1 我1 和 我 7 我_7 我7 虽然是同一个词,但因为出现在句子的不同位置,所以他们表达的意思可能不同。假设我们的目标词是 开 心 4 开心_4 开心4。语境中不应该含有 开 心 4 开心_4 开心4,因为这会造成标签泄露 – 我们在提出问题的同时也直白地给出了答案 – 此时模型很难学出有用的语言知识。所以理想的语境建模应基于 我 1 今 天 2 很 3 , 5 因 为 6 我 7 中 8 了 9 彩 票 10 我_1 今天_2 很_3 ,_5因为_6 我_7 中_8 了_9 彩票_{10} 我1今天2很3,5因为6我7中8了9彩票10。
3. 预训练词向量(Word Embedding)
神经网络刚开始进入自然语言处理的时候,预训练词向量(Word Embedding)的方法如 Skip-gram, Glove 等是语言表征学习的主要手段。由于缺乏有效建模词的相互依赖的手段,我们使用目标词前后的窗口内的词作为目标词的语境词(Context Word),每个词/语境词都有一个独立的向量作为其表征。
假如窗口长度是 2 的话,在上述例子中,我们可以得到的输入-输出对为 ( 很 → 开 心 ) (很 \to 开心) (很→开心), ( , → 开 心 ) (,\to 开心) (,→开心), ( 今 天 → 开 心 ) (今天 \to 开心) (今天→开心), ( 因 为 → 开 心 ) (因为 \to 开心) (因为→开心)。为了避免统计稀疏性,我们丢弃了词的位置信息。
这种语境建模方式非常粗糙。滑动窗口只是词间相互依赖的一种粗略估计。同时单个语境词不足以表达丰富的语境信息 – 这是由语境中不同词相互依赖共同决定的。这使得该预测任务存在大量的歧义。最后由于缺乏对语境的细致建模,我们只能学到单个词的模糊的表征。
4. 循环神经网络(Recurrent Neural Network, RNN)
用一个向量代表一个词在预训练词向量流行之后已经变成标准做法,也是我们用上神经网络模型组件的基础。我们的句子可以表示成一个有顺序的向量序列 [ x 我 , x 今 天 , x 很 , x 开 心 , x , , x 因 为 , x 我 , x 中 , x 了 , x 彩 票 ] [\mathbf{x}_{我}, \mathbf{x}_{今天}, \mathbf{x}_{很}, \mathbf{x}_{开心}, \mathbf{x}_{,},\mathbf{x}_{因为}, \mathbf{x}_{我}, \mathbf{x}_{中}, \mathbf{x}_{了}, \mathbf{x}_{彩票}] [x我,x今天,x很,x开心,x,,x因为,x我,x中,x了,x彩票]
为了从这个向量序列计算出对应的表征向量 h \mathbf{h} h ,我们必须对这个向量序列进行变换(Transformation) 和整合(Aggregation)。循环神经网络(Recurrent Neural Network, RNN)通过一个递归算子实现了这个目的:
h t = RNN ( h t − 1 , x t ) = tanh ( W h h t − 1 + W x x t ) \mathbf{h}_t = \textrm{RNN}(\mathbf{h}_{t-1}, \mathbf{x}_t) = \tanh(\mathbf{W}_h\mathbf{h}_{t-1} + \mathbf{W}_x\mathbf{x}_t ) ht=RNN(ht−1,xt)=tanh(Whht−1+Wxxt)
我们按照一个顺序(从左到右)对上述向量序列编号: [ x 1 , x 2 , x 3 , x 4 , x 5 , x 6 , x 7 , x 8 , x 9 , x 10 ] [\mathbf{x}_{1}, \mathbf{x}_{2}, \mathbf{x}_{3}, \mathbf{x}_{4}, \mathbf{x}_{5},\mathbf{x}_{6}, \mathbf{x}_{7}, \mathbf{x}_{8}, \mathbf{x}_{9}, \mathbf{x}_{10}] [x1,x2,x3,x4,x5,x6,x7,x8,x9,x10]。按照编号的顺序,在第 t t t 位时,循环神经网络会根据第 t − 1 t-1 t−1 位的表征 h t − 1 \mathbf{h}_{t-1} ht−1 及当前的输入 x t \mathbf{x}_t xt 算出当前位置的表征 h t \mathbf{h}_t ht – 这便是序列 [ x 1 , x 2 , . . . , x t ] [\mathbf{x}_{1}, \mathbf{x}_{2},..., \mathbf{x}_{t}] [x1,x2,...,xt] 对应的表征。可以看到输入向量的相对位置决定了循环神经网络整合信息的计算顺序,或者说相对位置决定了计算图(Computation Graph)的构建。
5. 自回归语言模型(Auto-regressive Language Modeling)
在拥有循环神经网络这一序列建模利器之后,我们可以对语境进行更精细的建模。由于 RNN 的运算模式是按顺序依次处理每个词,所以语境可以是目标词前面的所有词。
对于例子 我 1 今 天 2 很 3 开 心 4 , 5 因 为 6 我 7 中 8 了 9 彩 票 10 我_1 今天_2 很_3 开心_4 ,_5因为_6 我_7 中_8 了_9 彩票_{10} 我1今天2很3开心4,5因为6我7中8了9彩票10,编号顺序是从左到右的话,对应的输入-输出对为 ( 我 今 天 很 → 开 心 ) (我 今天 很 \to 开心) (我今天很→开心);而从右到左则对应的是 ( 彩 票 了 中 我 因 为 → 开 心 ) (彩票 了中我因为 \to 开心) (彩票了中我因为→开心)。因为目标词总是语境的下一个词,所以我们并不需要输入目标词的位置信息。如前所述,词的相对位置决定了词的输入顺序,所以词的位置也不再需要输入了。
自回归语言模型的优点是计算效率比较高。我们只要对 我 1 今 天 2 很 3 开 心 4 , 5 因 为 6 我 7 中 8 了 9 彩 票 10 我_1 今天_2 很_3 开心_4 ,_5因为_6 我_7 中_8 了_9 彩票_{10} 我1今天2很3开心4,5因为6我7中8了9彩票10 这句话做一次表征计算,便可以得到许多输入输出对的语境表征: ( 我 → 今 天 ) (我 \to 今天) (我→今天), ( 我 今 天 → 很 ) (我 今天 \to 很) (我今天→很), ( 我 今 天 很 → 开 心 ) (我 今天 很 \to 开心) (我今天很→开心) 等等。
自回归语言模型也是自然语言生成的标准方案 – 一个句子的生成可以转化成以前面的片段为语境,预测下一个词的任务。而新预测的词可以拼到已经生成的片段,作为预测下一个词所依据的语境。
由于可以对语境进行建模,预训练词表征便可以从语境无关的词向量变成基于语境的词表征(Contextual Representation)。再结合增大数据量带来的巨大增益,这也使得 2018 年发表的 ELMo 成为自然语言处理领域第一个刷榜的大新闻。
但这种语境建模方式只使用了目标词左边(右边)单方向的所有词,所以预测任务仍然会存在歧义。语料中输入输出对 ( 我 1 今 天 2 很 3 → 开 心 ) (我_1 今天_2 很_3 \to 开心) (我1今天2很3→开心) 和 ( 我 1 今 天 2 很 3 → 伤 心 ) (我_1 今天_2 很_3 \to 伤心) (我1今天2很3→伤心) 都有可能出现,所以模型学不到 “开心” 和 “伤心” 的区别。
如何将目标词左右的语境(双向语境)同时引入建模便成为下一个需要解决的问题。一个简单的做法是分别学一个前向及后向的自回归语言模型,然后再将两个模型学出的表征合并。这便是 ELMo 里的标准做法。然而这种独立建模虽然拿到了两个方向的语境信息,但却学不出两个语境间细致的依赖关系。
6. Transformer
双向语境的建模困难主要源于循环神经网络单向、顺序的计算方式。除了限制依赖关系的方向之外,这种计算方式也限制了循环神经网络能建模的最大依赖距离。 x 1 \mathbf{x}_1 x1 和 x 300 \mathbf{x}_{300} x300 的间依赖关系需要通过重复计算 300 次 h t = RNN ( h t − 1 , x t ) \mathbf{h}_t = \textrm{RNN}(\mathbf{h}_{t-1}, \mathbf{x}_t) ht=RNN(ht−1,xt) 才能求得。而由于循环神经网络中存在矩阵乘法,在计算 h 300 \mathbf{h}_{300} h300 时 x 1 \mathbf{x}_1 x1的信息被相同的矩阵乘了 300 次 ( W h 300 x 1 \mathbf{W}_h^{300} \mathbf{x}_1 Wh300x1),视矩阵 W h \mathbf{W}_h Wh 的模不同,会导致信息的爆炸( ∥ W h ∥ 2 > 1 \|\mathbf{W}_h\|_2 >1 ∥Wh∥2>1)或者消失( ∥ W h ∥ 2 < 1 \|\mathbf{W}_h\|_2 <1 ∥Wh∥2<1)。
我们既要取得双向依赖建模,又要让长距离的依赖中间间隔的计算操作尽可能的少。Transformer 的提出实现了这两个目的。细节如层归一化(Layer Normalization),多注意力算子(Multi-Head Attention)可以参考原论文,这里主要介绍最核心的自注意力算子(Self-Attention),及其基础 – 注意力算子(Attention)。
我们先介绍注意力算子(Attention)。注意力算子的基本元素为查询向量(Query Vector) q i \mathbf{q}_i qi,地址向量(Key Vector) k j \mathbf{k}_j kj 以及内容向量(Value Vector) v j \mathbf{v}_j vj。其输出 h i \mathbf{h}_i hi 为所有内容向量的加权求和,每个权重由查询向量和地址向量算出的注意力权重(Attention Score)决定。
h i = ∑ j a i j v j = ∑ j attentionScore ( q i , k j ) v j = ∑ j q i ⊤ k j ⋅ v j \mathbf{h}_i = \sum_j a_{ij} \mathbf{v}_j = \sum_j\textrm{attentionScore}(\mathbf{q}_i, \mathbf{k}_j)\mathbf{v}_j = \sum_j \mathbf{q}_i^\top\mathbf{k}_j\cdot \mathbf{v}_j hi=∑jaijvj=∑jattentionScore(qi,kj)vj=∑jqi⊤kj⋅vj
注意力算子达到的目的是基于查询向量对一组表征信息进行聚合。
回到建模依赖关系的问题上。既然每个词都可能对其他词产生依赖,那我们让每个词都用注意力算子从其他词那里聚合信息不就好了嘛!这便是自注意力(Self-Attention) 的动机。
对于第 i i i 个词,我们可以根据其词向量 x i \mathbf{x}_i xi 算出其对应的查询向量、地址向量以及内容向量:
q i , k i , v i = W q x i , W k x i , W v x i \mathbf{q}_i, \mathbf{k}_i, \mathbf{v}_i = \mathbf{W}_q\mathbf{x}_i, \mathbf{W}_k\mathbf{x}_i, \mathbf{W}_v\mathbf{x}_i qi,ki,vi=Wqxi,Wkxi,Wvxi
在进行表征聚合时, q \mathbf{q} q 来自要求表征的词, k \mathbf{k} k 和 v \mathbf{v} v 来自所有词(包括要求表征的词本身)。“自注意力(Self-Attention)” 中之所以有 “自(Self)”,是因为查询、地址和内容的角色均来自同一个序列。
自注意力算子的引入解决了循环神经网络的两个问题:第 i i i 个词表征 h i \mathbf{h}_i hi 的构建可以同时基于双向的语境;词间不管依赖距离多长,都只间隔了一次运算操作。
但是自注意力算子会引入新的问题 – 词的相对位置的信息被丢弃了。回到我们的例句 我 1 今 天 2 很 3 开 心 4 , 5 因 为 6 我 7 中 8 了 9 彩 票 10 我_1 今天_2 很_3 开心_4 ,_5因为_6 我_7 中_8 了_9 彩票_{10} 我1今天2很3开心4,5因为6我7中8了9彩票10,丢弃词的相对位置意味着在自注意力算子眼里, 我 1 我_1 我1 和 我 7 我_7 我7 表达的意思是一样的。解决这个问题的方法是将位置作为词表征的一部分一并输入模型。Transformer 采用的是简单粗暴的加法: 我 1 我_1 我1 和 我 7 我_7 我7 的表征分别为 x ^ 我 1 = x 我 + p 1 \hat{\mathbf{x}}_{我_1}=\mathbf{x}_{我} + \mathbf{p}_{1} x^我1=x我+p1, x ^ 我 7 = x 我 + p 7 \hat{\mathbf{x}}_{我_7}=\mathbf{x}_{我} + \mathbf{p}_{7} x^我7=x我+p7,其中 p 1 \mathbf{p}_{1} p1 和 p 7 \mathbf{p}_{7} p7 是位置 1 和 7 对应的位置编码(Position Embedding)。这和循环神经网络截然不同:在循环神经网络里,相对位置决定了计算的顺序,而在 Transformer 里则是决定了词的表征。在后文会提到,将位置纳入词表征的做法在 XLNet 中被巧妙地利用了。
Transformer 在每个词基于语境的表征时会同时用上前后语境,但是自回归语言模型却限制了语境的方向。鉴于自回归语言模型在自然语言生成中的普遍应用,为了使用灵活的 Transformer 进行建模,我们需要对 Transformer 进行相应的修改。解决方案是对计算出的注意力权重进行屏蔽 – 我们强行将不想要的注意力权重置为 0,这样计算表征的时候就不会用到目标词及其右边的词了 – 这些词的注意力权重为 0。这称之为注意力掩码(Attention Mask)。这一点也是构建 XLNet 训练目标所必须的技巧。再加上对下游任务的适配以及大量的数据,GPT 和 GPT-2 也搞了一波大新闻。
上述构造技巧再加上多注意力算子(Multi-Head Attention) 以及标准深度学习组件的组合(Dropout, Position-Wise FeedForwrd Layer, Layer Normalization),Transformer 给自然语言处理的建模方式带来了变革性的贡献,无愧其名 “Transformer”(改革者)。
7. 去噪自编码模型(Denoising Auto-encoder)/掩码语言模型(Masked Language Modeling)
加入 Transformer 后,我们的军火库多了建模双向语境的武器。但是如前所述,自注意力算子构建的是第
i
i
i 个词基于语境的表征,使用这个表征来预测第
i
i
i 个词会带来标签泄露。这就好比在给你出题的时候顺便直白地告诉了你答案。
我们既想用上 Transformer 的建模能力,又想从第 i i i 个词的表征中剔除这个词的信息。以 BERT 为代表的去噪自编码模型(Denoising Auto-Encoder)/掩码语言模型(Masked Language Modeling)的做法是将这些词替换成特殊字符 “MASK”。“MASK” 对应的表征即为原来词的语境表征,既获得了双向语境的信息,又避免了标签泄露,可以用来预测原来的词。为了复用计算出的表征,BERT 会随机选取多个词替换成 “MASK”,然后在对应的位置分别预测原来的词。由于这些词都被替换成相同的字符 “MASK”,他们对应的语境表征计算的区别主要来自于其位置编码。
对于本文开头的例子,我们构建的输入-输出对为 ( [ 我 1 今 天 2 很 3 MASK 4 , 5 因 为 6 我 7 中 8 了 9 彩 票 10 ∣ p 4 ] → 开 心 ) ([我_1 今天_2 很_3 \textrm{MASK}_4 ,_5因为_6 我_7 中_8 了_9 彩票_{10}| \mathbf{p}_4] \to 开心) ([我1今天2很3MASK4,5因为6我7中8了9彩票10∣p4]→开心)。由于预测目标取决于位置,所以我们的输入增加了位置编码 p 4 \mathbf{p}_4 p4。
虽然结合 Transformer 和去噪自编码模型的 BERT 可以说是拿到了语境建模的"双向圣杯",其设计的次句判断任务(Next sentence prediction)也对下游任务有重要帮助。但是人无完人,BERT 无完 BERT。BERT 中 “MASK” 字符的加入,使得非目标词表征的建模都会依赖于人造的 “MASK” 字符,这会使模型学出虚假的依赖关系(比如 “MASK” 可以作为不同词信息交换的桥梁) – 但 “MASK” 在下游任务中并不会出现。这便是 XLNet 中提到的预训练-微调差异(Pretrain-Finetune Discrepancy)。同时除了位置编码 p \mathbf{p} p 的区别外,同一句话内所有目标词依赖的语境信息完全相同,这除了忽略被替换的词间的依赖关系外,随着网络层数的加深,作为输入的位置编码 p \mathbf{p} p 的信息也可能被过多的计算操作抹去(类似于上述循环神经网络难以建模长程依赖的原因)。
8. XLNet 的核心贡献: 乱序语言模型(Permutation Language Modeling)
如上所述,BERT 虽然充分地建模了双向语境信息,但是其用来预测不同目标词的语境信息只有目标位置编码的区别,同时也建模不了被替换成 “MASK” 的词间的依赖关系。自回归语言模型虽然只能建模单向的语境,但是其计算效率比较高,且预测每个词所用的语境都是不一样的。怎么把这两者的长处结合呢?
回顾我们对自回归语言模型的介绍。对于一句话 我 1 今 天 2 很 3 开 心 4 , 5 因 为 6 我 7 中 8 了 9 彩 票 10 我_1 今天_2 很_3 开心_4 ,_5因为_6 我_7 中_8 了_9 彩票_{10} 我1今天2很3开心4,5因为6我7中8了9彩票10,我们得到的输入输出样本为 ( 我 → 今 天 ) (我 \to 今天) (我→今天), ( 我 今 天 → 很 ) (我 今天 \to 很) (我今天→很), ( 我 今 天 很 → 开 心 ) (我 今天 很 \to 开心) (我今天很→开心)等等。这些样本中的语境毫无例外都是单向且有序的。
对样本语境的选取是否可以更灵活一些?在上述对分布式语义假设的介绍中我们提到,语境中的词之间的相互依赖关系,一是取决于词本身的性质,二是取决于语境中词的相对位置。所以有了词以及词在语境中的位置,我们就有了从这个词构建依赖关系的全部信息。所以对于同一句话 我 1 今 天 2 很 3 开 心 4 , 5 因 为 6 我 7 中 8 了 9 彩 票 10 我_1 今天_2 很_3 开心_4 ,_5因为_6 我_7 中_8 了_9 彩票_{10} 我1今天2很3开心4,5因为6我7中8了9彩票10,我们可以使用更灵活的样本选取办法,得到 ( 我 1 → 开 心 4 ) (我_1 \to 开心_4) (我1→开心4), ( 我 1 开 心 4 → 今 天 2 ) (我_1 开心_4 \to 今天_2) (我1开心4→今天2), ( 我 1 今 天 2 开 心 4 → 很 3 ) (我_1 今天_2 开心_4 \to 很_3) (我1今天2开心4→很3) 等等。这便是乱序语言模型(Permutation Language Modeling)的思想。和自回归语言模型不一样,新的样本中的语境需要输入词的位置,否则就退化成了词带模型(Bag of Words)。这可以类比到人的阅读方式:字词在书本上的位置是一定的,但从左到右的阅读顺序并不是强制的,我们还可以跳读。
从概率模型的角度考虑,上述对样本的采样方式的不同对应了对句子概率 P ( 我 1 今 天 2 很 3 开 心 4 , 5 因 为 6 我 7 中 8 了 9 彩 票 10 ) P(我_1 今天_2 很_3 开心_4 ,_5因为_6 我_7 中_8 了_9 彩票_{10}) P(我1今天2很3开心4,5因为6我7中8了9彩票10) 的不同分解。
对于自回归语言模型,其分解方式为
P ( 我 1 今 天 2 很 3 开 心 4 , 5 因 为 6 我 7 中 8 了 9 彩 票 10 ) = P ( 我 1 ) P ( 今 天 2 ∣ 我 1 ) P ( 很 3 ∣ 我 1 今 天 2 ) P ( 开 心 4 ∣ 我 1 今 天 2 很 3 ) . . . P(我_1 今天_2 很_3 开心_4 ,_5因为_6 我_7 中_8 了_9 彩票_{10}) = P(我_1)P( 今天_2 |我_1)P(很_3|我_1 今天_2)P(开心_4|我_1 今天_2 很_3)... P(我1今天2很3开心4,5因为6我7中8了9彩票10)=P(我1)P(今天2∣我1)P(很3∣我1今天2)P(开心4∣我1今天2很3)...
对于乱序语言模型,其分解方式可以为
P ( 我 1 今 天 2 很 3 开 心 4 , 5 因 为 6 我 7 中 8 了 9 彩 票 10 ) = P ( 我 1 ) P ( 开 心 4 ∣ 我 1 ) P ( 今 天 2 ∣ 我 1 开 心 4 ) P ( 很 3 ∣ 我 1 今 天 2 开 心 4 ) . . . P(我_1 今天_2 很_3 开心_4 ,_5因为_6 我_7 中_8 了_9 彩票_{10}) = P(我_1)P( 开心_4 |我_1)P(今天_2|我_1 开心_4)P(很_3|我_1 今天_2 开心_4 )... P(我1今天2很3开心4,5因为6我7中8了9彩票10)=P(我1)P(开心4∣我1)P(今天2∣我1开心4)P(很3∣我1今天2开心4)...
每一种分解方式由一个随机排列 z z z 确定,如上述分解方式对应 z = [ z 1 , z 2 , z 4 , z 3 , . . . ] = [ 我 1 → 今 天 2 → 开 心 4 → 很 3 → . . . ] z = [z_1 ,z_2 , z_4 , z_3 , ...] = [ 我_1 \to 今天_2 \to开心_4 \to 很_3 \to ...] z=[z1,z2,z4,z3,...]=[我1→今天2→开心4→很3→...], 其中 z t z_t zt 代表随机排列的第 t t t 个词。乱序语言模型是自回归语言模型的一种推广,因为 z z z 可以是原来序列的顺序。
乱序语言模型的语境可以同时来自目标词的前向和后向,所以其建模了双向的依赖。每个被预测的词(除最后一个词外)都会加入到语境中,所以既解决了 BERT 忽略被替换的词间的依赖关系的问题,又解决了 BERT 不同目标词依赖的语境趋同的问题。相比于 BERT 一次性输入几乎所有的语境信息,乱序语言模型可以认为是对双向语境进行了采样(或者 Embedding Dropout),这会产生类似于 Dropout 效果,可以让模型学出更鲁棒的语境依赖。
但需要注意的是,当构成语境的词比较少时,根据语境预测目标词的歧义性就会增大,训练难度也会增大。这也是为什么 XLNet 只采样了一小部分词去预测的原因。
讲了这么多好处,那如何用 Transformer 实现乱序语言模型呢?
9. 乱序语言模型的实现:双自注意力通道(Two Stream Self-Attention)
Transformer 中每个词的表征由其词向量和位置编码共同决定 – 我们既拿到了词本身的性质,又有词的位置信息。所以 Transformer 天然就和乱序语言模型相契合。
假设整句话为 我 1 今 天 2 很 3 开 心 4 我_1 今天_2 很_3 开心_4 我1今天2很3开心4,我们只采样出一个样本 ( 今 天 2 很 3 开 心 4 → 我 1 ) (今天_2 很_3 开心_4 \to 我_1 ) (今天2很3开心4→我1),XLNet 的做法和 BERT 有同有异。
和 BERT 一样,XLNet 同样是将目标词 我 1 我_1 我1 替换成一个特殊字符 “MASK”。和 BERT 不同,“MASK” 不会纳入表征的地址向量 k \mathbf{k} k 以及内容向量 v \mathbf{v} v 的计算,“MASK” 自始至终只充当了查询向量 q \mathbf{q} q 的角色,因此所有词的表征中都不会拿到 “MASK” 的信息。这也杜绝了 “MASK” 的引入带来的预训练-微调差异(Pretrain-Finetune Discrepancy) – 这个改动也可以直接应用到 BERT 上面。
在下图中记 “MASK” 对应的词向量为 G,X2 - X4 为各自的词向量,G1, H1 - H4 为各自的表征。图中省略了位置编码
p
\mathbf{p}
p。
上面只是讨论最简单的情况 – 即一句话只产生一个样本。但我们还希望保证训练效率 – 我们想和自回归语言模型一样,只进行一次整句的表征计算便可以获得所有样本的语境表征。这时所有词的表征就必须同时计算,此时便有标签泄露带来的矛盾:对于某个需要预测的目标词,我们既需要得到包含它信息以及位置的表征 h \mathbf{h} h (用来进一步计算其他词的表征),又需要得到不包含它信息,只包含它位置的表征 g \mathbf{g} g (用来做语境的表征)。
一个很自然的想法就是同时计算两套表征,这便是 XLNet 提出的双通道自注意力(Two Stream Self-Attention),同时计算内容表征通道(Content Stream) h \mathbf{h} h 和语境表征通道(Query Stream) g \mathbf{g} g。注意这里采用的是意译而不是直译,请读者谅解。
假设我们要计算第 1 个词在第 l l l 层的语境表征 g 1 l \mathbf{g}_1^l g1l 和内容表征 h 1 l \mathbf{h}_1^l h1l,我们只关注注意力算子查询向量 Q Q Q、地址向量 K K K 以及内容向量 V V V 的来源:
g 1 l = Attention ( Q ← g 1 l − 1 , K V ← h j ≠ 1 l − 1 ) \mathbf{g}_1^l = \textrm{Attention}(Q\leftarrow \mathbf{g}^{l-1}_1, KV\leftarrow \mathbf{h}_{j\neq1}^{l-1}) g1l=Attention(Q←g1l−1,KV←hj̸=1l−1)
h 1 l = Attention ( Q ← h 1 l − 1 , K V ← h : l − 1 ) \mathbf{h}_1^l = \textrm{Attention}(Q\leftarrow \mathbf{h}^{l-1}_1, KV\leftarrow \mathbf{h}_:^{l-1}) h1l=Attention(Q←h1l−1,KV←h:l−1)
计算
g
1
l
\mathbf{g}_1^l
g1l 时用到了
h
j
≠
1
l
−
1
\mathbf{h}_{j\neq1}^{l-1}
hj̸=1l−1,表示第
l
−
1
l-1
l−1 层除了第 1 个词外所有词的表征,这是为了保证标签不泄露;计算
h
1
l
\mathbf{h}_1^l
h1l 时用到了
h
:
l
−
1
\mathbf{h}_:^{l-1}
h:l−1,表示第
l
−
1
l-1
l−1 层所有词的表征,这和标准的 Transformer 计算表征的过程一致。
但上述做法在堆叠多层自注意算子时仍然会带来标签泄露。
虽然计算 g 1 l \mathbf{g}_1^l g1l 时我们已经采取措施防止 h 1 l − 1 \mathbf{h}_{1}^{l-1} h1l−1 的信息泄露到 g 1 l \mathbf{g}_1^l g1l 中,但是考虑两层自注意力算子的计算:
g 1 l = Attention ( Q ← g 1 l − 1 , K V ← h j ≠ 1 l − 1 ) \mathbf{g}_1^l = \textrm{Attention}(Q\leftarrow \mathbf{g}^{l-1}_1, KV\leftarrow \mathbf{h}_{j\neq1}^{l-1}) g1l=Attention(Q←g1l−1,KV←hj̸=1l−1)
h j l − 1 = Attention ( Q ← h j l − 2 , K V ← h : l − 2 ) = Attention ( Q ← h j l − 2 , K V ← [ h j ≠ 1 l − 2 , h 1 l − 2 ] ) \mathbf{h}_j^{l-1} = \textrm{Attention}(Q\leftarrow \mathbf{h}^{l-2}_j, KV\leftarrow \mathbf{h}_{:}^{l-2}) =\textrm{Attention}(Q\leftarrow \mathbf{h}^{l-2}_j, KV\leftarrow [\mathbf{h}_{j\neq1}^{l-2},\mathbf{h}_{1}^{l-2} ]) hjl−1=Attention(Q←hjl−2,KV←h:l−2)=Attention(Q←hjl−2,KV←[hj̸=1l−2,h1l−2])
我们看到第 l − 2 l-2 l−2 层第 1 个词的表征 h 1 l − 2 \mathbf{h}_{1}^{l-2} h1l−2 会通过第 l − 1 l-1 l−1 层的所有表征 h j l − 1 \mathbf{h}_j^{l-1} hjl−1 泄露给 g 1 l \mathbf{g}_1^l g1l。
和将 Transformer 应用到自回归语言模型的情况类似,我们还需要对每层的注意力使用注意力掩码(Attention Mask),根据选定的分解排列 z z z,将不合理的注意力权重置零。我们记 z t z_t zt 为分解排列中的第 t t t 个词,那我们在词 z t z_t zt 的表征时, g t l \mathbf{g}_t^l gtl 和 h t l \mathbf{h}_t^l htl 分别只能看到排列中前 t − 1 t-1 t−1 个词 z 1 : t − 1 z_{1:t-1} z1:t−1 和前 t t t 个词 z 1 : t z_{1:t} z1:t,即
g z t l = Attention ( Q ← g z t l − 1 , K V ← h z 1 : t − 1 l − 1 ) \mathbf{g}_{z_t}^l = \textrm{Attention}(Q\leftarrow \mathbf{g}^{l-1}_{z_t}, KV\leftarrow \mathbf{h}_{z_{1:t-1}}^{l-1}) gztl=Attention(Q←gztl−1,KV←hz1:t−1l−1)
h z t l = Attention ( Q ← h z t l − 1 , K V ← h z 1 : t l − 1 ) \mathbf{h}_{z_t}^l = \textrm{Attention}(Q\leftarrow \mathbf{h}^{l-1}_{z_t}, KV\leftarrow \mathbf{h}_{z_{1:t}}^{l-1}) hztl=Attention(Q←hztl−1,KV←hz1:tl−1)
在如此做完注意力掩码后,所有 g z t l \mathbf{g}_{z_t}^l gztl 便可以直接用来预测词 z t z_t zt,而不会有标签泄露的问题。
这里我们也可以看到,在具体实现效率的限制下,想要获得多样的语境并防止标签泄露,我们只能依据乱序语言模型的定义去使用注意力掩码。这也体现了 XLNet 设计的精巧性。
10. XLNet 的重要元素:Transformer-XL
上面已经提到,和循环神经网络不同,Transformer 是同时计算语段内所有词的表征的。受限于系统内存大小,Transformer 输入的序列长度会有一个上限。通常我们会将过长的序列切成固定长度为 N N N 的片段,再依次输入Transformer 计算表征。所以 Transformer 的构造虽然降低了长程依赖的学习难度,但其最长只能建模长度为 N N N 的依赖。
为了在内存的限制下让 Transformer 学到更长的依赖,Transformer-XL 借鉴了 TBPTT(Truncated Back-Propagation Through Time) 的思路,将上一个片段 s t − 1 s_{t-1} st−1 计算出来的表征缓存在内存里,加入到当前片段 s t s_t st 的表征计算中。
如上图所示,由于计算第 l l l 层的表征时,使用的第 l − 1 l-1 l−1 层的表征同时来自于片段 s t s_t st 和 s t − 1 s_{t-1} st−1,所以每增加一层,模型建模的依赖关系长度就能增加 N N N。在上图中,Transformer-XL 建模的最长依赖关系为 3*2=6。
但这又会引入新的问题。Transformer 的位置编码(Position eEmbedding)是绝对位置编码(Absolute Position Embedding),即每个片段内,各个位置都有其独立的一个位置编码向量。所以片段 s t s_t st 第一个词和片段 s t − 1 s_{t-1} st−1 第一个词共享同样的位置编码 – 这会带来歧义。
Transformer-XL 引入了更加优雅的相对位置编码(Relative Position Embedding)。
因为位置编码只在自注意力算子中起作用,我们将 Transformer 的自注意力权重的计算拆解成:
a i , j a b s = q i ⊤ k j = x i ⊤ W q ⊤ W k x j + x i ⊤ W q ⊤ W k p j + p i ⊤ W q ⊤ W k x j + p i ⊤ W q ⊤ W k p j a_{i, j}^{\mathrm{abs}}=\mathbf{q}_{i}^{\top} \mathbf{k}_{j}=\mathbf{x}_i^{\top} \mathbf{W}_{q}^{\top} \mathbf{W}_{k} \mathbf{x}_j+ \mathbf{x}_i^{\top} \mathbf{W}_{q}^{\top} \mathbf{W}_{k} \mathbf{p}_j+\mathbf{p}_i^{\top} \mathbf{W}_{q}^{\top} \mathbf{W}_{k} \mathbf{x}_{j}+\mathbf{p}_{i}^{\top} \mathbf{W}_{q}^{\top} \mathbf{W}_{k} \mathbf{p}_{j} ai,jabs=qi⊤kj=xi⊤Wq⊤Wkxj+xi⊤Wq⊤Wkpj+pi⊤Wq⊤Wkxj+pi⊤Wq⊤Wkpj
我们可以将其中的绝对位置编码 p j \mathbf{p}_j pj 的计算替换成相对位置编码 r i − j r_{i-j} ri−j,把 p i \mathbf{p}_i pi 替换成一个固定的向量(认为位置 i i i 是相对位置的原点)。这样便得到相对位置编码下的注意力权重:
a i , j r e l = q i ⊤ k j = x i ⊤ W q ⊤ W k x j + x i ⊤ W q ⊤ W k r i − j + p ⊤ W q ⊤ W k x j + p ⊤ W q ⊤ W k r i − j a_{i, j}^{\mathrm{rel}}=\mathbf{q}_{i}^{\top} \mathbf{k}_{j}=\mathbf{x}_i^{\top} \mathbf{W}_{q}^{\top} \mathbf{W}_{k} \mathbf{x}_j+ \mathbf{x}_i^{\top} \mathbf{W}_{q}^{\top} \mathbf{W}_{k} \mathbf{r}_{i-j}+\mathbf{p}^{\top} \mathbf{W}_{q}^{\top} \mathbf{W}_{k} \mathbf{x}_{j}+\mathbf{p}^{\top} \mathbf{W}_{q}^{\top} \mathbf{W}_{k} \mathbf{r}_{i-j} ai,jrel=qi⊤kj=xi⊤Wq⊤Wkxj+xi⊤Wq⊤Wkri−j+p⊤Wq⊤Wkxj+p⊤Wq⊤Wkri−j
Transformer-XL 的实际实现方式与上式有所不同,但思想是类似的。
相对位置编码解决了不同片段间位置编码的歧义性。通过这种拆解,我们可以进一步将相对位置编码从词的表征中抽离,只在计算注意力权重的时候加入。这可以解决 Transformer 随着层数加深,输入的位置编码信息被过多的计算抹去的问题。Transformer-XL 在 XLNet 中的应用使得 XLNet 可以建模更长的依赖关系。
11. XLNet 的模型改进增益
文章最后的消融分析很好地证明了乱序语言模型和 Transformer-XL 主干网络带来的提升。这部分实验采用和 BERT 一致的训练数据。以 BERT 为基础,将 BERT 的主干网络从 Transformer 换成 Transformer-XL 后,在需要建模较长上下文的阅读理解任务 RACE 和 SQuAD2.0 均有比较明显地提升(对比1&2行)。而在此基础上加上乱序语言模型后,在所有任务上都有不同程度的提升(对比2&3行)。
12. 如何评价 XLNet
自词向量到如今以 XLNet 为代表的预训练语言模型,他们的主要区别在于对语境的不同粒度的建模:
模型 | 语境 | 训练任务 |
---|---|---|
Skip-gram, Glove | 与目标词在同一个滑动窗口下的词 | 矩阵分解[2] |
ELMo, GPT, GPT2 | 目标词前/后一定长度的语段 | 自回归语言模型 |
BERT, ERNIE | 目标词前后一定长度的语段 | 去噪自编码模型 |
XLNet | 目标词前后一定长度的语段的采样 | 乱序语言模型 |
XLNet 的成功来自于三点:
- 分布式语义假设的有效性,即我们确实可以从语料的统计规律中习得常识及语言的结构。
- 对语境更加精细的建模:从"单向"语境到"双向"语境,从"短程"依赖到"长程"依赖,XLNet 是目前对语境建模最精细的模型。
- 在模型容量足够大时,数据量的对数和性能提升在一定范围内接近正比 [3] [4]:XLNet 使用的预训练数据量可能是公开模型里面最大的。
可以预见的是资源丰富的大厂可以闭着眼睛继续顺着第三点往前走,或许还能造出些大新闻出来,这也是深度学习给的承诺。这些大新闻的存在也渐渐堵住调参式的工作的未来,迫使研究者去思考更加底层,更加深刻的问题。
对语境的更精细建模自然是继续发展的道路,以语言模型为代表的预训练任务和下游任务之间的关系也亟待探讨。
退后一步讲,分布式语义假设的局限性在哪里?根据符号关联假设(Symbol Interdependency Hypothesis)[5],虽然语境的统计信息可以构建出符号之间的关系,从而确定其相对语义。但我们仍需要确定语言符号与现实世界的关系(Language Grounding),让我们的 AI 系统知道,"红色"对应的是红色,"天空"对应的是天空,"国家"对应的是国家。这种对应信息是通过构建知识库,还是通过和视觉、语音系统的联合建模获得?解决这一问题可能是下一大新闻的来源,也能将我们往 AI 推进一大步。
基于分布式语义假设的预训练同时受制于报道偏差(Reporting Bias)[6]:不存在语料里的表达可能是真知识,而存在语料里面的表达也可能是假知识,更不用提普遍存在的模型偏见(Bias)了。我们不能因为一百个人说了"世上存在独角兽"就认为其为真,也不能因为只有一个人说了"地球绕着太阳转"便把它当做无益的噪声丢弃掉。
为了达到足够大的模型容量,我们真的需要这么大的计算量吗?已经有工作证明训练充分的 Transformer 里面存在很多重复冗余的模块[6]。除了把网络加深加宽外,我们还有什么办法去增大模型容量的同时,保持一定的计算量?
参考文献
[1] Firth, J. R. (1957). Papers in linguistics 1934–1951. London: Oxford University Press.
[2] Levy O, Goldberg Y. Neural word embedding as implicit matrix factorization[C]//Advances in neural information processing systems. 2014: 2177-2185.
[3] Mahajan D, Girshick R, Ramanathan V, et al. Exploring the limits of weakly supervised pretraining[C]//Proceedings of the European Conference on Computer Vision (ECCV). 2018: 181-196.
[4] Hestness J, Narang S, Ardalani N, et al. Deep learning scaling is predictable, empirically[J]. arXiv preprint arXiv:1712.00409, 2017.
[5] Louwerse M M. Knowing the meaning of a word by the linguistic and perceptual company it keeps[J]. Topics in cognitive science, 2018, 10(3): 573-589.
[6] Gordon J, Van Durme B. Reporting bias and knowledge acquisition[C]//Proceedings of the 2013 workshop on Automated knowledge base construction. ACM, 2013: 25-30.
[7] Michel P, Levy O, Neubig G. Are Sixteen Heads Really Better than One?[J]. arXiv preprint arXiv:1905.10650, 2019.