点击上方“AI公园”,关注公众号,选择加“星标“或“置顶”web
做者:Xu LIANG微信
编译:ronghuaiyang
架构
理解XLNet中的双流自注意力机制。编辑器
在我以前的文章什么是XLNet,它为何比BERT效果好?中,我主要讨论了XLNet (AR语言模型)和BERT (AE语言模型)之间的区别以及重排列语言建模。
函数
我相信对XLNet有一个直观的理解远比实现细节重要,因此我只解释了重排列语言建模,而没有提到另外一个重要的部分,双流自注意力架构。但正如陈家明在评论中提到的,双流自注意力是XLNet论文的另外一个亮点,因此我写这篇文章是为了尽量清楚地解释双流自注意力。性能
内容结构以下。学习
-
重排列语言建模的快速回顾 -
重排列带来了什么问题? -
BERT有这样的问题吗? -
XLNet如何解决这个问题? -
注意力mask: XLNet如何实现重排列?
重排列建模的快速回顾
特殊的术语:编码
-
AR语言模型: 自回归语言建模 -
AE语言模型: 自动编码器语言建模
为了使这篇文章更加独立,我在这里作一个简短的总结:什么是XLNet,为何它的性能优于BERT。url
XLNet提出使用重排列语言建模,使AR语言模型学习双向上下文。这样能够避免AE语言模型中MASK方法带来的弊端。spa
重排列方法是获取一个序列的重排列,并使用以前的t-1
个tokens做为上下文来预测第t个位置的token。例如,咱们有一个句子[x1, x2, x3, x4]
,而x3
是咱们要预测的第t个位置的token。首先,咱们获得句子的排列。
[('x1', 'x2', 'x3', 'x4'),
('x1', 'x2', 'x4', 'x3'),
('x1', 'x3', 'x2', 'x4'),
('x1', 'x3', 'x4', 'x2'),
('x1', 'x4', 'x2', 'x3'),
('x1', 'x4', 'x3', 'x2'),
('x2', 'x1', 'x3', 'x4'),
('x2', 'x1', 'x4', 'x3'),
('x2', 'x3', 'x1', 'x4'),
('x2', 'x3', 'x4', 'x1'),
('x2', 'x4', 'x1', 'x3'),
('x2', 'x4', 'x3', 'x1'),
('x3', 'x1', 'x2', 'x4'),
('x3', 'x1', 'x4', 'x2'),
('x3', 'x2', 'x1', 'x4'),
('x3', 'x2', 'x4', 'x1'),
('x3', 'x4', 'x1', 'x2'),
('x3', 'x4', 'x2', 'x1'),
('x4', 'x1', 'x2', 'x3'),
('x4', 'x1', 'x3', 'x2'),
('x4', 'x2', 'x1', 'x3'),
('x4', 'x2', 'x3', 'x1'),
('x4', 'x3', 'x1', 'x2'),
('x4', 'x3', 'x2', 'x1')]
而后选取一些样本做为训练数据。(本文从排列中随机抽取样本)
('x1', 'x2', 'x4', 'x3'),
('x1', 'x4', 'x3', 'x2'),
('x2', 'x3', 'x4', 'x1'),
('x4', 'x2', 'x3', 'x1'),
('x3', 'x2', 'x4', 'x1'),
咱们能够看到每一个token都有机会出如今x3以前。所以,AR模型能够从这些上下文tokens中学习双向信息。若是你仍然不清楚重排列,你能够阅读前面的文章。
重排列带来了什么问题?
这种重排列可使AR模型从两个方向看到上下文,但也带来了原transformer 没法解决的问题.
重排列语言建模目标:
-
Z: 一种分解顺序 -
p_θ: 似然函数 -
x_zt: 分解顺序中的第t个token -
x_z<t: 第t个token以前的全部tokens
这是重排列语言建模的目标函数,即以t-1个tokens为上下文,预测第t个token。
有两个标准Transformer不能知足的要求:
-
为了预测token x_t,模型应该只看到x_t的位置,而不是x_t的content(我将在下一节解释什么是content) -
为了预测token x_t,模型应该将x_t以前的全部token编码为content
特别是第一个要求,transformer将位置编码合并到token嵌入中。所以,它不能将位置信息与token嵌入分离开来。
BERT有这样的问题吗?
BERT是一个AE语言模型,它不像AR语言模型那样须要单独的位置信息。与XLNet须要位置信息来预测第t个token不一样,BERT使用[MASK]来表示要预测哪一个token(咱们能够认为[MASK]只是一个占位符)。例如,若是BERT使用x2, x1, x4来预测x3,那么x2, x1, x4的嵌入包含了位置信息和其余与[MASK]相关的信息。所以,该模型颇有可能预测[MASK]是x3。
在这里我将对信息作更详细的说明。BERT embedded (BERT所学的信息)包含两种信息:位置信息和内容信息(为简单起见,我将其分为两部分)。
位置信息很容易理解,由于它告诉模型当前token的位置。内容信息(语义和语法)包含当前标记的“意义”。一个直观的例子是kind — man + woman = queen
。
XLNet怎么解决这个问题?
XLNet提出了双流自注意力来解决这个问题。
顾名思义,它包含两种自注意力。一个是content stream attention,它是Transformer中的标准自注意力。另外一个是query stream attention。XLNet引入它来替换BERT中的[MASK] token。
例如,若是BERT想用上下文单词x1和x2的知识来预测x3,它可使用[MASK]来表示x3 token。[MASK]只是一个占位符。x1和x2的嵌入包含位置信息,帮助模型“知道”[MASK]的是x3。
XLNet的状况有所不一样。一个token x3将服务两种角色。当它被用做内容来预测其余标记时,咱们可使用内容表示(经过内容流注意力来学习)来表示x3。可是若是咱们想要预测x3,咱们应该只知道它的位置而不是它的内容。这就是为何XLNet使用查询表示(经过查询流注意力来学习)来保留x3以前的上下文信息,只保存x3的位置信息。
为了直观地理解双流自注意力,咱们能够认为XLNet用查询表示代替了BERT中的[MASK]。他们只是选择不一样的方法作同一件事。
注意力mask:XLNet如何实现重排列?
当我第一次读到这篇文章的时候,我不由对训练中重排列的实现细节产生了疑惑。若是大家感兴趣,我就简单讲一下。
在第一部分“重排排列语言建模的快速回顾”中,我给出了一个句子[x1, x2, x3, x4]
的排列示例,以下所示。
[('x1', 'x2', 'x3', 'x4'),
('x1', 'x2', 'x4', 'x3'),
('x1', 'x3', 'x2', 'x4'),
('x1', 'x3', 'x4', 'x2'),
('x1', 'x4', 'x2', 'x3'),
('x1', 'x4', 'x3', 'x2'),
('x2', 'x1', 'x3', 'x4'),
('x2', 'x1', 'x4', 'x3'),
('x2', 'x3', 'x1', 'x4'),
('x2', 'x3', 'x4', 'x1'),
('x2', 'x4', 'x1', 'x3'),
('x2', 'x4', 'x3', 'x1'),
('x3', 'x1', 'x2', 'x4'),
('x3', 'x1', 'x4', 'x2'),
('x3', 'x2', 'x1', 'x4'),
('x3', 'x2', 'x4', 'x1'),
('x3', 'x4', 'x1', 'x2'),
('x3', 'x4', 'x2', 'x1'),
('x4', 'x1', 'x2', 'x3'),
('x4', 'x1', 'x3', 'x2'),
('x4', 'x2', 'x1', 'x3'),
('x4', 'x2', 'x3', 'x1'),
('x4', 'x3', 'x1', 'x2'),
('x4', 'x3', 'x2', 'x1')]
咱们很容易误解,咱们须要得到一个句子的随机顺序并将其输入到模型中。但事实并不是如此。输入语句的顺序是[x1, x2, x3, x4]
,XLNet使用注意力掩码来重排列分解因子的顺序。
这个句子的原始顺序是[x1, x2, x3, x4]
。咱们随机获得一个分解的顺序为[x3, x2, x4, x1]
。
左上角是内容表示的计算。若是咱们想要预测x1的内容表示,咱们应该拥有全部4个token内容信息。KV = [h1, h2, h3, h4]
和Q = h1
。
左下角是查询表示的计算。若是咱们想要预测x1的查询表示,咱们不能看到x1自己的内容表示。KV = [h2, h3, h4]
,Q = g1
。
右下角是整个计算过程。我把它从头至尾解释了一遍。首先,h
和g
被初始化为e(xi)
和w
。在内容掩码和查询掩码以后,双流注意力将输出第一层输出h^(1)
和g^(1)
,而后计算第二层。
注意右边的内容掩码和查询掩码。它们都是矩阵。在内容mask中,第一行有4个红点。这意味着第一个token (x1)能够看到(注意到)全部其余tokens,包括它本身(x3->x2->x4->x1)。第二行有两个红点。这意味着第二个token (x2)能够看到(注意到)两个token(x3->x2)。等等。
内容掩码和查询掩码之间唯一的区别是,查询掩码中的对角元素为0,这意味着token不能看到它们本身。
让咱们总结一下。输入的句子只有一个顺序。可是咱们可使用不一样的注意力mask来实现不一样的分解顺序。
总结
在这篇文章中,我主要解释了XLNet面临的问题是什么,以及如何使用双流自注意力来解决它。我还提到了有关排列注意里mask的一些实现细节。对于结果的比较,你能够从XLNet team中找到最新的发布,它比论文的比较更加公平。

英文原文:https://towardsdatascience.com/what-is-two-stream-self-attention-in-xlnet-ebfe013a0cf3
请长按或扫描二维码关注本公众号
喜欢的话,请给我个好看吧!
本文分享自微信公众号 - AI公园(AI_Paradise)。
若有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一块儿分享。