這是今年清華大學及阿里巴巴發表在NIPS 2020上的一篇論文《CogLTX: Applying BERT to Long Texts》,介紹瞭如何優雅地使用bert處理長文字。作者同時開源了不同NLP任務下使用COGLTX的程式碼:

論文地址:NIPS20-Ding-et-al-CogLTX。pdf

程式碼開源:Sleepychord/CogLTX

bert在長文字處理一般分為三種方法

[1]

·

截斷法;

·

Pooling法;

·

壓縮法。

該論文就是壓縮法的一種,是三種方法中最好的。我們在科研和工作中都會遇到該問題,例如我最近關注的一個文字分類比賽:

面向資料安全治理的資料內容智慧發現與分級分類 競賽 - DataFountain。

其文字資料長度就都在3000左右,無法將其完整輸入bert,使用COGLTX就可以很好地處理該問題,那麼就一起來看看該論文具體是怎麼做的吧。

1.背景

基於以下情形:

·

bert作為目前最優秀的PLM,不用是不可能的;

·

長文字資料普遍存在,且文字中包含的資訊非常分散,難以使用滑動視窗

[2]

截斷。

而由於bert消耗計算資源和時間隨著token的長度是平方級別增長的,所以其無法處理太長的token,目前最長只支援512個token,token過長也很容易會記憶體溢位,所以在使用bert處理長文字時需要設計巧妙的方法來解決這個問題。

BERT長文字處理-COGLTX【附程式碼】

2.提出模型

COGLTX模型在三類NLP任務中的結構如下:

BERT長文字處理-COGLTX【附程式碼】

BERT長文字處理-COGLTX【附程式碼】

首先假設:存在短文字

z^{+}

可以完全表達原長文字

x^{+}

的語義:

reasoner(x^{+}) \approx reasoner(z^{+}) \\ \large

那麼令

z^{+}

代替

x^{+}

輸入原來的模型即可,那麼怎麼找到這個

z^{+}

1、使用動態規劃演算法將長文字

x^{+}

劃分為文字塊集合

[x_{0}...x_{T-1}]

2、使用

MemRecall

對原長句中的子句進行打分,MemRecall結構如圖,而表現如下式:

z^{+}=[[CLS]\; Q \;[SEP]\;z_{0}\;SEP\;[SEP]...z_{n-1}]\\

judge(z^{+})\;=\;sifmoid(MLP(BERT(z^{+})))\in (0,1)^{len(z^{+})}\\

從而選擇出分數最高的子句組成

z^{+}

再進行訓練,這樣一來的話,COGLTX相當於使用了了兩個bert,MemRecall中bert就是負責打分,另一個bert執行原本的NLP任務。

可以發現剛才找到

z^{+}

例子將問題Q放在了初始化

z^{+}

的開頭,但是並不是每個NLP任務都可以這麼做,分類的時候就沒有類似Q的監督,這時候COGLTX採用的策略是將每個子句從原句中移除判斷其是否是必不可少的(t是一個閾值):

loss_{reasoner}(z-z_{i})-loss_{reasoner}(z)>t\;\;necessity\\

loss_{reasoner}([z\;z_{i}])-loss_{reasoner}(z)\approx t\;\;sufficiency\\

作者透過設計不同任務下的MemRecall實現了在長文字中使用bert並透過實驗證明了方法的有效性。

3.實驗

BERT長文字處理-COGLTX【附程式碼】

BERT長文字處理-COGLTX【附程式碼】

透過多維度地對比,證明了本文提出演算法的有效性。

參考

^https://zhuanlan。zhihu。com/p/88944564

^

Z。 Wang, P。 Ng, X。 Ma, R。 Nallapati, and B。 Xiang。 Multi-passage bert: A globally normalized bert model for open-domain question answering。 arXiv preprint arXiv:1908。08167, 2019。