《Recurrent Chunking Mechanisms for Long-Text Machine Reading Comprehension》ACL2020论文阅读

目录

论文认为的问题:

主要解决办法:

BERT的缺陷:

模型架构:

基于策略的强化学习(policy-based RL):

对目标函数求导

模型的loss:

测试阶段:

结果:

补充:


机构为:伊利诺伊大学厄巴纳-香槟分校、微软AI、腾讯AI。

论文认为的问题:

认为当前输入文本的长度是固定的(bert最大为512),而且预测答案是每段文本独立进行预测,获取的文本信息只能局限于本段。故提出了Recurrent Chunking Mechanisms。

主要解决办法:

提出通过增强学习让模型学习决定输入每段的长度。同时通过循环机制让每段文本流动,让机器做决定的时候可以参考除本段之外的信息。循环机制实现可使用gated recurrence和LSTM recurrence。通过上述方法可以在CoQA,QuAC以及TriviaQA数据集上取得较好的效果。

BERT的缺陷:

固定分割,Bert源码举例:

我们来一步一步的计算切分过程:

  • 首先start_offset=0,length=700>max_tokens_for_doc=500,所以第一次的切分就是[0-500],由于length=500>doc_stride=128,所以start_offset=128
  • 第二次start_offset=128,length=700-128=572>max_tokens_for_doc=500,所以第二次的切分就是[128-628],由于length=500>doc_stride=128,所以start_offset这时等于256
  • 第三次start_offset=256,length=700-256=444<max_tokens_for_doc=500,所以第三次的切分就是[256-700]
    因此第一次切分的文章长度为500,第二次切分的文章长度为500,第三次剩下的文章长度为444

 切分后的每一篇segment与问题构成一个样本作为BERT的输入,比如在文章长度为700,doc_stride为128的情况下,会切分出来3个segment,于是也就和同一个问题组成了三个example,需要注意的是如果某个segment不包含有答案,那么这个segment是不用的。

所以出现问题:1.以固定长度分割文章,那么就可能导致某些分割后的文章所包含的答案的上下文不充分,也就是说答案在分割后的位置靠近边缘。

上图指出当答案的中心词位置与切分文章的中心词位置之间的距离影响着模型预测答案位置的准确率。

论文提出的第二个问题就是当文章分段送入bert中去,那么模型在阅读了第一个分割片段后的语义信息,应该是是对第二段阅读提取答案有所帮助。但是之前是忽略了这个问题。

首先bert的输入形式如下:

我们重点关注CLS,bert原文中对CLS的描述为:

The final hidden state corresponding to this token is used as the aggregate sequence representation for classification tasks.

也就是说CLS这个token的最终的hidden state聚集了整个sequence的表示,这篇论文的模型的循环机制的原理就是:

将CLS的hidden state通过LSTM/Gate达到循环的目的,具体做法就是将前一个segment的LSTM/Gate的输出作为当前LSTM的hidden state \ \ h_{t-1},当前segment的CLS的表示作为LSTM的输入x_t,然后当前的LSTM的输出 h_t 作为下一时刻的segment的hidden state。

模型架构:

 

在论文源代码中,train_model、val_model、test_model都有这句 for t in range(args.max_read_times) 通过这行代码,我们了解到模型是固定了分割次数的,也就是说模型会在一篇document上分割max_read_times次数。

同样在这三个model中都有下面这行代码:

利用上述代码,实现循环机制。

因为步幅actions的选择是连续的决策过程,通过强化学习来训练分块策略是很自然的。

因此难点在于如何通过强化学习来解决分割document的问题

基于策略的强化学习(policy-based RL):

RL的思想是:环境environment输入给智能体agent一个状态s,agent根据策略 \pi_\theta 做出一个行为a,然后得到环境给它的奖励r的同时环境转移到了下一个状态。\theta为模型的参数。如下图所示。

其中环境与agent交互,环境给agent的是状态和奖励,agent做出的行为会改变环境的状态。在深度学习中应用强化学习时,策略policy就是神经网络NN。

好的接下来我们定义目标函数:
我们从agent与环境交互所产生的轨迹的角度来定义目标函数:

参照上图,分别解释每一行公式:
首先,给定一个初始状态 s_1,agent会在s_1下与环境进行交互,产生一条轨迹ττ,我们希望的是在这条轨迹τ上的所有奖励 r_t^\tau 的累计值最大。
那么目标函数自然就是期望所有的轨迹上的累计奖励都是最大。

也就是说我们希望在最优的参数\theta^\ast下,根据策略\pi_{\theta^\ast},我们任意得到的轨迹τ上的累计奖励值都是最大的。所以接下来的问题就是如何优化策略的参数\theta

对目标函数求导

首先我们重新写出来目标函数:

第一行我们已经知道,它的含义就是对策略下 \pi_\theta 的任意一条轨迹上的累计奖励值的期望。

第二行公式就是将期望用公式符号表达出来,也就是在策略 \pi_\theta 下产生的轨迹τ的概率乘以这条轨迹τ的累计奖励值。

但是轨迹的个数是不确定的,因为随便拿一个初始状态,都会产生很多条轨迹。因此用采样近似的方式。取出来N条轨迹,我们的目标是这N条轨迹上的累计奖励值求和后的值最大。

而给定一个初始状态,在参数\theta下产生一条轨迹的概率为:

这里的第一行公式就是指一条轨迹的产生的概率为:初始状态s_1的概率乘以在s_1​状态下根据\pi_\theta采取行为a_1的概率乘以在s_1​状态下采取了行为a_1后得到的奖励r_1以及环境转移为状态s_2的概率,以此类推。

第二行是对概率取log,第三行对\theta求导。

注意到p(s_1^\tau)是初始状态的概率,p(s_{t+1}^\tau,r_t^\tau|a_t^\tau,s_t^\tau)是由环境给出的,因此这两项与参数 \theta无关,所以对参数的导数为0。

我们重新整理一下:

在已知上面的公式后,我们对目标函数求导:

第一行公式就是对目标函数求导数,奖励是环境给的,与策略无关,因此只需要计算p(\tau|\theta)的导数。

第二行的目的是为了构造出对log概率求导,因为dlogf(x)=\frac{df(x)}{f(x)},于是也就有了第三行公式

因此我们得到最后一行公式。

最后一行公式有两个求和符号,他们的意义是,对N条轨迹的每一条轨迹上的累计奖励求和取平均,而我们知道轨迹上的奖励是在某个状态s下采取行为a获得的。因此上述公式也就等价于对数据集中的所有可能的(状态,行为)对,所获得的奖励求和取平均。

我们的目的就是在参数\theta^\ast下,数据集中所有可能的(状态,行为)对,所获得的奖励累计是最大的。

最终我们将J(\theta)改写为:

即使不看上述推导过程,也没关系,我们只要知道P(a|s;\theta)R(s,a)是什么就可以训练模型了。这里的P(a|s;\theta)就是神经网络的输出,这个输出是指在行为空间上的概率分布。

所以我们要清楚状态、行为、奖励是什么: 

  • 状态是模型的输入,在本文中当然就是切割后的某一段文本片段segment
  • 行为是模型的输出,本文的目的是让模型学会自己分割文章,那么输出的自然是下一次切分的滑动步长,行为空间定义为{-32,64,128,256,512} (这是论文中对CoQA数据集设定的action space)。
  • 奖励是要预先定义好的,见论文的公式11

我们对照着论文的公式11和公式12:

{\widetilde{v}}_cv_c{\widetilde{v}}_{c-1}通过LSTM得到的,其中v_c是CLS的向量表示,{\widetilde{v}}_{c-1}是上一次的segmentLSTM的输出。

看公式就行了:

q_c是模型预测当前segment包含答案的概率,它是由前一个segment的循环状态和当前segment的CLS的表示通过LSTM得到的。

r_c是模型从当前的segment提取出答案位置的概率,R(s^\prime,a^\prime)是未来的累计奖励,关于R(s^\prime,a^\prime)我们后面参照论文源码来解释。

这里需要知道的是当前的segment包含有答案时,如果模型预测的当前segment包含答案的概率较高,也就是q_c值比较高,那么当前状态下采取行为a的奖励主要是由 q_c\ast r_c决定的。

而如果当前的segment没有包含答案,那么r_c=0,而如果模型预测当前segment包含答案的概率较小,也就是q_c​值比较小,那么1-q_c比较大,所以当前状态采取行为a的奖励主要由未来的累计奖励决定。但是在r_c=0的情况下,模型预测当前segment包含答案的概率较大,那么1-q_c比较小,显然此时模型获得的奖励就比较少。

通俗的说就是,若当前的segment包含答案,模型预测当前的segment确实包含答案,而且还能正确的提取出答案位置,那么此时给模型的奖励主要是q_c\ast r_c

希望模型在下次见到同样的segment时,增加p(a|s;\theta)的概率。其他的情况下是类似的。

模型的loss:

模型的loss有三个,第一个是答案提取器(Answer Extractor)的loss,它的值是模型预测的答案位置与真实位置的交叉熵:

BERT产生第c个segment中的第i个token产生的vector representation h_{c,i} 。

Answer Extractor计算可能答案区间开头部分的概率。同理p_{c,i}^{end}。其中有两个求和符号,第一个求和符号是对整个序列上每一个位置的单词的预测概率,第二个求和符号是对所有的分割次数求和。

第二个是L_{CS},它代表的是切分段落计分器(Chunking Scorer)的损失值,也就是模型在每一次切分的segment下,预测该segment包含有答案的概率与实际包含答案的交叉熵,仍然是对所有的切分次数求和。

 

前两个的损失函数都是交叉熵损失函数,属于监督学习,有明确的标签,但是第三个损失值:

L_{CP}是强化学习的损失函数,没有标签,只有奖励。

不过根据前面推导,我们已经推导出该损失函数的导数为:

所以现在我们只需要计算出logP(a|s;\theta)R(s,a) 就可以了

看源代码:(因为是组会上分享了,所以博客没有记录)

测试阶段:

不需要那么复杂,因为不必计算loss了,我们只需要根据模型在当前state下采取的action a 得到的概率值P(a|s),在训练阶段我们是采样的方式,也就是每一个行为都有可能被采样出来,只是概率大的更多次的会被采样出来。而测试阶段采取贪心策略,只选取概率最大的那个行为作为输出。

定义:

作为当前的segment预测答案位置的分数

然后根据当前状态下所作出的行为a^\ast,我们会得到一个新的状态s_{t+1},比如之前的a^\ast=32,那么当前的状态就是上一次的segment向右移动32个单词长度得到的。然后这个新的状态下,仍然得到:

总计会有max_read_times个,我们取出来其中值最大的作为模型在切分了一篇文章max_read_times后所作出的综合预测。

结果

根据此表我们可以看出来,当最大长度max_seq_len限制为512的时候,其实这种循环切分的机制并没有比BERT-large有什么明显的效果,主要原因是,CoQA和QuAC数据集的文章大部分不是特别的长

根据上图我们了解到,CoQA和QuAC的训练集合的文章长度平均为352和516个单词,显然很多文章并不需要切分。因此Recurrent chunking机制发挥不了什么作用,但是随着最大长度的减小,比如,当最大长度限制为192的时候,也就是说当一篇文章会被切分成很多长度不超过192的segment的时候,循环切分的方式明显好于baseline,因为baseline的做法是将切分的各个segment独立的预测答案,而且也不考虑answer在segment中的位置,前面已经分析了,那些answer位置在segment位置中心的答案容易预测出来,而处于segment边缘的答案由于缺少足够的上下文,是不容易准确的预测出来的。

下表是在TriviaQA数据集上的实验结果:

因为TriviaQA数据集比较长,max_seq_len固定为512的情况下,显然循环切分机制效果要好于baseline的,说明循环切分机制适用于处理长文本。

上图指的是BERT-large这个基线模型和RCM这个循环切分机制在切分文本时,切分的文本包含完整答案在切分的所有文本中的比例,也叫Hit rate,命中率。显然循环切分机制切分的文章中有大部分都是包含完整答案的。而baseline这种按照固定滑动步数切分文章的做法,有相当一部分的文章是不包含有答案的。

补充:

在循环切分机制当中,对于不包含有答案的segment,仍然会保留下来作为样本参与训练,因为整个切分过程是在一篇document上连续切分的,中间断了显然是不行的,而且我们需要让模型学会避免切分出这种不包含answer的segment.具体的做法是,对于不包含答案的segment,和question构成一个example输入到BERT当中,BERT的CLS的表示和上一时刻的segment的LSTM的输出一起输入到LSTM当中,得到{\widetilde{v}}_c,然后{\widetilde{v}}_c输入到激活函数sigmiod,输出得到q_c,这个q_c代表的就是模型预测当前segment包含答案的概率,然后在这个不包含answer的segment下,r_c=0。给模型的奖励是R(s,a)=q_c\ast r_c+(1-qc)*R(s',a'),显然模型预测的q_c越小,获得的奖励越多。

红色字体代表的是answer,第一次切分时,固定到max_seq_length为止,也就是图片中的黄色部分,第二次切分时,向右滑动128个单词,滑动有点多,答案到右边界,也就是蓝色部分chunk 2,第三次切分下模型向左移动了16个单词,目的是使得第三个chunk包含答案更多的上下文,也就是图片中的橘色部分,显然这种切分方式比固定切分要好,而且固定的切分方式是不会向左移动的。

 

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值