【NLP應用之智慧司法】最強之GoogleBERT模型在智慧司法領域的實踐淺談

  • 2019 年 10 月 7 日
  • 筆記

閱讀大概需要12分鐘

跟隨小部落客,每天進步一丟丟
來自:實在智慧

知乎鏈接:https://zhuanlan.zhihu.com/p/54934304

碎片化利用時間推薦:

10月中旬,GoogleAI團隊新發布的BERT模型,在機器閱讀理解頂級水平測試SQuAD1.1中表現出驚人的成績:兩個衡量指標上超越人類,並且還在11種不同NLP測試中創出最佳成績,奠基新的NLP里程碑。後續,Google開源了該項目,並且公布了包括中文字向量預訓練模型等在大規模數據上預訓練過的通用模型。隨後,陸續有AI業界同仁嘗試在不同任務中應用BERT預訓練模型,其中有團隊在AI Challenger閱讀理解賽道中取得了最好成績。

開源項目公布之前,我們對BERT論文進行了學習和討論,並根據論文思想實現了簡化版、預訓練的TextCNN模型。在預訓練的中文BERT模型公布不久,作者寫了一個BERT中文預訓練模型的簡短教程,並將模型成功部署到我們正在推進的「AI賦能法律」相關係統。

最近,我們結合智慧法律評估工作實踐對pre-train和fine-tune不同模式下BERT模型與經典模型的效果差異進行了對比,發現即使僅訓練有限輪次,預訓練過的BERT模型也能取得很不錯的效果。本文將具體介紹上述實踐和探索,同時也將介紹在GoogleTPU上訓練訂製版BERT模型的過程。

關鍵詞:

BERT; pre-train; fine-tuning; performance; sequence length; TPU; multi-label; on-line prediction

1. 模型效果對比

我們使用司法領域的公開數據,在10萬份民事判決書上進行訓練和效果對比。輸入包括原告訴求請求、事實描述或法院認定的事實以及特定案由下的訴求類型;輸出是「0,1」。「1」代表支援原告,「0」代表不支援原告。訓練數據包含11個民事大案由,55個訴求類型。所有訴求類型的數據都經過取樣,支援與否比例為1比1。雖已預先過濾了一部分缺失證據、訴訟時效存在問題等影響結果預測的數據,但數據集中仍存在不少噪音。字元級別文本平均長度為420。報告的準確率,指驗證集上的準確率。

數據集:100k, 55個類別, 二元分類,驗證集上準確率,類別平衡

3L代表3層網路;sent-piar代表sentence pairs即句子對任務;seq-512代表sequence length即最大句子長度為512;batch32表示batch size即批次大小為32;epoch10代表訓練10輪次。其他簡寫,表示類似意思。

從訓練結果來看,有以下初步結論:

(1). 在同等條件下,使用句子對 (sent-pair)形式和單純的文檔分類(classify)的形式,來做本任務,效果相差不顯著;

(2). 根據12層(12L)和3層(3L)的模型對比效果,在本任務中暫不能得到 「更多層的BERT模型效果更好」的結論;

(3).最大序列長度(max sequence length)對模型的效果影響比較大。最好的模型是序列長度為512、使用3層的預訓練過的BERT模型。隨著最大序列長度增加,效果有所提升,但模型的訓練時間也相應增加。當最大序列長度變小後(如截取資訊),模型的準確率下降約3-4%。

(4). 批次大小(batch size)對模型的效果影響也比較,如從64下降到16後,模型的準確率下降幅度較大。

(5).fine-tuning模式下略微提高訓練輪次(epoch) ,效果可進一步提高2-5%。

(6). 不同模型效果對比:BERT模型>Fasttext模型(僅需訓練幾分鐘,準確率僅比BERT模型低3.5%)>TextCNN模型。可能的原因是我們的智慧法律評估任務並不僅關注關鍵詞等局部資訊,同時要結合文本中很多資訊做綜合判斷。

需要說明的是,本次效果對比在有限時間內完成,雖然每個模型都有做了一些調優工作,但這些模型如能結合一些其他技術、特徵工程等,可能都有比較大的提升空間。

除上述結論外,我們還發現了BERT預訓練模型在特定情況下(GPU環境,顯示卡配置固定)長文本任務中的困境——無法同時增大對最終效果提升有幫助的批次和最大序列長度。

從總體上看,在我們的任務中,使用比較長的序列長度,比較大的批次大小,效果比較好。但由於BERT模型比較大,在11G的顯示卡環境下,使用12層的網路、512的序列長度,批次大小最大只能設置為4,批次過小,導致訓練會不穩定。而使用256的序列長度,批次可以增大為16,但很多資訊又被丟失,效果也不佳,從而陷入兩難境地。

2. 在自己的數據集上運行BERT的三個步驟

(1).在github上克隆Google的BERT項目,下載中文預訓練的模型;

(2).分類任務中,在run_classifier.py中添加一個processor,明確如何獲取輸入和標籤。之後將該processor加到main中的processors。將自己的數據集放入到特定目錄。每行是一個數據,包括輸入和標籤,中間可以用特殊符號,如」t」隔開。數據集包含訓練集(如train.tsv)和驗證集(如dev.tsv);

(3).運行命令run_classifier.py,帶上指定參數,主要包含:訓練的任務類型、預訓練的模型地址、數據集的位置等。

3. 在自有數據集上做pre-train,然後做fine-tune

如果有任務相關的比較大的數據集,可在BERT中文預訓練模型的基礎上,再使用自有數據集做進一步的預訓練(可稱之為domain-pre-train),然後在具體的任務中做fine-tune。

需要做的工作包括:

(1)從領域相關的數據集上抽取出預訓練文本。文本的格式如下:每一句話是一行,每一個文檔直接用空行隔開。

(2)將預訓練文本轉換成tfrecord格式的數據。

運行 create_pretraining_data.py

(3)預訓練模型pre-train

運行 run_pretraining.py

(4)調優模型(fine-tuning)

運行 run_classifier.py

預訓練任務上的效果對比:

由此可看到,使用領域相關的數據做pre-train,在兩個預訓練任務上,效果提升了3-5%。在我們的實驗中,為了加快預訓練速度,只選取了領域相關的300萬行數據,運行12個小時,1/3個epoch,但預訓練任務的準確率還是有明顯的提升。

領域相關的任務上的效果對比:

我們使用了5個不同業務類別的數據,文本平均長度超過400,預測結果為0或1。

使用領域相關的數據做pre-train,相對直接使用BERT預訓練過的模型,絕對值有4.4%的提升,相對值有5.9%的提升。

隨著使用更大的領域相關數據,並且增加訓練輪次,相信效果會有進一步的提升。

4. 在TPU上使用BERT模型

下面簡單介紹使用TPU的兩種方式。任何一種方式下,都需要有Google計算引擎的賬戶,以及Google雲存儲的賬戶來存儲數據和保存訓練過的模型。使用TPU的好處之一是可以利用其強大的計算能力,猶如在CPU時代使用GPU來訓練,大幅提升訓練速度和效率。

Google Colab notebook方式體驗TPU

可通過Google Colab notebook 免費使用TPU, 體驗在TPU環境下,BERT在兩個自帶數據集的分類任務: "BERT FineTuning with Cloud TPUs"。但這個Colab主要是demo形式為主,雖能得出訓練和結果,但可能僅支援BERT自帶任務。

CTPU方式訪問TPU(Google雲專門訪問TPU環境的工具)

相比方式一,這是一個真正的生產環境,可以訓練模型。序列長度為512,在普通GPU下只能支援batch size為4,而在TPU下可以設置為128。從下圖可以看到訓練使用了8卡的TPU,每個卡訓練的batch size為16.

可通過Google的ctpu工具(見ctpu的github項目說明)運行「ctpu up」命令進入tpu環境。

(1).需要Google雲帳號和google cloud storage(gcs)存儲服務。

(2).在gcs中新建bucket,放入訓練和驗證數據、BERT預訓練過的模型。之後可通過gs:\形式,像訪問本地文件一樣訪問存儲服務中的數據。如新建了一個名叫data_training的bucket,那麼在TPU中它的地址就可以寫成

「gs:\data_training」。

(3).在TPU環境下克隆並下載自己訂製的BERT項目(或github上Google的BERT項目)。

(4).像在GPU里一樣運行命令訓練任務,只需加上參數use_tpu=true。訓練完後,從Google存儲位置的bucket中下載模型的checkpoint。

TPU下的訓練,Sequence length=512, batch size=128

第一次僅訓練了三輪後的準確率為0.739,模型的檢查點(checkpoint)自動被保存到預先設定的Google存儲服務的bucket中。如下圖:

5. 使用BERT模型做多類別任務

BERT模型本身只支援二分類或多分類,或是閱讀理解任務和命名實體識別任務。如需支援多類別任務(multi-label classfication),則需要訂製。具體可基於tensorflow的高級API(tf.estimator)來修改,也可以直接基於session-feed的風格實現。其中,基於session-feed方式主要修改如下:

(1)修改損失函數,使得多個類別任務具有非排他性。

(2)將一些輸入、標籤等,特別是是否訓練(is_training)的參數,變成佔位符(placeholder)。這樣可使用feed方式提供訓練或驗證數據;從而也可以根據訓練、驗證或測試的類型,來控制模型的防止過擬合的參數值(dropout的比例)。

因為做的是分類任務,需要在輸入序列的第一位插入特殊符號[CLS],訓練完後,模型根據最後一層的[CLS]所在的位置的隱藏狀態(hidden states),得到做為整個任務狀態的表示(representation)。

(3)根據BERT數據轉換的方式,以feed方式在session中將轉換後的數據通過佔位符輸出至模型。

6. 使用BERT模型做在線預測

BERT模型本身在訓練或驗證中只支援從文件中讀取數據,並不支援在線預測。可基於session-feed方式,根據BERT數據轉換的規則,將需要預測的數據提供給模型,從而獲得預測的概率分布,並完成預測。

7. 總結

BERT發布之前,模型的預訓練主要應用於電腦視覺領域。BERT發布後,很多NLP相關工作可在BERT模型預訓練的基礎上完成,使得自然語言處理更加成熟,支援在不同應用場景取得更好效果。

BERT模型在很大程度上提升了短文本、閱讀理解等任務效果,但由於目前業界單個顯示記憶體大小的限制和瓶頸,在長文本等任務上存在佔用較大計算資源和效果打折等問題。

在後續的工作中,我們將繼續嘗試提升BERT預訓練模型在長文本上的效果,如在領域相關的大數據上訓練、採用基於詞向量的BERT模型、使用滑動窗口方式應對文本過長的問題以及在TPU環境下實施大數據集的大規模訓練等。

實在智慧演算法團隊

作者介紹:

徐亮,實在智慧演算法專家,在深度學習、文本分類、意圖識別、問答系統方面有非常深入的研究和創新,github top10最受歡迎的文本分類項目作者。


Python方向有很多:機器學習、深度學習,python,情感分析、意見挖掘、句法分析、機器翻譯、人機對話、知識圖譜、語音識別等。