BERT的全稱是Bidirectional Encoder Representation from Transformers,是Google2018年提出的預訓練模型,即雙向Transformer的Encoder,由於decoder是不能獲要預測的信息的。模型的主要創新點都在pre-train方法上,即用了Masked LM和Next Sentence Prediction兩種方法分別捕捉詞語和句子級別的representation。git
Bert最近很火,應該是最近最火爆的AI進展,網上的評價很高,那麼Bert值得這麼高的評價嗎?我我的判斷是值得。那爲何會有這麼高的評價呢?是由於它有重大的理論或者模型創新嗎?其實並無,從模型創新角度看通常,創新不算大。可是架不住效果太好了,基本刷新了不少NLP的任務的最好性能,有些任務還被刷爆了,這個纔是關鍵。另一點是Bert具有普遍的通用性,就是說絕大部分NLP任務均可以採用相似的兩階段模式直接去提高效果,這個第二關鍵。客觀的說,把Bert當作最近兩年NLP重大進展的集大成者更符合事實。github
自從深度學習火起來後,預訓練過程就是作圖像或者視頻領域的一種比較常規的作法,有比較長的歷史了,並且這種作法頗有效,能明顯促進應用的效果。面試
那麼圖像領域怎麼作預訓練呢,上圖展現了這個過程,網絡
咱們設計好網絡結構之後,對於圖像來講通常是CNN的多層疊加網絡結構,能夠先用某個訓練集合好比訓練集合A或者訓練集合B對這個網絡進行預先訓練,在A任務上或者B任務上學會網絡參數,而後存起來以備後用。app
假設咱們面臨第三個任務C,網絡結構採起相同的網絡結構,在比較淺的幾層CNN結構,網絡參數初始化的時候能夠加載A任務或者B任務學習好的參數,其它CNN高層參數仍然隨機初始化。框架
以後咱們用C任務的訓練數據來訓練網絡,此時有兩種作法:機器學習
一種是淺層加載的參數在訓練C任務過程當中不動,這種方法被稱爲「Frozen」;分佈式
另外一種是底層網絡參數儘管被初始化了,在C任務訓練過程當中仍然隨着訓練的進程不斷改變,這種通常叫「Fine-Tuning」,顧名思義,就是更好地把參數進行調整使得更適應當前的C任務。函數
通常圖像或者視頻領域要作預訓練通常都這麼作。這樣作的優勢是:若是手頭任務C的訓練集合數據量較少的話,利用預訓練出來的參數來訓練任務C,加個預訓練過程也能極大加快任務訓練的收斂速度,因此這種預訓練方式是老小皆宜的解決方案,另外療效又好,因此在作圖像處理領域很快就流行開來。工具
爲何預訓練可行
對於層級的CNN結構來講,不一樣層級的神經元學習到了不一樣類型的圖像特徵,由底向上特徵造成層級結構,因此預訓練好的網絡參數,尤爲是底層的網絡參數抽取出特徵跟具體任務越無關,越具有任務的通用性,因此這是爲什麼通常用底層預訓練好的參數初始化新任務網絡參數的緣由。而高層特徵跟任務關聯較大,實際能夠不用使用,或者採用Fine-tuning用新數據集合清洗掉高層無關的特徵抽取器。
神經網絡語言模型(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提供了一種簡潔優雅的解決方案。
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:也就是說,ELMO的預訓練過程不只僅學會單詞的Word Embedding,還學會了一個雙層雙向的LSTM網絡結構,而這二者後面都有用。
上面介紹的是ELMO的第一階段:預訓練階段。那麼預訓練好網絡結構後,如何給下游任務使用呢?上圖展現了下游任務的使用過程,好比咱們的下游任務仍然是QA問題:
由於ELMO給下游提供的是每一個單詞的特徵形式,因此這一類預訓練的方法被稱爲「Feature-based Pre-Training」。
前面咱們提到靜態Word Embedding沒法解決多義詞的問題,那麼ELMO引入上下文動態調整單詞的embedding後多義詞問題解決了嗎?解決了,並且比咱們期待的解決得還要好。對於Glove訓練出的Word Embedding來講,多義詞好比play,根據它的embedding找出的最接近的其它單詞大多數集中在體育領域,這很明顯是由於訓練數據中包含play的句子中體育領域的數量明顯佔優致使;而使用ELMO,根據上下文動態調整後的embedding不只可以找出對應的「演出」的相同語義的句子,並且還能夠保證找出的句子中的play對應的詞性也是相同的,這是超出期待之處。之因此會這樣,是由於咱們上面提到過,第一層LSTM編碼了不少句法信息,這在這裏起到了重要做用。
ELMO有什麼值得改進的缺點呢?
GPT是「Generative Pre-Training」的簡稱,從名字看其含義是指的生成式的預訓練。GPT也採用兩階段過程,第一個階段是利用語言模型進行預訓練,第二階段經過Fine-tuning的模式解決下游任務。
上圖展現了GPT的預訓練過程,其實和ELMO是相似的,主要不一樣在於兩點:
若是對Transformer模型不太瞭解的,能夠參考我寫的文章:Transformer
ELMO在作語言模型預訓練的時候,預測單詞
同時使用了上文和下文,而GPT則只採用Context-before這個單詞的上文來進行預測,而拋開了下文。這個選擇如今看不是個太好的選擇,緣由很簡單,它沒有把單詞的下文融合進來,這限制了其在更多應用場景的效果,好比閱讀理解這種任務,在作任務的時候是能夠容許同時看到上文和下文一塊兒作決策的。若是預訓練時候不把單詞的下文嵌入到Word Embedding中,是很吃虧的,白白丟掉了不少信息。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
這裏的Embedding由三種Embedding求和而成:
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全局的可視,又增長了信息的獲取,可是不讓模型獲取全量信息。
選擇一些句子對A與B,其中50%的數據B是A的下一條句子,剩餘50%的數據B是語料庫中隨機選擇的,學習其中的相關性,添加這樣的預訓練的目的是目前不少NLP的任務好比QA和NLI都須要理解兩個句子之間的關係,從而能讓預訓練的模型更好的適應這樣的任務。 我的理解:
總結下BERT的主要貢獻:
BERT優勢
BERT缺點
評價
Bert是NLP裏裏程碑式的工做,對於後面NLP的研究和工業應用會產生長久的影響,這點毫無疑問。可是從上文介紹也能夠看出,從模型或者方法角度看,Bert借鑑了ELMO,GPT及CBOW,主要提出了Masked 語言模型及Next Sentence Prediction,可是這裏Next Sentence Prediction基本不影響大局,而Masked LM明顯借鑑了CBOW的思想。因此說Bert的模型沒什麼大的創新,更像最近幾年NLP重要進展的集大成者,這點若是你看懂了上文估計也沒有太大異議,若是你有大的異議,槓精這個大帽子我隨時準備戴給你。若是概括一下這些進展就是:
Bert最大的亮點在於效果好及普適性強,幾乎全部NLP任務均可以套用Bert這種兩階段解決思路,並且效果應該會有明顯提高。能夠預見的是,將來一段時間在NLP應用領域,Transformer將佔據主導地位,並且這種兩階段預訓練方法也會主導各類應用。
做者:@mantchs
GitHub:github.com/NLP-LOVE/ML…