論文鏈接:https://arxiv.org/abs/1810.04805
tensorflow版本代碼鏈接:https://github.com/google-research/bert
pytorch版本代碼鏈接:https://github.com/codertimo/BERT-pytorch
導讀
這篇論文由谷歌團隊發表於2018年的NAACL上《BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding》,目前引用量超 3800 次。Bert 取名來自 Bidirectional Encoder Representations from Transformers,大致可以瞭解到他採用的是雙向的 Transformer 的 Encoder 結構。
因此,閱讀論文時我們可以關注下 Bert 模型的兩個點:
1.利用 Encoder 完成預訓練後如何配合下游任務?
2.預訓練過程的雙向是類似 ELMo 的雙向嗎?如果不是的話,怎麼去防止數據泄漏?
1、引言
通過預訓練語言模型可以顯著提高 NLP 下游任務,包括 NER、QA、知識推理等。目前的預訓練有兩種策略:feature-based 和 fine-tuning,對應着我們之前介紹過兩個預訓練模型:ELMo 和 GPT。基於 feature-based 的 ELMo 是針對指定任務進行預訓練;而基於 fine-tuning 的 GPT 設計的是一個通用架構,並針對下游任務進行微調,兩方法都是使用單向的語言模型來學習一般的語言表示。
但是谷歌的同學認爲,預訓練的潛力遠遠不應該只有這些,特別是對於 fine-tuning 來說。限制模型潛力的主要原因在於現有模型使用的都是單向的語言模型,無法充分了解到單詞所在的上下文結構(試想:我們想了解一個單詞的含義,其實是會結合上下文來判斷,而不是隻結合單詞的上文)。
針對這一痛點:谷歌的同學提出了新的預訓練方法 BERT。BERT 受完形填空(cloze task)的啓發,通過使用 “Masked Language Model” 的預訓練目標來緩解單向語言模型的約束。
首先 “Masked Language Model” 會隨機屏蔽(masked)一些單詞,然後讓模型根據上下文來預測被遮擋的單詞。與 ELMo 不同的是,BERT 是真正的結合上下文進行訓練,而 ELMo 只是左向和右向分別訓練。
除了 “Masked Language Model” 外,谷歌的同學還提出了 “next sentence prediction” 的任務預訓練文本對。將 token-level 提升到 sentence-level,以應用不同種類的下游任務。
2、BERT模型
BERT 和之前的模型類似都採用兩階段的步驟:pre-training 和 fine-tuning。pre-training 階段,BERT 在未標記的數據上進行無監督學習;而 fine-tuning 階段,BERT 首先利用預訓練得到的參數初始化模型,然後利用下游任務標記好的數據進行有監督學習,並對所有參數進行微調。所有下游任務都有單獨的 fine-tuning 模型,即使是使用同樣的預訓練參數。下圖是對 BERT 的一個概覽:
2.1、模型架構
BERT 是由多層雙向的 Transformer Encoder 結構組成,區別於 GPT 的單向的 Transformer Decoder 架構。
谷歌的同學在論文中提供了兩個不同規模的 BERT:BERT Base 和 BERT Large。前者有 12 個隱藏層,768 個隱單元,每個Multi-head Attention 中有 12 個 Attention,共 1.1 億參數,主要是爲了與 OpenAI 比較性能;而後者有 24 個隱藏層,1024 個隱單元,每個 Multi-head Attention 中有 16 個Attention,共 3.4 億參數,主要是用來秀肌肉的。
從創新的角度來看,BERT其實並沒有過多的結構方面的創新點,其和GPT一樣均是採用的transformer的結構,相對於GPT來說,其是雙向結構的,而GPT是單向的,如下圖所示:
ELMo:將上下文當作特徵,但是無監督的語料和我們真實的語料還是有區別的,不一定符合我們特定的任務,是一種雙向的特徵提取。
OpenAI GPT就做了一個改進,也是通過transformer學習出來一個語言模型,不是固定的,通過任務 fine-tuning,用transfomer代替ELMo的LSTM。OpenAI GPT其實就是缺少了encoder的transformer。當然也沒了encoder與decoder之間的attention。OpenAI GPT雖然可以進行fine-tuning,但是有些特殊任務與pre-training輸入有出入,單個句子與兩個句子不一致的情況,很難解決,還有就是decoder只能看到前面的信息。
其次BERT在多方面的NLP任務變現來看效果都較好,具備較強的泛化能力,對於特定的任務只需要添加一個輸出層來進行fine-tuning即可。
總結
2.2、輸入
爲了能應對下游任務,BERT 給出了 sentence-level 級別的 Representation,包括句子和句子對。
在 BERT 中 sequence 並不一定是一個句子,也有可能是任意的一段連續的文本;而句子對主要是因爲類似 QA 問題。
我們來看下 BERT 的輸入:
分爲三塊:Token Embeddings、Segment Embeddings 和 Position Embeddings。
Token Embeddings 採用的 WordPiece Embedding,共有 30000 個 token。每個 sequence 會以一個特殊的 classification token [CLS] 開始,同時這也會作爲分類任務的輸出;句子間會以 special token [SEP] 進行分割。
WordPiece Embedding:n-gram 字符級 Embedding,採用 BPE 雙字節編碼,可以將單詞拆分,比如 “loved” “loving” ”loves“ 會拆分成 “lov”,“ed”,“ing”,“es”。
Segment Embedding 也可以用來分割句子,但主要用來區分句子對。Embedding A 和 Embedding B 分別代表左右句子,如果是普通的句子就直接用 Embedding A。
Position Embedding 是用來給單詞定位的,學習出來的embedding向量。這與Transformer不同,Transformer中是預先設定好的值。。
BERT 最終的 input 是三種不同的 Embedding 直接相加。
2.3、預訓練Pre-training
BERT 採用兩種非監督任務來進行預訓練,一個是 token-level 級別的 Masked LM,一個是 sentence-level 級別的 Next Sentence Prediction。兩個任務同時訓練,所以 BERT 的損失函數是兩個任務的損失函數相加。
當我們在訓練語言模型時,有一個挑戰就是要定義一個預測目標,很多模型在一個序列中預測下一個單詞,
“The child came home from ___”
雙向的方法在這樣的任務中是有限制的,爲了克服這個問題,BERT 使用以下的兩個策略:
2.3.1、Masked LM
我們知道語言模型只能是單向的,即從左到右或者從右到左,而使用雙向的話會導致數據泄漏問題,即模型可以間接看到要預測的單詞。這也是爲什麼 ELMo 要採用兩個獨立的雙向模型的原因。
爲了解決這個問題,谷歌的同學提出了 Masked LM 的概念:隨機屏蔽一些 token 並通過上下文預測這些 token。這種況下就解決了雙向模型和數據泄漏的問題。在具體實驗過程中,BERT 會隨機屏蔽每個序列中的 15% 的 token,並用 [MASK] token 來代替。
但這樣會帶來一個新的問題:[MASK] token 不會出現在下游任務中。爲了緩解這種情況,谷歌的同學採用以下三種方式來代替 [MASK] token:
- 80% 的 [MASK] token 會繼續保持 [MASK];
- 10% 的 [MASK] token 會被隨機的一個單詞取代;
- 10% 的 [MASK] token 會保持原單詞不變(但是還是要預測)。
最終 Masked ML 的損失函數是隻由被 [MASK] 的部分來計算。
這樣做的目的主要是爲了告訴模型 [MASK] 是噪聲,以此來忽略標記的影響。
這樣就需要:
- 在 encoder 的輸出上添加一個分類層
- 用嵌入矩陣乘以輸出向量,將其轉換爲詞彙的維度
- 用 softmax 計算詞彙表中每個單詞的概率
BERT 的損失函數只考慮了 mask 的預測值,忽略了沒有掩蔽的字的預測。這樣的話,模型要比單向模型收斂得慢,不過結果的情境意識增加了。
2.3.2、Next Sentence Prediction
部分下游任務如問答(QA)、語言推理等都是建立在句子對的基礎上的,而語言模型只能捕捉 token-level 級別的關係,捕捉不了 sentence-level 級別的關係。
爲了解決這個問題,谷歌的同學訓練了一個 sentence-level 的分類任務。具體來說,假設有 A B 兩個句對,在訓練過程 50% 的訓練樣本 A 下句接的是 B 作爲正例;而剩下 50% 的訓練樣本 A 下句接的是隨機一個句子作爲負例。並且通過 classification token 連接 Softmax 輸出最後的預測概率。
雖然很簡單,但是在實際效果是非常好的。
爲了幫助模型區分開訓練中的兩個句子,輸入在進入模型之前要按以下方式進行處理:
- 在第一個句子的開頭插入 [CLS] 標記,在每個句子的末尾插入 [SEP] 標記。
- 將表示句子 A 或句子 B 的一個句子 embedding 添加到每個 token 上。
- 給每個 token 添加一個位置 embedding,來表示它在序列中的位置。
爲了預測第二個句子是否是第一個句子的後續句子,用下面幾個步驟來預測:
- 整個輸入序列輸入給 Transformer 模型
- 用一個簡單的分類層將 [CLS] 標記的輸出變換爲 2×1 形狀的向量
- 用 softmax 計算 IsNextSequence 的概率
在訓練 BERT 模型時,Masked LM 和 Next Sentence Prediction 是一起訓練的,目標就是要最小化兩種策略的組合損失函數。
2.4、微調Fine-tuning
預訓練好後我們看下 BERT 的 Fine-tuning 是怎麼實現的。
由於預訓練的 Transformer 已經完成了句子和句子對的 Representation,所以 BERT 的 Fine-tuning 非常簡單。
針對不同的下游任務,我們可以將具體的輸入和輸出是適配到 BERT 中,並且採用端到端的訓練去微調模型參數。BERT 可以用於各種NLP任務,只需在覈心模型中添加一個層,例如:
- 在分類任務中,例如情感分析等,只需要在 Transformer 的輸出之上加一個分類層
- 在問答任務(例如SQUAD v1.1)中,問答系統需要接收有關文本序列的 question,並且需要在序列中標記 answer。 可以使用 BERT 學習兩個標記 answer 開始和結尾的向量來訓練Q&A模型。
- 在命名實體識別(NER)中,系統需要接收文本序列,標記文本中的各種類型的實體(人員,組織,日期等)。 可以用 BERT 將每個 token 的輸出向量送到預測 NER 標籤的分類層。
如下圖所示:
- a b 是 sentence-level 級別的任務,類似句子分類,情感分析等等,輸入句子或句子對,在 [CLS] 位置接入 Softmax 輸出 Label;
- c 是 token-level 級別的任務,比如 QA 問題,輸入問題和段落,在 Paragraph 對應輸出的 hidden vector 後接上兩個 Softmax 層,分別訓練出 Span 的 Start index 和 End index(連續的 Span)作爲 Question 的答案;
- d 也是 token-level 級別的任務,比如命名實體識別問題,接上 Softmax 層即可輸出具體的分類。
3、實驗
下圖是與不同模型的對比情況
下圖是Masked LM與單向的LM的實驗對比情況
下圖爲不同Mask策略下的效果
4、結論
BERT 採用 Pre-training 和 Fine-tuning 兩階段訓練任務,在 Pre-training 階段使用多層雙向 Transformer 進行訓練,並採用 Masked LM 和 Next Sentence Prediction 兩種訓練任務解決 token-level 和 sentence-level 的問題,爲下游任務提供了一個通用的模型框架;在 Fine-tuning 階段會針對具體 NLP 任務進行微調以適應不同種類的任務需求,並通過端到端的訓練更新參數從而得到最終的模型。
BERT 是 NLP 領域中一個里程碑式的工作,並對後續 NLP 的研究工作產生了深遠影響。
5、思考
總結下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,歷時四天。
個人觀點:
-
個人並不認爲文章是模型的改進,更認可爲任務的設計改進。
-
論文作者只比較了有沒有task1的影響,並沒有針對task2對比試驗。提升是否來自好的預訓練任務設計沒有明說。
-
bert對nlp領域目前已有知識的有效“整合”,在硬件配置足夠的情況下能提高nlp多領域性能