1. 程式人生 > >一文徹底搞懂BERT

一文徹底搞懂BERT

一文徹底搞懂BERT 

一、什麼是BERT?

沒錯下圖中的小黃人就是文字的主角Bert ,而紅色的小紅人你應該也聽過,他就是ELMo。2018年釋出的BERT 是一個 NLP 任務的里程碑式模型,它的釋出勢必會帶來一個 NLP 的新時代。BERT 是一個演算法模型,它的出現打破了大量的自然語言處理任務的記錄。在 BERT 的論文釋出不久後,Google 的研發團隊還開放了該模型的程式碼,並提供了一些在大量資料集上預訓練好的演算法模型下載方式。Goole 開源這個模型,並提供預訓練好的模型,這使得所有人都可以通過它來構建一個涉及NLP 的演算法模型,節約了大量訓練語言模型所需的時間,精力,知識和資源。BERT模型的全稱是:BERT(Bidirectional Encoder Representations from Transformers)。從名字中可以看出,BERT模型的目標是利用大規模無標註語料訓練、獲得文字的包含豐富語義資訊的Representation。

 

二、Bert模型原理

  • BERT模型簡介

BERT BASE: 與OpenAI Transformer 的尺寸相當,以便比較效能。

BERT LARGE: 一個非常龐大的模型,是原文介紹的最先進的結果。

BERT的基礎整合單元是Transformer的Encoder。關於Transformer的介紹可以閱讀Paper--Attention is All You Need。

2 個 BERT 的模型都有一個很大的編碼器層數,(論文裡面將此稱為 Transformer Blocks) - 基礎版本就有 12 層,進階版本有 24 層。同時它也有很大的前饋神經網路 ( 768 和 1024 個Hidden units),還有很多 Attention heads(12和16 個)。這超過了 Transformer 論文中的參考配置引數(6 個編碼器層,512 個隱藏層單元,和 8 個注意頭)。在我們平時實際使用bert的過程中一般只會使用Bert-base,因為Bert模型的太大了,龐大的引數一般人的電腦配置難以駕馭,當然有TPU的土豪除外... 

  •  模型的輸入和輸出

BERT模型的主要輸入是文字中各個詞的原始詞向量,該向量既可以隨機初始化,也可以利用Word2Vector等演算法進行預訓練以作為初始值;輸出是文字中各個詞融合了全文語義資訊後的向量表

 

從上圖中可以看出,BERT模型的輸入具體分為三種資訊:

Token Embeddings:是每個詞的詞向量,第一個單詞是[CLS] Token,其取值在模型訓練過程中自動學習,用於刻畫文字的全域性語義資訊,可以用於之後的分類任務。[SEP] Token是用來分割輸入的兩條句子。

Segment Embeddings:用來區別兩種句子(是否是正常順序的兩個句子),因為Bert預訓練不光做MLM還要做以兩個句子為輸入的分類任務。

Position Embeddings:由於出現在文字不同位置的詞所攜帶的語義資訊存在差異(比如:“我愛你”和“你愛我”),因此,BERT模型對不同位置的詞分別附加一個不同的向量以作區分。

特別地,在目前的BERT模型中,文章作者還將英文詞彙作進一步切割,劃分為更細粒度的語義單位(WordPiece),例如:將playing分割為play和ing;此外,對於中文,目前作者尚未對輸入文字進行分詞,而是直接將單個字作為構成文字的基本單位。輸出是文字中各個詞融合了全文語義資訊後的向量表示。

  • 模型的預訓練任務

1) Task 1#: Masked Language Model

為了達到真正的bidirectional的LM的效果,作者創新性的提出了Masked LM,如下圖所示,簡單來說就是將句子中的一部分詞mask掉,然後讓模型去預測被mask掉的詞(可以理解為我們大家初中都做過的完形填空)。這樣有個缺點是在預訓練的過程中把一些詞mask起來,但是未來的fine tuning過程中的輸入是沒有mask的,這樣模型有可能沒見過這些詞。這個量積累下來還是很大的。在訓練過程中作者隨機mask 15%的token,而不是把像CBOW一樣把每個詞都預測一遍。最終的損失函式只計算被mask掉那個token(其實這樣也會導致一個問題就是訓練的效率會比較低,因為每次反向傳播只能計算15%的詞)。Mask具體如何做也是有技巧的,前面說過如果全部用標記[MASK]代替會影響模型的fine tuning,所以作者mask的時候10%的單詞會被隨機替代成其他單詞,還有10%的單詞保持不變,剩下80%才被替換為[MASK] token。要注意的是Masked LM預訓練階段模型是不知道真正被mask的是哪個詞,所以模型每個詞都要關注。因為序列長度太大(512)會影響訓練速度,所以90%的steps都用seq_len=128訓練,餘下的10%步數訓練512長度的輸入。 

 

2) Task 2#: Next Sentence Prediction

Next Sentence Prediction的任務可以解釋為:給定一篇文章中的兩句話,判斷第二句話在文字中是否緊跟在第一句話之後,目的是讓模型理解兩個句子之間的聯絡,如下圖所示。將一篇文章的各段打亂,讓我們通過重新排序把原文還原出來,這其實需要我們對全文大意有充分、準確的理解。Next Sentence Prediction任務實際上就是段落重排序的簡化版:只考慮兩句話,判斷是否是一篇文章中的前後句。在實際預訓練過程中,作者從文字語料庫中隨機選擇50%正確語句對和50%錯誤語句對進行訓練,與Masked LM任務相結合,讓模型能夠結合上下文預料更準確地表示每個詞和句子的語義資訊。

 

  • 模型Fine tuning

Bert的fine-tuning之前對模型的修改非常簡單,如果做Sentence pair classification 任務,那麼就兩句話一起輸入例如:[CLS]我喜歡吃蘋果[SEP]你喜歡吃梨子,最後取第一個token [CLS]的輸出表示,餵給一個softmax層得到分類結果輸出。Single sentence classification 就更簡單,也是輸入一句話,然後取第一個token [CLS]的輸出來進行分類。對於Q&A問題著同時輸入[CLS]Question[SEP]Answer,然後取輸出的Answer中Start和End之間即為答案。對於Single sentence tagging tasks(NER),取所有token的最後層transformer輸出,餵給softmax層做分類。總之不同型別的任務需要對模型做不同的修改,但是修改都是非常簡單的,最多加一層神經網路即可。如下圖所示:

 

四、總結

Bert的優點:BERT是截至2018年10月的最新state of the art模型,通過預訓練和精調橫掃了11項NLP任務,這首先就是最大的優點了。而且它還用的是Transformer,也就是相對基於RNN的模型Bert更加高效、能捕捉更長距離的依賴。對比起之前的預訓練模型,它捕捉到的是真正意義上的bidirectional context資訊。

Bert的缺點:主要就是MLM預訓練時的mask問題,[MASK]標記在實際預測中不會出現,訓練時用過多[MASK]會影響模型在fine tuning的下游任務上帝的表現;每個batch只有15%的token被預測,所以BERT收斂得比left-to-right模型要慢(它們會預測每個token)。全文讀下來你會發現其實Bert也沒有我們想象中的那麼神奇,但是實際中Bert卻是如此的強大,其中重要的原因也是Google擁有龐大的語料庫(錢)來進行訓練,當然TPU(錢)也是必不可少的。

 

論文地址:https://arxiv.org/pdf/1810.04805

程式碼地址(TensorFlow和Pytorch兩個版本):

https://github.com/google-research/bert

https://github.com/huggingface/pytorch-pretrained-BERT

&n