计算机语言工具文

如何利用Bert处理长文本

2021-07-16  本文已影响0人  烛之文

1 前言

预训练模型Bert能处理最大序列长度为512,当面对长文本(文档级别)时候,通常是采用text truncation或者sliding window方式,让输入模型的序列长度符合预设值,但这种处理方式会导致丢失与任务相关的全局信息。如下图,在做QA任务中,与问题相关的答案在Bert处理的长度范围外,这样难以让模型回答正确。为了解决该问题,本次分享NeurIPS 2020年的一篇paperCogLTX: Applying BERT to Long Texts,作者来自清华与阿里团队。论文的核心思想是,模仿人的理解记忆力机制,使用Bert处理长文本,提出MemRecal机制,识别长文本中的关键句子,然后经过排序、抽取、融合,形成新的文本用于下游任务。本篇论文开放了源码,地址为https://github.com/Sleepychord/CogLTX

2 模型


上图为CogLTX面向三种不同任务的处理流程:
(1) 将输入的长文本x,通过动态的方式切成连续的短句子(x[0],....,x[n]);
(2) 通过MenRecall模块,从(x[0],....,x[n])中识别与任务相关的关键片段(key text),组成语块z
(3) 依据不同任务类型,将关键语块z组成满足任务需求的输入格式,然后输入BERT模型(文中称为:reasoner)进行下游任务处理;

看上图其实很好理解,跟正常用BERT处理流程是一致的,关键是部分是MenRecall,如何从long text中抽取与任务相关的key text,将key text代替long text作为输入,这便是本篇论文的核心

关于MenRecall,作者是基于这样的假设的:

上述公式的意思:长文本x^+输入任务模型与关键文本块z^+输入任务模型得到的效果是差不多的,是一致的;另一层面意思为长文本中是有很多跟任务不相关的句子,删掉也是不会影响任务处理效果的。这个假设是很合理的。

基于上述的假设,作者就设定了一个judge(z^+)模型,来判断z^+是否是关键语块;其判断计算方式如下:

具体操作是按照judge([z^+[SEP]x_i])的方式遍历x_i,若输出为1,就表明x_i与任务相关,是关键语句,将其加入z^+中,接着判断x_{i+1},依次下去,当len(z^+)超过输入BERT的最大长度时,可以作为终止判断的条件。

如此,就会引出下面的问题:通过judge(z^+)从长文本中抽取出关键语块,这是一个新的任务,那在训练该任务时,它的损失函数是什么?

针对上面的问题,文中设计两种损失函数方式,一种面向监督学习,一种面向无监督学习,如下:


公式(3),(4)显示将判断的语块与真实的语块做下交叉熵比较;公式(5),(6)表示减少或增加一个句子,看原任务损失值变化来判断该片段是否是关键语块。显然,这是个逐步迭代的过程。下图为MenRecall详细计算过程示意图。

3 Experiments

本文利用自己的方法在多个任务下进行实验,具体包括Reading comprehensionMulti-hop question answeringText classificationMulti-label classification,下面是部分任务的实验结果。

Reading comprehension results Text classification results Multi-label classification results

显示模型测试效果特别明显,每个任务下的数据集上都有近4%~5%的提升。也说明捕捉长文中更多有用的信息进行学习,是对任务肯定有利的。

4 结语

关于长文本的处理相关的paper很多,其共性做法都是要将长文本变成短文本来处理,而如何来处理,便产生了不同的想法。本人之前是采用KMeans聚类的方式来识别关键语块,但这个方式对具体做什么任务关系很大,因为在某些任务中很多句子是否是关键句并不明显,用向量表征的方式聚类,效果并不太好。看了本篇paper的思路,觉得值得借鉴试试,同时也就分享出来~

更多文章可关注笔者公众号:自然语言处理算法与实践

上一篇下一篇

猜你喜欢

热点阅读