Pretraning in NLP(預訓練ELMo,GPT,BERT,XLNet)

在這裏插入圖片描述
圖像中的Pretraning往往是在大規模圖像集上進行訓練後,再在特定的任務上進行fine-turning。而nlp領域的fine-turning就是word embedding了。而詞嵌入(例如word2vec,GloVe)通常是在一個較大的語料庫上利用詞的共現統計預訓練得到的。例如king和queen上下文時常相同或相似,所以詞向量相似,在向量空間中詞距離很近。

但是word2vec在訓練完畢後,某個單詞的表示向量就已經確定了,這樣的向量對於一詞多義其實是沒有幫助的,換一個語境單詞所表達的意思就完全不一樣的,即Word2vec的處理其實是與上下文無關的(雖然可能用了多個不同語境的句子進行計算,但是最後總會得到一個向量,無法得到區分)。雖然可以在此基礎之上做一些聚類,但是也只是治標不治本。那如何做到靜態變動態呢?

ELMo(embedding from language models)
paper:https://arxiv.org/pdf/1802.05365.pdf
官網:https://allennlp.org/elmo
code:https://github.com/allenai/allennlp
在這裏插入圖片描述
ELMO的fine-turning:在使用中動態調整。
即,對於已經用語言模型訓練好了的Word Embedding,雖然無法處理多義詞,但在句子中使用這個詞向量的時候,會結合當前句子的上下文去調整這個單詞的Embedding,就ok了。(有點不同的是,NLP的pre往往是無監督的)

  • 實現細節如上圖。想要結合上下文信息,很自然的想法就是利用LSTM,<s>是句子的開頭要逐詞的預測下一位。(這個bilstm就可以理解爲 nlp的fine-turning…有時候也把原輸入embedding也拼接,即三個向量的cat)另外由於ELMo的輸入是字母爲單位,而不是單詞,所以對於 hhhhhh 這種沒有記錄的單詞也有很好的效果,至少能給出相近詞性的解釋。
  • ELMo是基於BiLSTM來抽取文本特徵的,即得到左右綠色和藍色的兩個LSTM特徵後,直接拼接(或者用alpha做控制)輸入到模型中去做下游任務。
  • 最後通過打印出在不同下游預訓練任務中哪些特徵比較重要,如右下角,在不同的時候某些特徵參數會格外的large,這在BERT等其他模型中可以觀察到,即預訓練模型究竟做了什麼,它是怎麼根據應用而適時的調整詞向量的。
    在這裏插入圖片描述

GPT(Generative Pre-Training)
paper:https://www.cs.ubc.ca/~amuham01/LING530/papers/radford2018improving.pdf
code:https://openai.com/blog/language-unsupervised/
在這裏插入圖片描述
GPT和ELMo一樣,也是先語言模型預訓練embedding,然後再fine-turning。fine-turning的不同點在於

  • LSTM升級爲Transformer提取特徵
  • Bi捨棄,變成單向而不是雙向。作者認爲如果雙向,在編碼解碼中有些單詞可能會間接的作弊,即提前的‘’看到‘’自己。(但是實際證明上下文信息對詞語的理解是非常重要了,所以之後的模型還是使用了雙向,並使用別的trick解決“作弊”問題)

由於結果固定住了,GPT在使用時需要讓 下游任務 往GPT的輸出靠攏,不過效果好什麼都中。

  • 序列標註:中文分詞,詞性標註,命名實體識別,語義角色標註等。
  • 分類任務:文本分類,情感計算
  • 句子關係判斷:Entailment,QA,語義改寫,自然語言推理
  • 生成式任務:機器翻譯,文本摘要,寫詩造句,看圖說話
  • 細分下來有,自然語言十項全能挑戰(decaNLP),涉及十個任務:問答,機器翻譯,摘要,自然語言推理,情感分析,詞性標註,關係抽取,目標導向對話,數據庫查詢生成和代詞解析
    在這裏插入圖片描述

BERT(Bidirectional Encoder Representation from Transformer)
劃時代之作。
paper:https://arxiv.org/abs/1810.04805
code:https://github.com/google-research/bert
在這裏插入圖片描述

  • LSTM太慢了啦 —> 還是Transformer吧,並行而且還沒有梯度的問題
  • 人類理解語言會同時考慮上下文的 —> 雙向吧,只要不看要預測的部分就可以

從圖看BERT的輸入是兩個句子A和B進行成對訓練,輸入以【CLS】(classification token)隔開,句子則是【SEP】(special token)隔開。。然後特徵由三個部分組成:詞嵌入後的token embedding,句子類別的符號segment embedding句子A,句子B,詞的位置信息position embedding,這跟Transformer裏面是一致的。這三個部分相加之後作爲輸入。然後Loss=MLM+NSP進行fine-turning:

  • Masked Language Model(MLM)。靈感來自完型填空,先扣掉(以【MASK】標記),再嘗試恢復。【MASK】總詞的15%,在15%中:80%用[MASK]標記替換,10%用其他的詞隨機替換,10%保持原詞不做替換,這一部分的loss只針對【MASK】位置的輸出。(即其他位置的詞輸出正確與否,不在MLM計算)
  • Next Sentence Prediction(NSP)。NSP關注兩個句子間的關係,所以輸出是binarized task即成對訓練。對於成對訓練的【句子A,句子B】的構建,50%的兩個句子對間有上下關係,此時label爲IsNext或1,剩下50%的句子無上下關係(隨機選擇),標記label爲NoNext或0。

Training tips

  • 1dupe_factor,從訓練文檔中重複使用一些數據的比例,訓練集數目少的時候可以設置高一些
  • 2max_predictions_per_eq,控制一句話裏面被mask的最大數目
  • 3do_whole_word_mask,如果是true就整個詞矇住,如果false則是會傾向矇住單詞裏的字母(個人理解這種操作同樣也是填空的一種形式,矇住後的詞同樣是不認識的新詞,需要靠語境來判斷)
  • 4length of a sentence is larger than the limit,句子中的最大長度限制

BERT的缺點:

  • 【MASK】只會在預訓練中使用,後續任務是不會出現的,所以導致訓練環境和測試環境不一樣(一個有mask,一個沒有mask)。實際處理中,在後續任務時需要同樣按相同的比率替換句子。即把輸入序列中的k%(一般爲15%,k太小:計算代價過大。k太大:剩下的上下文不足以準確預測)的詞掩蓋住,然後通過上下文預測這些被掩蓋住的詞。
  • independent assumption。每個詞都是獨立的,很多短語被強行拆開(如New York)。(這點由於ELMo服從概率完備,用LSTM基於前面的詞的隱向量,預測後面的句子,所以可以處理好這個問題,即詞和詞之間有聯繫的)
  • 缺乏生成能力。是mased地方的重構。

BERT的本質
BERT的本質是Denoising Autoencoder,降噪自編碼。

  • 預訓練是無監督的,尋找詞自己之間的關係和表達。之後在下游任務中才會有監督。
  • AE:輸入–中間特徵–輸出,約束輸入==輸出。DAE:輸入+噪聲–中間特徵–輸出,在同樣的約束下起降噪的作用使結果更加的魯棒。而BERT:輸入+【MASK】–Transformer–輸出預測【MASK】。所以實際上,【MASK】的作用就是加了噪音,然後利用Transformer進行降噪。

在這裏插入圖片描述

XLNet(Generalized Autoregressive Pretraining for Language)
集大成者來了。

  • 自迴歸語言模型(Autoregressive LM)。代表是ELMo 和 GPT,根據前文預測後面的單詞或者反過來的思路。優點是:詞與詞之間是有聯繫的。缺點是:只能利用上文或者下文的信息,不能同時利用上文和下文的信息(ELMO雖然雙向都做,但是是僞雙向,即正向的時候用不到反向,反向用不到正向)。
  • 自編碼語言模型(Autoencoder LM)。代表BERT。優點:直接就是上下文都能夠考慮到。缺點:1 詞和詞割裂 2使用了【MASK】使訓練和測試的環境不一致。

XLNet:我要融合。我要構建一個

  • 考慮上下文雙向信息
  • 考慮詞間依賴關係
  • 測試環境一致
    在這裏插入圖片描述

融合思路顯然是改裝ELMo更爲方便,只需要把ELMo變得可以處理真正的上下文就行。那麼如何在只看得到前面詞的時候,也能揉入後面的詞?

  • 亂序全排列語言模型(Permutation Language model),即如果每個詞都可以有不同的位置,就可以利用到上下文信息了!如上圖h1(1),h1(2)h^{(1)}_1,h^{(2)}_1上標是層數(多層Transformer),下標是位置信息,正常情況下一個四個詞的句子詞順序是【1 2 3 4】,那麼打亂這個順序變成【3 2 4 1】,【2 4 3 1】等等,那麼在預測比如x3x_3的時候,【1 2 3 4】的3的前面有1 2的信息,【3 2 4 1】的3的沒有其他的詞即會是開始符,【2 4 3 1】的3的前面有2 4的信息可以利用,以前正常的順序是無法看到4號的信息,打亂之後就可以用到了。
  • 在具體的實現中,不用打亂輸入(即還是1234),只是此時的3要用到誰,就連接誰,如上圖的第2個圖【2 4 3 1】,3的前面有2 4的信息可以用,那麼h3(1)h^{(1)}_3連接了x2x_2x4x_4,還有mem(即在當前詞輸出前,已經輸出的隱向量表示,即在預測3號的時候,實際上2和4已經輸出了,mem是它倆的表示)
  • 雙流自注意力機制(Two-stream Self Attention)。PLM實際上已經完成了融合的任務,但是此處存在一個衝突問題需要解決即:1 預測自己時不能有自己的內容信息(如果知道了x3x_3去預測x3x_3就作弊了,只能用x2x_2x4x_4的信息預測x3x_3) 2預測別人時,自己由作爲了上下文,又需要給出所有信息(內容信息+位置信息)。(預測完x3x_3後,需要輸出x1x_1,此時x3x_3需要用到其他詞的向量)。衝突就在於:既要沒有自己,自己又不能丟?怎麼辦?
  • two-stream,雙流,一個流content stream是既有內容又有位置信息,一個流query stream是隻有位置信息,沒有自己的內容信息。實現如下圖,h1h_1g1g_1分別是兩個流的隱層,圖a是標準self-Attention組成的content stream,查詢h1(0)h_1^{(0)}得到h1(1)h_1^{(1)},圖b是不能跟自己內容有連接的query stream,然後在不同情況下用不同的流進行計算就行。
  • 此外關於打亂的順序由利用Attention masks實現,即如圖中的矩陣紅色代表有關係。(在content stream第一行與1234有關,第二行與23有關,第三行與3有關,第四行與234有關,即邏輯上的順序是【3 2 4 1】,query stream中則是沒有對角線即不能看到自己,不作弊)通過不同的掩碼,就能得到不同邏輯順序的句子了。
    在這裏插入圖片描述

Trick:
引入了Transformer-XL做提升,Transformer-XL=Transformer+RNN。

  • 原因:Transformer的最大缺點是每個Transformer的所有的Decoder層的矩陣都要保存以便BP,但是預訓練模型往往需要很大量的計算,比如直接輸入好幾本書,計算資源消耗比較大,所以導致Transformer每次無法輸入很長的文本進行訓練。
  • 主要思路:相對位置編碼以及分段RNN機制。即第一頁句子在第一個Transformer訓練,第二頁在另一個訓練,由於兩者之間可能存在關係,再使用分段RNN機制進行連接。實踐已經證明這兩點對於長文檔任務是很有幫助的。
    未來:1Transformer-XL爲什麼有效?2permutation的採樣如何更加有效 3compress成Albert 4合適的融合應用。

和BERT其實是一回事?

  • Bert是直接在輸入端顯示地通過引入Mask標記,在輸入側隱藏掉一部分單詞,讓這些單詞在預測的時候不發揮作用,要求利用上下文中其它單詞去預測某個被Mask掉的單詞;而XLNet則拋棄掉輸入側的Mask標記,通過Attention Mask機制,在Transformer內部隨機Mask掉一部分單詞(這個被Mask掉的單詞比例跟當前單詞在句子中的位置有關係,位置越靠前,被Mask掉的比例越高,位置越靠後,被Mask掉的比例越低),讓這些被Mask掉的單詞在預測某個單詞的時候不發生作用。

(詳細請參看張俊林大牛:https://zhuanlan.zhihu.com/p/70257427)

應用BERT提特徵
實際訓練BERT 需要用 WordPiece工具分詞,並插入各種特殊的分離符如([CLS],用來分隔樣本)和分隔符([SEP],用來分隔樣本內的不同句子)等等細節,其訓練花費很輕鬆只需要76分鐘!(如果我們能有1024塊TPU…在16 個 Cloud TPU 上則需要訓練 4 天, GPT-2是BERT的3倍,而XLNet在128 個 Cloud TPU v3 下需要訓練 2 天半,花費以美金算emmm)

所以還是看怎麼使用Pretraning

版本一:使用自己的詞彙庫進行訓練
https://github.com/codertimo/BERT-pytorch

 1. pip install bert-pytorch
 2. 準備語料庫,兩個句子在同一行,並用 \t 分割。如
	Welcome to the \t the jungle\n
	I can stay \t here all night\n
 3. 建立vocab
 	bert-vocab -c data/corpus.small -o data/vocab.small
 4. 訓練bert
 	bert -c data/corpus.small -v data/vocab.small -o output/bert.model

版本二:利用訓練好的模型進行向量抽取
https://github.com/hanxiao/bert-as-service 或者keras的版本:https://github.com/CyberZHG/keras-bert

1. 下載英文詞向量:https://storage.googleapis.com/bert_models/2018_11_03/english_L-12_H-768_A-12.zip
2. 或者中文詞向量:https://storage.googleapis.com/bert_models/2018_11_03/chinese_L-12_H-768_A-12.zip
3. 開啓服務器BERT:bert-serving-start -model_dir /tmp/english_L-12_H-768_A-12/ -num_worker=4 

訪問本機
from bert_serving.client import BertClient
bc = BertClient()
bc.encode(['First do it', 'then do it right', 'then do it better'])

遠程訪問,加入端口號
from bert_serving.client import BertClient
bc = BertClient(ip='xx.xx.xx.xx')  # ip address of the GPU machine
bc.encode(['First do it', 'then do it right', 'then do it better'])

或者跑example的代碼,親測真好用…給大佬加星。

版本三:直接使用開源工具
文本摘要:https://github.com/dmmiller612/bert-extractive-summarizer

from summarizer import Summarizer

text='xxxx xxx'
model=Summarizer()
model(text)

ALBERT: A Lite BERT for Language Understanding:
最後,最近又有火爆的模型出現了!由於BERT參數太了(base版1.1億,large版3.4億),ALBERT模型的目的是實現參數量輕量級。它主要的優化是:

  • factorized embedding parametrization。在one-hot處理的過程中先用矩陣做低秩分解,從O(V×H)O(V\times H)O(V×+E×H)O(V\times+E\times H),減少了19M個參數。
  • 共享Transformer注意力所有層的參數。即不管多少層,每層參數都用一樣的(雖然參數共享,但每一層的輸出不一樣,Attention的動態調整效果也是不一樣的)。以前使用12層Transformer,所以參數數量變成12分之一。
  • 不要dropout。提升不明顯,還佔內存,所以不使用。
  • 將參數變少後性能略有降低,然後學Alex把網絡加寬加深,這樣在參數量比較小的情況下得到了比BERT性能很好的提升。
  • 之前有人發文詬病:NSP構建正負例的方式,由於負例的句子是隨機組合,這樣容易讓網絡找到topic進行學習(即線索詞,A句子和B句子很無關,所以很容易分別上下文是否有聯繫)。所以作者將NSP變成SOP(sentence order prediction),即直接把A,B對換就行了,這樣保證了topic一致的情況下構建了正負例。

在這裏插入圖片描述
ERNIE2.0
ERNIE1.0如上,是把BERT改爲適合中文的模型,想法是來自對於中文的詞很容易猜到masked某個詞,所以masked是一整個詞(做到這一點將BERT融合了知識圖譜(knowledge graphs,KG),以知識圖譜中的多信息實體(informative entity)作爲外部知識改善語言表徵)。

而ERNIE2.0挺有意思的,也放上來一下,它主要貢獻是兩個:

  • 序列多任務學習的預訓練任務機制(sequential multi-task learning),使模型能夠學習到詞彙,語法,語義信息。不同於持續學習和多任務學習,序列多任務學習在引入新的訓練任務時,先利用之前學習到的參數對模型進行初始化,再同時訓練新任務和舊任務。
  • 定製和引入了多種預訓練任務。側重詞彙的任務(mask,大寫字詞預測,字詞-文章關係),側重結構/語法的任務(詞語重排序,語句距離),側重語義的任務(文章關係任務,信息檢索相關性任務)。

Future?

  • Pre+KG。
  • Pre+ENDEcodeer。如UULM。
  • Pre+Multi-Learning。如MT-DNN,ERNIE。
  • Updated Pre。如XLNet,RoBERTa。
  • Pre+Chinese。BERT-WWM。
  • Pre+Turning。
  • Updated Transformer?Transformerxl?

模型對比
在這裏插入圖片描述
預訓練語言模型(PLM)論文清單:https://github.com/t/thunlp/PLMpaper

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章