本文主要用于記錄谷歌發(fā)表于2018年的一篇論文。該論文提出的BERT模型被各地學(xué)者媒體美譽為NLP新一代大殺器。本筆記主要為方便初學(xué)者快速入門,以及自我回顧。
論文鏈接:https://arxiv.org/pdf/1810.04805.pdf
基本目錄如下:
- 摘要
- 核心思想
- 總結(jié)
------------------第一菇 - 摘要------------------
1.1 論文摘要
本文作者推出了一套新的語言表達模型BERT,全稱為Bidirectional Encoder Representations from Transformers。與近年來提出的語言模型不一樣的地方在于,BERT不再僅僅是只關(guān)注一個詞前文或后文的信息,而是整個模型的所有層都去關(guān)注其整個上下文的語境信息。實驗結(jié)果證明,使用預(yù)訓(xùn)練過的BERT模型,僅僅在后面再包一層輸出層,并對其進行微調(diào)訓(xùn)練,就可以取得很不錯的結(jié)果。具體有多不錯,那就是刷爆了NLP領(lǐng)域的11大任務(wù),甚至有幾項任務(wù)的準確率已經(jīng)超過了人類。
------------------第二菇 - 核心思想------------------
2.1 論文模型背景
其實BERT模型本身的提出,說實話,并不是什么劃時代的產(chǎn)物,只不過他的效果直接刷爆了NLP的各項任務(wù)(谷歌家強大的計算資源也是原因之一,想復(fù)現(xiàn)這篇論文難度也是很大),看起來比較震撼。所以,該篇論文之所以有那么高的評價,倒不是模型本身有多出色,或者預(yù)訓(xùn)練方法有多標新立異,我個人更愿意稱其為近年NLP領(lǐng)域突破的集大成者(確實是一個里程碑)。因此,為了能更好的理解這篇文章所表達的內(nèi)涵,光是看這一篇文章是遠遠不夠的,所以,不同于以往直接深入文章核心,這里先隨著論文一起聊聊本文的模型背景。
在NLP領(lǐng)域,語言模型的預(yù)訓(xùn)練早已被證明是提高下游模型表現(xiàn)的不二選擇,從目前提出的預(yù)訓(xùn)練方法來看,主要可以分為兩個類型如下,
1)基于特征(Feature-Based)主要的代表有ELMO,用做任務(wù)的模型來學(xué)習(xí)提前預(yù)訓(xùn)練好的語言模型內(nèi)部隱狀態(tài)的組合參數(shù)。(詳情可參見我的另一篇論文筆記來講ELMO的)。
2)微調(diào)(Fine-Tuning)主要的代表有OpenAI GPT,用做任務(wù)的數(shù)據(jù)來微調(diào)已經(jīng)訓(xùn)練好的語言模型。
但是以上的預(yù)訓(xùn)練都存在一個問題,即在預(yù)訓(xùn)練的時候,僅僅考慮了文本的單向順序,不論是從左到右,還是從右到左,始終不能很好的解決想同時學(xué)習(xí)這個詞匯上下文的信息的問題(ELMO那篇其實也是Bi-directional LM,但確實沒有做到同時學(xué)習(xí)這點,畢竟只是把從左到右和從右到左拼接在一起。。。暫時不知道作者這么說的意思具體指什么,我目前就單純的理解為作者提出的這個思想核心在于“同時”,而其他NLP的Bi依然停留在分別訓(xùn)練再concact的層面,并沒有真正的利用單詞的上下文來同時預(yù)測這個單詞,其實也就是沒有脫離傳統(tǒng)語言模型的套路)。因此本文的最大的創(chuàng)新點也就在此了,提出了一種新的預(yù)訓(xùn)練語言模型的方法(masked language model)。除此之外,本論文的其他幾大貢獻為,
1)用實驗證實利用完整預(yù)訓(xùn)練的語言模型,能大大減輕業(yè)務(wù)端的網(wǎng)絡(luò)結(jié)構(gòu)的復(fù)雜度,上一些輕型的模型就能夠取得很好的效果,甚至超過那些專為業(yè)務(wù)設(shè)計的復(fù)雜網(wǎng)絡(luò)結(jié)構(gòu)。
2)作者預(yù)訓(xùn)練的這一套BERT模型,刷爆了各大任務(wù)指標,希望這一套模型能成為NLP領(lǐng)域的ResNet,開創(chuàng)NLP新時代!
2.2 論文模型結(jié)構(gòu)
論文的模型倒沒有什么特別的創(chuàng)新,主要的特征提取層還是Transformer(改用RNN體系當(dāng)然也可以)那一套(不熟悉的同學(xué)可以看我另一篇筆記,里面有詳細的介紹),這里直接貼一張原論文的圖,想必大家應(yīng)該也能看懂。(原論文對于BERT還有BASE和LARGE的區(qū)別,BASE主要是為了對標比較OPENAI GPT)

(PS. 看模型圖,這個真的是做到了上下文信息一起進去了,所有的token都有一個指向每一個Transformer的箭頭)
以及順便得再提一下,模型的輸入包括三個部分,分別為
1)基于詞級別的詞向量(分隔以后)- 針對每一個單詞的embedding
2)基于位置的向量 - 告訴模型每一個單詞在一個句子中的位置信息
3)每一個句子的向量(分隔以后)- 告訴模型這個單詞是來自第一個句子還是第二個句子的(訓(xùn)練方法二需要)
具體可以見下圖,應(yīng)該說是很清楚了,

2.3 論文預(yù)訓(xùn)練方法 - Masked LM
接下來重點解析一下作者的預(yù)訓(xùn)練方法。為了訓(xùn)練一個深度雙向表示模型,作者提出了一種屏蔽一句話中的部分詞的訓(xùn)練方法,然后讓模型來預(yù)測屏蔽的那個詞(同比于CBOW,就是根據(jù)這個詞的上下文,去預(yù)測每一個詞,損失函數(shù)由所有詞的loss組成(cross-entropy),而本文的loss只來源于那些被屏蔽的詞)。
這里我簡單聊一下我對這種訓(xùn)練方法的理解。其實本質(zhì)上來講,這種訓(xùn)練方法來源于深度學(xué)習(xí)中很主流的自編碼(AutoEncoder)的方法論,該方法論的核心就是給定一個輸入,經(jīng)過若干層的特征提取變化,最后的輸出還是輸入本身(比如圖像領(lǐng)域,輸入一張圖片,輸出仍是這一張圖片,其作用就是更好的提取這張圖片的特征表達,是一種非監(jiān)督的學(xué)習(xí)方法)。當(dāng)然為了讓模型更加robust,有一種升級的自編碼器就是加入一定的噪音(denoising-AutoEncoder),模型的訓(xùn)練目標依舊是要復(fù)原輸入。再回過來看谷歌提出的這一種訓(xùn)練方法,其實就是輸入一句話,我們要復(fù)原這一句話,而其中的mask就是我們加的隨機的噪音~真的是很巧妙的遷移,解決了同時利用上下文信息的痛點~??!
在作者的實驗設(shè)置中,大約15%的詞被隨機屏蔽。但是這樣的訓(xùn)練方法有兩個缺陷。
1)預(yù)訓(xùn)練階段與微調(diào)階段不一致,因為微調(diào)階段是不會有【MASK】存在的,所以考慮到這一層面,作者也不總是將隨機選擇的詞屏蔽為MASK,主要的操作如下描述(相信大家一定看的懂,就不翻譯了)

總結(jié)來講就是,模型需要完成的任務(wù)有:
1)通過 MASK -> 自己(相對比較難的任務(wù))
2)通過自己 -> 自己(相對簡單的任務(wù))
3)通過其他 -> 自己(很難的任務(wù))
并且作者還強調(diào)了一下,隨機屏蔽的這一點量,似乎并不會影響文本的語言理解(但是必須強調(diào),該訓(xùn)練方法訓(xùn)練出的其實已經(jīng)不是語言模型了,因為他無法用來生成一句話)。
2)正因為從理論上來講每一次都只有15%的詞是來被訓(xùn)練到的,所以,需要更多預(yù)訓(xùn)練的計算與時間成本。而作者也在后文實驗證實了該方法確實收斂的較慢,但是效果好呀?。▽τ谶@種,只要做好一次,就能一勞永逸的預(yù)訓(xùn)練模型,時間和計算成本的增加對谷歌來說確實是小case哈哈)
關(guān)于該預(yù)訓(xùn)練方法的圖解如下【1】

這里得補充說明一點,大家可以注意到,圖中的輸入不僅僅有一句話中的所有單詞,還有一個特殊的標記,[CLS]~關(guān)于這個標記,我覺得可以簡單理解為,該標記經(jīng)過特征提取層以后的得到的向量,是能夠代表整一個句子的(因為后面的每一個詞都會有一個自己對應(yīng)的向量,而很多下游任務(wù)都是希望得到句子的向量表達,所以要么采用暴力的方法,把所有的詞匯對應(yīng)的向量做一個pooling,要么就如谷歌實驗設(shè)計的一樣,加入一個新的標記,讓模型對于這個標記去學(xué)會整個句子的表達,用于下游的一系列文本分類任務(wù)等,看下面的圖示也應(yīng)該能很好理解了,圖解也是直接用了[CLS]的輸出,并不是誤畫漏畫其他的單詞)。
2.3 論文預(yù)訓(xùn)練方法 - Next Sentence Prediction
這個預(yù)訓(xùn)練方法就比較好直觀的理解了,該預(yù)訓(xùn)練方法主要是為了增加模型對句子間關(guān)系的理解能力(即Bert不僅僅解決一個句子內(nèi)的關(guān)系,他還解決句子間的關(guān)系)。因此作者設(shè)計了一種二分類預(yù)訓(xùn)練方法(注意這里是嚴格的句子順序,如果輸入是s1-s2,那么順序不可顛倒,如果變?yōu)閟2-s1,那就是錯誤的),讓模型來判斷,B句是不是A句的后面一句。其中,作者的樣本集為平均分布,即一半是正確的,一半是錯誤的。最終,模型能達到97%-98%的準確率。關(guān)于該預(yù)訓(xùn)練方法的圖解如下【1】。

補充一下,除了[CLS]這個標記,谷歌還另外設(shè)計了一個標記[SEP],這個標記就比較簡單了,就是單純的用來區(qū)分倆個句子的。而最終的loss也是來源于兩種訓(xùn)練方法疊加的一個loss。
2.4 論文預(yù)訓(xùn)練與微調(diào)的過程
與傳統(tǒng)的LM模型訓(xùn)練過程相似,BERT的訓(xùn)練也遵循基本的套路(大家可參見ULMFiT,我的另一篇筆記也有詳實的介紹)。作者強調(diào)了一下,訓(xùn)練數(shù)據(jù)集選取的一個關(guān)鍵,就是要選取基于文本的(document-level)而不僅僅是基于句子的(sentence-level),主要是為了讓模型學(xué)會long contiguous sequences。接下來原論文中就提了一下預(yù)訓(xùn)練的細節(jié),有興趣的同學(xué)可以了解一下(大概很難復(fù)現(xiàn)?)。至于BERT的實踐應(yīng)用,完全值得另開一篇文章來詳細解讀,本文就先不具體展開了~
2.5 論文實驗結(jié)果分析
論文作者把自己提出的整套框架在各大NLP任務(wù)上實現(xiàn)了一遍,并且最后還對模型的訓(xùn)練過程做了一些實驗對比,這里就不具體展現(xiàn)了。有興趣的讀者可以自行研讀。值得一提的是,谷歌有開源的tensor2tensor,有空還是可以讀一遍源碼,或者工業(yè)界的小伙伴,可以學(xué)一波應(yīng)用(資源允許的話)。
但是,仔細考量一下,Bert也并非是無敵的存在,我總結(jié)一下其主要的缺點有:
1)這是非語言模型,所以不能適用于生成文本。
2)其訓(xùn)練和預(yù)測的過程是不一樣的,即預(yù)測的時候是沒有[MASK]這種東西的,但是訓(xùn)練的時候是有的。
3)效率還是比較低下,沒有GPU的小伙伴基本是無緣嘍~
哎,不過人家就是效果好啊~哈哈~
------------------第三菇 - 總結(jié)------------------
3.1 總結(jié)
到這里,整篇論文的核心思想及其創(chuàng)新點已經(jīng)說清楚了。本論文主要集中在于闡述BERT的核心思想,并且解釋了如何實現(xiàn)整一套BERT,附上了詳實的對比實驗,來驗證模型的可行性。
簡單總結(jié)一下本文就是先羅列了一下該論文的摘要,再具體介紹了一下自己對BERT的理解,以及詳細解釋了一些BERT涉及的訓(xùn)練方法。總的來說,谷歌這篇論文注定是要開啟一個新時代。希望大家讀完本文后能進一步加深對該論文的理解。有說的不對的地方也請大家指出,多多交流,大家一起進步~??