BERT預訓練模型的演進過程!(附代碼)

1. 什麼是BERT

BERT的全稱是Bidirectional Encoder Representation from Transformers,是Google2018年提出的預訓練模型,即雙向Transformer的Encoder,因爲decoder是不能獲要預測的信息的。模型的主要創新點都在pre-train方法上,即用了Masked LM和Next Sentence Prediction兩種方法分別捕捉詞語和句子級別的representation。

Bert最近很火,應該是最近最火爆的AI進展,網上的評價很高,那麼Bert值得這麼高的評價嗎?我個人判斷是值得。那爲什麼會有這麼高的評價呢?是因爲它有重大的理論或者模型創新嗎?其實並沒有,從模型創新角度看一般,創新不算大。但是架不住效果太好了,基本刷新了很多NLP的任務的最好性能,有些任務還被刷爆了,這個纔是關鍵。另外一點是Bert具備廣泛的通用性,就是說絕大部分NLP任務都可以採用類似的兩階段模式直接去提升效果,這個第二關鍵。客觀的說,把Bert當做最近兩年NLP重大進展的集大成者更符合事實。

2. 從Word Embedding到Bert模型的發展

2.1 圖像的預訓練

自從深度學習火起來後,預訓練過程就是做圖像或者視頻領域的一種比較常規的做法,有比較長的歷史了,而且這種做法很有效,能明顯促進應用的效果。

那麼圖像領域怎麼做預訓練呢,上圖展示了這個過程,

  1. 我們設計好網絡結構以後,對於圖像來說一般是CNN的多層疊加網絡結構,可以先用某個訓練集合比如訓練集合A或者訓練集合B對這個網絡進行預先訓練,在A任務上或者B任務上學會網絡參數,然後存起來以備後用。

  2. 假設我們面臨第三個任務C,網絡結構採取相同的網絡結構,在比較淺的幾層CNN結構,網絡參數初始化的時候可以加載A任務或者B任務學習好的參數,其它CNN高層參數仍然隨機初始化。

  3. 之後我們用C任務的訓練數據來訓練網絡,此時有兩種做法:

    一種是淺層加載的參數在訓練C任務過程中不動,這種方法被稱爲“Frozen”;

    另一種是底層網絡參數儘管被初始化了,在C任務訓練過程中仍然隨着訓練的進程不斷改變,這種一般叫“Fine-Tuning”,顧名思義,就是更好地把參數進行調整使得更適應當前的C任務。

一般圖像或者視頻領域要做預訓練一般都這麼做。這樣做的優點是:如果手頭任務C的訓練集合數據量較少的話,利用預訓練出來的參數來訓練任務C,加個預訓練過程也能極大加快任務訓練的收斂速度,所以這種預訓練方式是老少皆宜的解決方案,另外療效又好,所以在做圖像處理領域很快就流行開來。

爲什麼預訓練可行

對於層級的CNN結構來說,不同層級的神經元學習到了不同類型的圖像特徵,由底向上特徵形成層級結構,所以預訓練好的網絡參數,尤其是底層的網絡參數抽取出特徵跟具體任務越無關,越具備任務的通用性,所以這是爲何一般用底層預訓練好的參數初始化新任務網絡參數的原因。而高層特徵跟任務關聯較大,實際可以不用使用,或者採用Fine-tuning用新數據集合清洗掉高層無關的特徵抽取器。

2.2 Word Embedding

神經網絡語言模型(NNLM)的思路。先說訓練過程。學習任務是輸入某個句中單詞 [公式] 前面句子的t-1個單詞,要求網絡正確預測單詞Bert,即最大化:

[公式]

前面任意單詞 [公式] 用Onehot編碼(比如:0001000)作爲原始單詞輸入,之後乘以矩陣Q後獲得向量 [公式] ,每個單詞的 [公式] 拼接,上接隱層,然後接softmax去預測後面應該後續接哪個單詞。這個 [公式] 是什麼?這其實就是單詞對應的Word Embedding值,那個矩陣Q包含V行,V代表詞典大小,每一行內容代表對應單詞的Word embedding值。只不過Q的內容也是網絡參數,需要學習獲得,訓練剛開始用隨機值初始化矩陣Q,當這個網絡訓練好之後,矩陣Q的內容被正確賦值,每一行代表一個單詞對應的Word embedding值。所以你看,通過這個網絡學習語言模型任務,這個網絡不僅自己能夠根據上文預測後接單詞是什麼,同時獲得一個副產品,就是那個矩陣Q,這就是單詞的Word Embedding。

2013年最火的用語言模型做Word Embedding的工具是Word2Vec,後來又出了Glove,Word2Vec。對於這兩個模型不熟悉的可以參考我之前的文章,這裏不再贅述:

上面這種模型做法就是18年之前NLP領域裏面採用預訓練的典型做法,之前說過,Word Embedding其實對於很多下游NLP任務是有幫助的,只是幫助沒有大到閃瞎忘記戴墨鏡的圍觀羣衆的雙眼而已。那麼新問題來了,爲什麼這樣訓練及使用Word Embedding的效果沒有期待中那麼好呢?答案很簡單,因爲Word Embedding有問題唄。這貌似是個比較弱智的答案,關鍵是Word Embedding存在什麼問題?這其實是個好問題。

**這片在Word Embedding頭上籠罩了好幾年的烏雲是什麼?是多義詞問題。**我們知道,多義詞是自然語言中經常出現的現象,也是語言靈活性和高效性的一種體現。多義詞對Word Embedding來說有什麼負面影響?如上圖所示,比如多義詞Bank,有兩個常用含義,但是Word Embedding在對bank這個單詞進行編碼的時候,是區分不開這兩個含義的,因爲它們儘管上下文環境中出現的單詞不同,但是在用語言模型訓練的時候,不論什麼上下文的句子經過word2vec,都是預測相同的單詞bank,而同一個單詞佔的是同一行的參數空間,這導致兩種不同的上下文信息都會編碼到相同的word embedding空間裏去。所以word embedding無法區分多義詞的不同語義,這就是它的一個比較嚴重的問題。

有沒有簡單優美的解決方案呢?ELMO提供了一種簡潔優雅的解決方案。

2.3 ELMO

ELMO是“Embedding from Language Models”的簡稱,其實這個名字並沒有反應它的本質思想,提出ELMO的論文題目:“Deep contextualized word representation”更能體現其精髓,而精髓在哪裏?在deep contextualized這個短語,一個是deep,一個是context,其中context更關鍵。

在此之前的Word Embedding本質上是個靜態的方式,所謂靜態指的是訓練好之後每個單詞的表達就固定住了,以後使用的時候,不論新句子上下文單詞是什麼,這個單詞的Word Embedding不會跟着上下文場景的變化而改變,所以對於比如Bank這個詞,它事先學好的Word Embedding中混合了幾種語義 ,在應用中來了個新句子,即使從上下文中(比如句子包含money等詞)明顯可以看出它代表的是“銀行”的含義,但是對應的Word Embedding內容也不會變,它還是混合了多種語義。這是爲何說它是靜態的,這也是問題所在。

ELMO的本質思想是:我事先用語言模型學好一個單詞的Word Embedding,此時多義詞無法區分,不過這沒關係。在我實際使用Word Embedding的時候,單詞已經具備了特定的上下文了,這個時候我可以根據上下文單詞的語義去調整單詞的Word Embedding表示,這樣經過調整後的Word Embedding更能表達在這個上下文中的具體含義,自然也就解決了多義詞的問題了。所以ELMO本身是個根據當前上下文對Word Embedding動態調整的思路。

ELMO採用了典型的兩階段過程,第一個階段是利用語言模型進行預訓練;第二個階段是在做下游任務時,從預訓練網絡中提取對應單詞的網絡各層的Word Embedding作爲新特徵補充到下游任務中。

上圖展示的是其預訓練過程,它的網絡結構採用了雙層雙向LSTM,目前語言模型訓練的任務目標是根據單詞 [公式] 的上下文去正確預測單詞 [公式][公式] 之前的單詞序列Context-before稱爲上文,之後的單詞序列Context-after稱爲下文。

圖中左端的前向雙層LSTM代表正方向編碼器,輸入的是從左到右順序的除了預測單詞外 [公式] 的上文Context-before;右端的逆向雙層LSTM代表反方向編碼器,輸入的是從右到左的逆序的句子下文Context-after;每個編碼器的深度都是兩層LSTM疊加。

這個網絡結構其實在NLP中是很常用的。使用這個網絡結構利用大量語料做語言模型任務就能預先訓練好這個網絡,如果訓練好這個網絡後,輸入一個新句子 [公式] ,句子中每個單詞都能得到對應的三個Embedding:

  • 最底層是單詞的Word Embedding;
  • 往上走是第一層雙向LSTM中對應單詞位置的Embedding,這層編碼單詞的句法信息更多一些;
  • 再往上走是第二層LSTM中對應單詞位置的Embedding,這層編碼單詞的語義信息更多一些。

也就是說,ELMO的預訓練過程不僅僅學會單詞的Word Embedding,還學會了一個雙層雙向的LSTM網絡結構,而這兩者後面都有用。

上面介紹的是ELMO的第一階段:預訓練階段。那麼預訓練好網絡結構後,如何給下游任務使用呢?上圖展示了下游任務的使用過程,比如我們的下游任務仍然是QA問題:

  1. 此時對於問句X,我們可以先將句子X作爲預訓練好的ELMO網絡的輸入,這樣句子X中每個單詞在ELMO網絡中都能獲得對應的三個Embedding;
  2. 之後給予這三個Embedding中的每一個Embedding一個權重a,這個權重可以學習得來,根據各自權重累加求和,將三個Embedding整合成一個;
  3. 然後將整合後的這個Embedding作爲X句在自己任務的那個網絡結構中對應單詞的輸入,以此作爲補充的新特徵給下游任務使用。對於上圖所示下游任務QA中的回答句子Y來說也是如此處理。

因爲ELMO給下游提供的是每個單詞的特徵形式,所以這一類預訓練的方法被稱爲“Feature-based Pre-Training”。

前面我們提到靜態Word Embedding無法解決多義詞的問題,那麼ELMO引入上下文動態調整單詞的embedding後多義詞問題解決了嗎?解決了,而且比我們期待的解決得還要好。對於Glove訓練出的Word Embedding來說,多義詞比如play,根據它的embedding找出的最接近的其它單詞大多數集中在體育領域,這很明顯是因爲訓練數據中包含play的句子中體育領域的數量明顯佔優導致;而使用ELMO,根據上下文動態調整後的embedding不僅能夠找出對應的“演出”的相同語義的句子,而且還可以保證找出的句子中的play對應的詞性也是相同的,這是超出期待之處。之所以會這樣,是因爲我們上面提到過,第一層LSTM編碼了很多句法信息,這在這裏起到了重要作用。

ELMO有什麼值得改進的缺點呢

  • 首先,一個非常明顯的缺點在特徵抽取器選擇方面,ELMO使用了LSTM而不是新貴Transformer,Transformer是谷歌在17年做機器翻譯任務的“Attention is all you need”的論文中提出的,引起了相當大的反響,很多研究已經證明了Transformer提取特徵的能力是要遠強於LSTM的。如果ELMO採取Transformer作爲特徵提取器,那麼估計Bert的反響遠不如現在的這種火爆場面。
  • 另外一點,ELMO採取雙向拼接這種融合特徵的能力可能比Bert一體化的融合特徵方式弱,但是,這只是一種從道理推斷產生的懷疑,目前並沒有具體實驗說明這一點。

2.4 GPT

GPT是“Generative Pre-Training”的簡稱,從名字看其含義是指的生成式的預訓練。GPT也採用兩階段過程,第一個階段是利用語言模型進行預訓練,第二階段通過Fine-tuning的模式解決下游任務。

上圖展示了GPT的預訓練過程,其實和ELMO是類似的,主要不同在於兩點:

  • 首先,特徵抽取器不是用的RNN,而是用的Transformer,上面提到過它的特徵抽取能力要強於RNN,這個選擇很明顯是很明智的;
  • 其次,GPT的預訓練雖然仍然是以語言模型作爲目標任務,但是採用的是單向的語言模型,所謂“單向”的含義是指:語言模型訓練的任務目標是根據 [公式] 單詞的上下文去正確預測單詞 [公式][公式] 之前的單詞序列Context-before稱爲上文,之後的單詞序列Context-after稱爲下文。

如果對Transformer模型不太瞭解的,可以參考我寫的文章:Transformer

ELMO在做語言模型預訓練的時候,預測單詞 [公式] 同時使用了上文和下文,而GPT則只採用Context-before這個單詞的上文來進行預測,而拋開了下文。這個選擇現在看不是個太好的選擇,原因很簡單,它沒有把單詞的下文融合進來,這限制了其在更多應用場景的效果,比如閱讀理解這種任務,在做任務的時候是可以允許同時看到上文和下文一起做決策的。如果預訓練時候不把單詞的下文嵌入到Word Embedding中,是很喫虧的,白白丟掉了很多信息。

2.5 BERT

Bert採用和GPT完全相同的兩階段模型,首先是語言模型預訓練;其次是使用Fine-Tuning模式解決下游任務。和GPT的最主要不同在於在預訓練階段採用了類似ELMO的雙向語言模型,即雙向的Transformer,當然另外一點是語言模型的數據規模要比GPT大。所以這裏Bert的預訓練過程不必多講了。模型結構如下:

對比OpenAI GPT(Generative pre-trained transformer),BERT是雙向的Transformer block連接;就像單向rnn和雙向rnn的區別,直覺上來講效果會好一些。

對比ELMo,雖然都是“雙向”,但目標函數其實是不同的。ELMo是分別以[公式][公式] 作爲目標函數,獨立訓練處兩個representation然後拼接,而BERT則是以 [公式] 作爲目標函數訓練LM。

BERT預訓練模型分爲以下三個步驟:Embedding、Masked LM、Next Sentence Prediction

2.5.1 Embedding

這裏的Embedding由三種Embedding求和而成:

  • Token Embeddings是詞向量,第一個單詞是CLS標誌,可以用於之後的分類任務
  • Segment Embeddings用來區別兩種句子,因爲預訓練不光做LM還要做以兩個句子爲輸入的分類任務
  • Position Embeddings和之前文章中的Transformer不一樣,不是三角函數而是學習出來的

2.5.2 Masked LM

MLM可以理解爲完形填空,作者會隨機mask每一個句子中15%的詞,用其上下文來做預測,例如:my dog is hairy → my dog is [MASK]

此處將hairy進行了mask處理,然後採用非監督學習的方法預測mask位置的詞是什麼,但是該方法有一個問題,因爲是mask15%的詞,其數量已經很高了,這樣就會導致某些詞在fine-tuning階段從未見過,爲了解決這個問題,作者做了如下的處理:

80%是採用[mask],my dog is hairy → my dog is [MASK]

10%是隨機取一個詞來代替mask的詞,my dog is hairy -> my dog is apple

10%保持不變,my dog is hairy -> my dog is hairy

注意:這裏的10%是15%需要mask中的10%

那麼爲啥要以一定的概率使用隨機詞呢?這是因爲transformer要保持對每個輸入token分佈式的表徵,否則Transformer很可能會記住這個[MASK]就是"hairy"。至於使用隨機詞帶來的負面影響,文章中解釋說,所有其他的token(即非"hairy"的token)共享15%*10% = 1.5%的概率,其影響是可以忽略不計的。Transformer全局的可視,又增加了信息的獲取,但是不讓模型獲取全量信息。

2.5.3 Next Sentence Prediction

選擇一些句子對A與B,其中50%的數據B是A的下一條句子,剩餘50%的數據B是語料庫中隨機選擇的,學習其中的相關性,添加這樣的預訓練的目的是目前很多NLP的任務比如QA和NLI都需要理解兩個句子之間的關係,從而能讓預訓練的模型更好的適應這樣的任務。
個人理解:

  • Bert先是用Mask來提高視野範圍的信息獲取量,增加duplicate再隨機Mask,這樣跟RNN類方法依次訓練預測沒什麼區別了除了mask不同位置外;
  • 全局視野極大地降低了學習的難度,然後再用A+B/C來作爲樣本,這樣每條樣本都有50%的概率看到一半左右的噪聲;
  • 但直接學習Mask A+B/C是沒法學習的,因爲不知道哪些是噪聲,所以又加上next_sentence預測任務,與MLM同時進行訓練,這樣用next來輔助模型對噪聲/非噪聲的辨識,用MLM來完成語義的大部分的學習。

3. BERT的評價

總結下BERT的主要貢獻:

  • 引入了Masked LM,使用雙向LM做模型預訓練。
  • 爲預訓練引入了新目標NSP,它可以學習句子與句子間的關係。
  • 進一步驗證了更大的模型效果更好: 12 --> 24 層。
  • 爲下游任務引入了很通用的求解框架,不再爲任務做模型定製。
  • 刷新了多項NLP任務的記錄,引爆了NLP無監督預訓練技術。

BERT優點

  • Transformer Encoder因爲有Self-attention機制,因此BERT自帶雙向功能。
  • 因爲雙向功能以及多層Self-attention機制的影響,使得BERT必須使用Cloze版的語言模型Masked-LM來完成token級別的預訓練。
  • 爲了獲取比詞更高級別的句子級別的語義表徵,BERT加入了Next Sentence Prediction來和Masked-LM一起做聯合訓練。
  • 爲了適配多任務下的遷移學習,BERT設計了更通用的輸入層和輸出層。
  • 微調成本小。

BERT缺點

  • task1的隨機遮擋策略略顯粗獷,推薦閱讀《Data Nosing As Smoothing In Neural Network Language Models》。
  • [MASK]標記在實際預測中不會出現,訓練時用過多[MASK]影響模型表現。每個batch只有15%的token被預測,所以BERT收斂得比left-to-right模型要慢(它們會預測每個token)。
  • BERT對硬件資源的消耗巨大(大模型需要16個tpu,歷時四天;更大的模型需要64個tpu,歷時四天。

評價

Bert是NLP裏裏程碑式的工作,對於後面NLP的研究和工業應用會產生長久的影響,這點毫無疑問。但是從上文介紹也可以看出,從模型或者方法角度看,Bert借鑑了ELMO,GPT及CBOW,主要提出了Masked 語言模型及Next Sentence Prediction,但是這裏Next Sentence Prediction基本不影響大局,而Masked LM明顯借鑑了CBOW的思想。所以說Bert的模型沒什麼大的創新,更像最近幾年NLP重要進展的集大成者,這點如果你看懂了上文估計也沒有太大異議,如果你有大的異議,槓精這個大帽子我隨時準備戴給你。如果歸納一下這些進展就是:

  • 首先是兩階段模型,第一階段雙向語言模型預訓練,這裏注意要用雙向而不是單向,第二階段採用具體任務Fine-tuning或者做特徵集成;
  • 第二是特徵抽取要用Transformer作爲特徵提取器而不是RNN或者CNN;
  • 第三,雙向語言模型可以採取CBOW的方法去做(當然我覺得這個是個細節問題,不算太關鍵,前兩個因素比較關鍵)。

Bert最大的亮點在於效果好及普適性強,幾乎所有NLP任務都可以套用Bert這種兩階段解決思路,而且效果應該會有明顯提升。可以預見的是,未來一段時間在NLP應用領域,Transformer將佔據主導地位,而且這種兩階段預訓練方法也會主導各種應用。

4. 代碼實現

bert中文分類實踐

機器學習通俗易懂系列文章

5. 參考文獻


作者:@mantchs

GitHub:https://github.com/NLP-LOVE/ML-NLP

歡迎大家加入討論!共同完善此項目!羣號:【541954936】NLP面試學習羣

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