谷歌BERT 學習

最近谷歌放了個大招,開源了他們最新的自然語言模型BERT,正好手頭有個文本分類的任務,打算拿來用用,特此記錄一下學習過程,如果錯誤,還望指正。
論文地址:https://arxiv.org/abs/1810.04805
開源github地址:https://github.com/google-research/bert

摘要

BERT(怎麼讀隨便),其實是Bidirectional Encoder Representations from Transformers的縮寫,屬於深度雙向預訓練模型,在模型的所有層的表示都依賴於左右兩個方向的上下文。這樣設計的結果就是在大規模預料上預訓練的BERT表示再加一層額外的輸出層便可以應用到很多任務中,並可以得到很好的效果,據論文說該模型在11種自然語言處理任務中都取得了目前最好的效果。(不得不佩服這種概念簡單但是實際效果屌炸的設計)

背景介紹

預訓練模型近幾年在自然語言處理領域逐漸得到廣泛關注,在很多任務中被驗證非常有效。目前在應用預訓練語言表示到下游任務(downstream tasks)中有兩種策略:1. 基於特徵,2. 基於fine-tuning;

  1. 基於特徵,例如ELMo,將預訓練好的representations作爲特徵輸入特定任務模型,訓練模型完成任務目標;
  2. 基於fine-tuning, Generative Pre-trained Transformer (OpenAI GPT) , 引入最少的特定任務參數,然後再下游任務中fine-tuning引入的參數;

BERT的提出感覺是在前人基礎上的集大成,之前GPT已經是基於transform的語言模型了,但只做了單向,BERT搞了雙向,增加了一些特殊的訓練方法,取得了很好的效果;

模型介紹

模型是一個多層雙向Transformer encoder, 基於《Attention is all you need》中的模型(在https://github.com/tensorflow/tensor2tensor中發佈,大神詳細介紹的博客:http://nlp.seas.harvard.edu/2018/04/03/attention.html )。
模型結果對比如下圖:

論文中的示意圖

模型輸入

模型的輸入可以是一個句子,也可以是a pair of 句子,如圖:
在這裏插入圖片描述
圖中的輸入爲一對句子,兩個句子用特殊分隔符[sep]隔開,每個輸入都是三個Embedding的疊加,同時對於分類任務來說,句子開頭還有一個表示類別的特殊embedding:[CLS]。

模型預訓練

並不是使用傳統的從左到右或者是從右到左語言模型進行預訓練,使用兩種新穎的無監督預測任務來進行BERT訓練。

Masked LM

爲了訓練深度雙向表示,我們直接將一些輸入token按一定的比例進行遮擋,然後預測這些被遮擋的tokens,這個過程就叫做“masked LM(MLM)”。
而BERT的訓練過程如下,
訓練數據生成器隨機選擇15%的tokens,例如選擇句子“my dog is hairy”中的"hairy", 並不總是將"hairy"替換爲[MASK], 進行如下處理:

  • 80%的時間進行[MASK] 替換,例如“my dog is hairy” -->“my dog is [MASK]”
  • 10%的時間隨機替換選擇的token, 例如"my dog is hairy" --> “my dog is apple”
  • 10%的時間保持選擇的token不變,例如“my dog is hairy” --> “my dog is hairy”; 目的是將表示向實際觀察到的token偏置;

上述過程有效解決了在fine-tuning過程中[MASK] token永遠不會被看到,從而使得預訓練與fine-tuning產生mismatch的問題;但也存在着收斂時間變長的固有問題(因爲每個batch只預測15%的token)
論文中的原理解釋:
Transformer encoder 並不知道之後會預測哪個word,也不知道輸入的哪個word被隨機替換了,因此會被強迫學習到每一個輸入token的上下文背景語義分佈。同時,由於隨機替換隻發生1.5%(10% of 15%),看起來也不會損害模型的語言理解能力。

Next Sentence Prediction

許多重要的下游任務,例如問答、自然語言推斷等都是基於對兩個句子關係的理解,同時使用語言模型又無法很好的捕捉。爲了訓練一個可以理解句子關係的模型,我們進行一個二值化的下一句子預測預訓練過程,訓練數據可以從任何一個大的文本集合中得到。
當我們選擇兩個句子A和B的時候,50%的時間B是真正的下一句子,50%的時間B是從集合中任意生成的一個句子,例如:
在這裏插入圖片描述
在 Next Sentence Prediction目標上,論文給出的結果最終的預訓練模型可以達到97%~98%的精確率(有點殘暴啊)。

上手使用

真正上手使用,需要經過兩個階段,分別是在大語料上的預訓練階段(與具體任務無關,語料越大越好)與具體應用的fine-tuning階段;

預訓練階段

準備好大的文本集合,將文本集合分爲A,B兩部分,爲Next Sentence Prediction目標準備數據;
由於同時訓練兩個任務目標,因此有兩部分損失函數:

total_loss = masked_lm_loss + next_sentence_loss

關於損失函數的定義,bert模型只使用了transform模型的encoder部分,它的encoder部分輸出爲每一個item的hidden_vector, 而對於masked_lm_loss,只使用對應mask掉的item hidden_vector過softmax 進行預測,同時限制了再一個訓練樣例中最多mask掉item的數量。
這裏需要注意一個特殊的"[cls]",我的理解是在訓練階段,每個訓練樣例輸入開頭的都是這個特殊item,對應在輸入的hidden_vector會學到一個包括整個序列的一些信息,只是最後這個特殊的item對應的hidden_vector輸出經過fine-tuning可以用來做分類任務,且效果很好,論文中把這個特殊向量叫做一個sequence的pooled representation。
補充一點,sequence難免長度不一樣,做訓練需要特殊處理,採用的方式是用0值padding成一樣長的隊列,對不padding部分使用一個mask的數據進行記錄,在訓練時候attention部分同樣有一個mask,進行對應處理。

fine-tuning階段

fine-tuning階段就看具體任務是做什麼了,我的任務是文本分類,那就對"[cls]"對應的輸出向量pooled representation 再加一個分類模型,二分類還是多分類看需求,在具體任務的訓練數據上繼續進行訓練,基本模式就是在最大化對數似然的過程中,fine-tine bert本身的參數與我們根據具體任務新加的參數。

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