天天看點

NLP入門開源實踐總結

一、任務介紹與實際應用

文本分類任務是NLP中最常見、最基礎的任務之一,顧名思義,就是對給定的一個句子或一段文本進行分類。根據文本分類的類别定義,可以分為二分類/多分類、多标簽、層次分類,以下面的新聞分類為例:

• 二分類/多分類:标簽集中有兩個或以上的标簽類别,每個樣本有且隻有一個标簽;

• 多标簽:每個樣本有一個或多個标簽;

• 層次分類:特殊的多分類或多标簽任務,标簽之間具有層次關系。比如下圖樣本的一級标簽是體育,二級标簽是足球,體育為足球的父标簽。

NLP入門開源實踐總結

文本分類廣泛應用于情感分析、新聞分類、事件類别分類、政務資料分類、商品資訊分類、商品類目預測、文章分類、論文分類、案件描述分類、罪名分類、意圖分類、郵件自動标簽、評論正負識别、藥物反應分類、對話分類、稅種識别、來電資訊自動分類、投訴分類、廣告檢測、敏感違法内容檢測、話題标記等日常或專業領域中。

• 情感分析:情感分析是針對資料的情感傾向進行分類,可以是二分類(正向或負向)或者是多分類(按照不同的細粒度劃分情感),情感分析在影音評論、商品評價、輿情分析、股民基金情感分析等都有重要的應用。

• 主題分類:主題分類也是常見的文本分類應用場景,根據内容或标題進行分類,既可以是多分類、多标簽也可以是層次分類,根據實際場景需要進行标簽體系構造和劃分。

• 金融資料分類:金融資料繁多複雜,文本分類可以應用于金融新聞分類、股民評論情感分析、基金類型分類、金融問答分類、金融情緒分析等多種任務,有助于從大量資料挖掘有效資訊。

• 醫療資料分類:目前,文本分類已有許多醫療領域的成功應用,如藥物反應分類、症狀和患者問題分類,健康問答分類、電子病曆分類、藥品文本分類等等。

• 法律資料分類:文本分類在法律領域也有許多成果的探索,如罪名分類、案情要素分類、刑期預測、法律條文分類、法律情感分析、判決預測、法律文本挖掘、合規審查等等,幫助我們從海量的法律資料抽取有效資訊。

二、預訓練模型簡介

随着Transformer 和 Bert 的出現,NLP模型大步跨向了預訓練模型時代,剛入門的NLP的同學可能會疑惑什麼是預訓練模型?預訓練模型和文本分類模型是什麼關系?我該使用什麼預訓練模型?隻有CPU能訓練嗎?怎麼加載預訓練模型?

1、什麼是預訓練模型?

通常來說模型複雜度越高參數越多,模型越能拟合複雜的問題,預測精度越高。随着深度學習的發展,模型參數的數量飛速增長。為了訓練這些參數,需要更大的資料集來避免過拟合,而建構大規模的标注資料集非常困難。是以目前的做法是先在超大規模的語料采用無監督或者弱監督的方式訓練模型,模型能夠獲得語言語義、文法相關的知識,然後再用具體的下遊任務資料微調訓練,這樣的模型稱為預訓練模型。

預訓練模型首先會将輸入的句子分成多個token,英文句子通常是subword-level的分詞政策,中文句子由于最小的機關就是字,是以通常是一個字元即為一個token,例如句子 "今天是個好天氣!" 切分為8個token ['今', '天', '是', '個', '好', '天', '氣', '!'];

在多語言模型中也有将詞作為token的情況,還是上面的例子,句子切分為5個token ['今天', '是個', '好', '天氣', '!']。(分詞細節可以參見 tokenizers小結) 此外,模型會在每個輸入的開頭加入一個[CLS]的token,在句子對間加入一個[SEP]的token。

如下圖所示,每個輸入token會映射為一個對應的特征表示,經過預訓練模型得到每個token的輸出特征表示,token輸出的特征表示會用于不同的任務,[CLS]的輸出特征通常被認為是整個句子的語義表示。這裡以BERT論文内示意圖為例,目前絕大多數基于Transformer的預訓練模型結構都是相似的。

NLP入門開源實踐總結

接下來就是預訓練,不同預訓練模型的預訓練方式略有不同,常用的無監督任務包括MLM和NSP任務:

• Mask Language Model(MLM,掩碼預測):,即将一個句子中某一個token用掩碼[MASK]替換,然後讓模型預測出這個token。例如:"今天出太陽了,是個[MASK]天氣",希望模型預測[MASK] -> 好。具體來說就是用[MASK]的模型輸出特征,後接一個分類器進行分類。

• Next sentence Prediction(NSP,上下文句子預測):從文章中摘取兩個句子A和B,50%是上下文關系,50%不是,訓練模型預測句子A和句子B是否為上下文關系,也即在[CLS]的模型輸出特征後接一個分類器進行二分類。

關于預訓練模型結構和訓練細節就不在這裡贅述了,現在已經有許多寫的很好文章講解。

2、預訓練模型和文本分類模型關系?

預訓練模型學習到的文本語義表示能夠避免從零開始訓練模型,他們之間的關系可以直覺地了解為,預訓練模型已經懂得了相關句法、語義的語言知識,用具體下遊任務資料訓練能夠使得預訓練模型”更懂”這個任務,在預訓練過程中學到的知識基礎使學習文本分類任務事半功倍。

NLP入門開源實踐總結

以BERT論文内示意圖為例,先對模型進行預訓練,在預訓練模型的參數基礎上用具體下遊任務的訓練資料微調

3、我該使用什麼預訓練模型?

目前已經有許多開源的預訓練集模型,雖然英文預訓練模型有GLUE 榜單,中文預訓練模型有CLUE榜單,多語言模型有XTREME榜單,但選擇模型還是要根據具體的任務和硬體條件進行選擇。我中文分類任務做的比較多,常用的預模型包括 ERNIE (多尺寸模型選擇真的香)、Roformer-v2、Mengzi、RoBERTa-wwm-ext。

4、隻有CPU能訓練嗎?

能,但耗時比較長。CPU開發者推薦使用層數比較少的小模型,或選擇白嫖一些線上AI平台免費算力比如AI Studio(每天白嫖8小時V100,Paddle)、Google Colab(要翻牆,Pytorch Tensorflow都支援)。

5、怎麼加載開源的預訓練模型?

目前最友善的方法就是在PaddleNLP(Paddle)或 HuggingFace(Pytorch)直接根據模型名稱使用AutoModel的方式調用,也可以在github上找開源模型參數下載下傳連結。

model = AutoModelForSequenceClassification.from_pretrained(MODEL_NAME)      

三、基于預訓練模型的文本分類算法

講了這麼多,終于到文本分類算法介紹了。文本分類算法最最常用的就是預訓練-微調方法,當然也還包括在最近讨論度很高的預訓練新範式——提示學習(Prompt Tuning),之前看到基于檢索的方法做文本分類也還蠻有意思的。

1、常用方法——預訓練模型微調

基于預訓練模型微調的想法非常簡單直接,也即将[CLS]的模型輸出特征表示作為輸入句子的特征表示,通常為768維或1024維的向量,然後接入一個線性分類器(通常為單層全連接配接層)進行文本分類任務訓練。

NLP入門開源實踐總結

基于預訓練模型微調的文本分類示意圖

2、小樣本——提示學習(Prompt Tuning)

近來,提示學習的火熱,主要還是在小樣本場景的優秀表現。

提示學習的主要思想是将文本分類任務轉換為構造提示(Prompt)中掩碼 [MASK] 的分類預測任務,也即在掩碼 [MASK]模型輸出特征後接入線性層分類器預測掩碼位置可能的字或詞。提示學習使用待預測字的預訓練向量來初始化分類器參數(如果待預測的是詞,則為詞中所有字的預訓練向量平均值),充分利用預訓練語言模型學習到的特征和标簽文本,進而降低樣本需求。

我們以下圖情感二分類任務為例來具體介紹提示學習流程。在輸入文本後加入構造提示"我[MASK]喜歡。",将"負向"或"正向"的情感二分類任務轉化為掩碼[MASK]"不"或"很"的二分類任務,構造提示[MASK]分類器預測分類與原始标簽的對應關系為"不"->"負向" 、"很"->"正向" 。具體實作方法是在掩碼[MASK]的輸出向量後接入線性分類器(二分類),然後用"不"和"很"的預訓練向量來初始化分類器進行訓練。

NLP入門開源實踐總結

圖:預訓練模型微調 vs 提示學習

3、創新方法——檢索

除了以上兩種方法,我還試過用檢索的方式做文本分類。檢索的方法适合标簽類别較多或者是标簽類别不固定(有時候會新增标簽)的情況,新增标簽類别無需重訓模型。

基于檢索的方法做文本分類有兩種思路,一種是把标簽集作為召回庫,一種是把訓練資料作為召回庫。這兩種思路在訓練階段的方法是一緻的,可以用雙塔模型(也就是兩個預訓練模型),一個模型輸入句子,另一個模型輸入标簽,拉近句子和标簽的[CLS]輸出特征表示之間的距離。在預測階段,召回集有所不同:

思路一把标簽作為召回集,每個标簽的向量表示(也即[CLS]輸出特征表示)是固定的,我們建構一個标簽向量庫。我們用待預測的句子的向量在标簽向量庫進行檢索,找到特征相似度最大的标簽,也即為待預測句子的标簽。

NLP入門開源實踐總結

圖:基于檢索思路實作文本分類

思路二則是把訓練資料作為召回集,建構一個訓練集文本的向量庫,我們用待預測的句子的向量表示(也即[CLS]輸出特征表示)在文本向量庫進行檢索,找到特征相似度最大的訓練集文本,待預測句子的标簽也即召回文本的标簽。

四、實踐經驗總結

1、資料為王時代

在實踐代碼開始之前更想讨論一下資料,我個人的實踐經驗來說,提高文本分類精度最快、最有效的方法是既不是模型,也不是算法調參,而是資料品質。文本分類總的來說不是個複雜的自然語言處理任務(甚至可以說是最基本的任務),如何更好地進行資料标簽的劃分,減少混淆重合情況和高品質的資料标注(正确标注,标準統一,且訓練集與預測資料分布一緻)是得到高精度的文本分類模型的關鍵。

•标簽體系劃分

文本分類任務的标簽體系依具體的任務而定,沒有固定标準,一個清晰分界明确的标簽體系有利于資料标注和分類。如果是多分類任務的話盡量減少标簽之間範圍重合,這樣有助于标注标準的統一,減少出現在标注的時候相似的樣本有的被标記為A,有的标記為B,降低準确率。

•标注正确

"Garbage in, garbage out(垃圾進,垃圾出)",如果訓練資料包含很多錯誤,可想而知模型不會有很好的預測結果。人工檢查所有資料标注是否準确,成本不低,是以可以通過一些算法計算訓練資料對模型的擾動,來篩選出髒資料進行重新标注。(這點之後會寫新的文章細講)

•訓練資料和預測資料分布一緻

深度學習模型可以了解為拟合訓練資料的分布,雖然大規模語料預訓練,能夠有效幫助模型有更好的泛化能力,但隻有模型學習與預測場景相似的訓練樣本,才能在預測資料有更好的表現。在實踐場景中遇到許多效果不好的基本是這個問題,比如遇到多标簽分類訓練集的資料隻有一個标簽,模型理所應當傾向于隻預測一個标簽,而測試集有多個标簽,效果可想而知不太好。

•文本資料精選有效資訊

目前預訓練模型通常支援的max_length最大為512,有些模型可能會應用一些政策使模型能夠接受輸入長度最長2048,當然還有一些支援長文本的模型例如Longformer,ERNIE-Doc。但輸入文本過長,容易爆顯存,訓練速度過慢,并且由于文本包含過多無用的資訊幹擾使模型效果變差。因為文本資料十分多樣,如何精選文本資料需要按實際資料而定,常見方法按句号對句子截斷、利用一些正則式比對的方法篩選有效文本内容等。

•充足的資料

雖然文本分類在零樣本和小樣本領域有許多探索,但效果暫時還是很難超越在充足訓練資料進行微調。充足的資料優先的方法當然是選擇資料标注的方式,資料增強政策也是常見擴充資料的方法。

總而言之,高品質的訓練資料是高精度文本分類模型的關鍵。

2、實踐經驗記錄

現實場景中的資料并不總是那麼理想,需要根據一些實際情況進行靈活變化。使用的也許不一定是最好的解法,歡迎各位大佬們讨論。

•文本分類的類别非常多,幾百上千甚至萬級别

這時候用預訓練模型微調的方法,效果表現可能非常一般甚至可能難以收斂。如果還要使用預訓練模型微調的話,建議是使用多個分類模型,先訓練一個文本分類模型(大類分類器)把資料分為具體的大類,每個大類再訓練一個文本分類模型(子類分類器)對樣本類别進行預測(缺點就是要訓練多個分類器);另一個方法就是用檢索的方法去做,不再是分類,而是召回與文本最相似的标簽。

•多分類任務預測可能會出現訓練集沒有出現的類别,希望可以預測成"其他"

前面也提到訓練資料最好與預測資料一緻,否則效果可能有限,但現實場景還是很難避免。最直接的想法是在多分類中建構一個"其他"的類别,但這種方法也有缺點,比如就是訓練的時候一點其他類别的資料沒有,另外也可能由于"其他"類别的資料分布差異很大,導緻這個類别預測效果較差。最終選擇的實踐方法是使用多标簽的方式進行訓練,然後預測時候選擇置信度最高的類别作為标簽類别,如果置信度低于門檻值(比如0.5),則這個類别為"其他"。訓練的時候,如果有"其他"類别的資料,則該資料的标簽為[0,0,0...,0]。

•關于調參

超參數設定我自己常用的是learning rate [1e-5,3e-5,5e-5],batch size[16, 24, 32],使用早停政策,選擇開發集精度最高的模型參數。如果要進一步提高精度的話,會標明epoch數(不使用早停政策)應用warmup政策。個人感覺,超參設定對模型效果影響不大(除非把batch size設為1,learning rate設的超大或超小這種),warmup政策也是小幅度的提高,在文本分類任務通過調參實作精度10%幅度這種大提高的可能性非常小。(參考:CLUE超參搜參結果)

3、常見分類資料集

PaddleNLP中整理了一系列文本分類資料集,大家可以自取:

NLP入門開源實踐總結

4、更多實戰

繼續閱讀