BERT和transformer

前言

BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding(/arxiv.org/abs/1810.04805)。BERT解決方案刷新了各大NLP任務的榜單,在各種NLP任務上都做到state of the art。這里我把BERT說成是解決方案,而不是一個算法,因為這篇文章并沒有提出新的算法模型,還是沿用了之前已有的算法模型。BERT最大的創新點,在于提出了一套完整的方案,利用之前最新的算法模型,去解決各種各樣的NLP任務,因此BERT這篇論文對于算法模型完全不做介紹,以至于在我直接看這篇文章的時候感覺云里霧里。但是本文中,我會從算法模型到解決方案,進行完整的詮釋。本文中我會分3個部分進行介紹,第一部分我會大概介紹一下NLP的發展,第二部分主要講BERT用到的算法,最后一部分講BERT具體是怎么操作的。

NLP發展

要處理NLP問題,首先要解決文本的表示問題。雖然我們人去看文本,能夠清楚明白文本中的符號表達什么含義,但是計算機只能做數學計算,需要將文本表示成計算機可以處理的形式。最開始的方法是采用one hot,比如,我們假設英文中常用的單詞有3萬個,那么我們就用一個3萬維的向量表示這個詞,所有位置都置0,當我們想表示apple這個詞時,就在對應位置設置1,如圖1.1所示。這種表示方式存在的問題就是,高維稀疏,高維是指有多少個詞,就需要多少個維度的向量,稀疏是指,每個向量中大部分值都是0。另外一個不足是這個向量沒有任何含義。

后來出現了詞向量,word embedding,用一個低維稠密的向量去表示一個詞,如圖1.2所示。通常這個向量的維度在幾百到上千之間,相比one hot幾千幾萬的維度就低了很多。詞與詞之間可以通過相似度或者距離來表示關系,相關的詞向量相似度比較高,或者距離比較近,不相關的詞向量相似度低,或者距離比較遠,這樣詞向量本身就有了含義。文本的表示問題就得到了解決。詞向量可以通過一些無監督的方法學習得到,比如CBOW或者Skip-Gram等,可以預先在語料庫上訓練出詞向量,以供后續的使用。順便提一句,在圖像中就不存在表示方法的困擾,因為圖像本身就是數值矩陣,計算機可以直接處理。

NLP中有各種各樣的任務,比如分類(Classification),問答(QA),實體命名識別(NER)等。對于這些不同的任務,最早的做法是根據每類任務定制不同的模型,輸入預訓練好的embedding,然后利用特定任務的數據集對模型進行訓練,如圖1.3所示。這里存在的問題就是,不是每個特定任務都有大量的標簽數據可供訓練,對于那些數據集非常小的任務,恐怕就難以得到一個理想的模型。

看一下圖像領域是如何解決這個問題的。圖像分類是計算機視覺中最基本的任務,當我要解決一個小數據集的圖像分類任務時,該怎么做?CV領域已經有了一套成熟的解決方案。我會用一個通用的網絡模型,比如VGG,ResNet或者GoogleNet,在ImageNet上做預訓練(pre-training)。ImageNet有1400萬張有標注的圖片,包含1000個類別,這樣的數據規模足以訓練出一個規模龐大的模型。在訓練過程中,模型會不斷的學習如何提取特征,底層的CNN網絡結構會提取邊緣,角,點等通用特征,模型越往上走,提取的特征也越抽象,與特定的任務更加相關。當完成預訓練之后,根據我自己的分類任務,調整最上層的網絡結構,然后在小數據集里對模型進行訓練。在訓練時,可以固定住底層的模型參數只訓練頂層的參數,也可以對整個模型進行訓練,這個過程叫做微調(fine-tuning),最終得到一個可用的模型。總結一下,整個過程包括兩步,拿一個通用模型在ImageNet上做預訓練(pre-training),然后針對特定任務進行微調(fine-tuning),完美解決了特定任務數據不足的問題。還有一個好處是,對于各種各樣的任務都不再需要從頭開始訓練網絡,可以直接拿預訓練好的結果進行微調,既減少了訓練計算量的負擔,也減少了人工標注數據的負擔。

NLP領域也引入了這種做法,用一個通用模型,在非常大的語料庫上進行預訓練,然后在特定任務上進行微調,BERT就是這套方案的集大成者。BERT不是第一個,但目前為止,是效果最好的方案。BERT用了一個已有的模型結構,提出了一整套的預訓練方法和微調方法,我們在后文中再進行詳細的描述。

算法

BERT所采用的算法來自于2017年12月份的這篇文章,Attenion Is All You Need(/arxiv.org/abs/1706.03762),同樣來自于谷歌。這篇文章要解決的是翻譯問題,比如從中文翻譯成英文。這篇文章完全放棄了以往經常采用的RNN和CNN,提出了一種新的網絡結構,即Transformer,其中包括encoder和decoder,我們只關注encoder。這篇英文博客(/jalammar.github.io/illus)對Transformer介紹得非常詳細,有興趣的讀者可以看一下,如果不想看英文博客也可以看本文,本文中的部分圖片也截取自這篇博客。

圖2.1是Transformer encoder的結構,后文中我們都簡稱為Transformer。首先是輸入word embedding,這里是直接輸入一整句話的所有embedding。如圖2.1所示,假設我們的輸入是Thinking Machines,每個詞對應一個embedding,就有2個embedding。輸入embedding需要加上位置編碼(Positional Encoding),為什么要加位置編碼,后文會做詳細介紹。然后經過一個Multi-Head Attention結構,這個結構是算法單元中最重要的部分,我們會在后邊詳細介紹。之后是做了一個shortcut的處理,就是把輸入和輸出按照對應位置加起來,如果了解殘差網絡(ResNet)的同學,會對這個結構比較熟悉,這個操作有利于加速訓練。然后經過一個歸一化normalization的操作。接著經過一個兩層的全連接網絡,最后同樣是shortcut和normalization的操作??梢钥吹?,除了Multi-Head Attention,都是常規操作,沒有什么難理解的。這里需要注意的是,每個小模塊的輸入和輸出向量,維度都是相等的,比如,Multi-Head Attention的輸入和輸出向量維度是相等的,否則無法進行shortcut的操作;Feed Forward的輸入和輸出向量維度也是相等的;最終的輸出和輸入向量維度也是相等的。但是Multi-Head Attention和Feed Forward內部,向量維度會發生變化。

來詳細看一下Multi-Head Attention的結構。這個Multi-Head表示多頭的意思,先從最簡單的看起,看看單頭Attention是如何操作的。從圖2.1的橙色方塊可以看到,embedding在進入到Attention之前,有3個分叉,那表示說從1個向量,變成了3個向量。具體是怎么算的呢?我們看圖2.3,定義一個WQ矩陣(這個矩陣隨機初始化,通過訓練得到),將embedding和WQ矩陣做乘法,得到查詢向量q,假設輸入embedding是512維,在圖3中我們用4個小方格表示,輸出的查詢向量是64維,圖3中用3個小方格以示不同。然后類似地,定義WK和WV矩陣,將embedding和WK做矩陣乘法,得到鍵向量k;將embeding和WV做矩陣乘法,得到值向量v。對每一個embedding做同樣的操作,那么每個輸入就得到了3個向量,查詢向量,鍵向量和值向量。需要注意的是,查詢向量和鍵向量要有相同的維度,值向量的維度可以相同,也可以不同,但一般也是相同的。

接下來計算每一個embedding的輸出,以第一個詞Thinking為例,參看圖2.4。用查詢向量q1跟鍵向量k1和k2分別做點積,得到112和96兩個數值。這也是為什么前文提到查詢向量和鍵向量的維度必須要一致,否則無法做點積。然后除以常數8,得到14和12兩個數值。這個常數8是鍵向量的維度的開方,鍵向量和查詢向量的維度都是64,開方后是8。做這個尺度上的調整目的是為了易于訓練。然后把14和12丟到softmax函數中,得到一組加和為1的系數權重,算出來是大約是0.88和0.12。將0.88和0.12對兩個值向量v1和v2做加權求和,就得到了Thinking的輸出向量z1。類似的,可以算出Machines的輸出z2。如果一句話中包含更多的詞,也是相同的計算方法。

通過這樣一系列的計算,可以看到,現在每個詞的輸出向量z都包含了其他詞的信息,每個詞都不再是孤立的了。而且每個位置中,詞與詞的相關程度,可以通過softmax輸出的權重進行分析。如圖2.5所示,這是某一次計算的權重,其中線條顏色的深淺反映了權重的大小,可以看到it中權重最大的兩個詞是The和animal,表示it跟這兩個詞關聯最大。這就是attention的含義,輸出跟哪個詞關聯比較強,就放比較多的注意力在上面。

上面我們把每一步計算都拆開了看,實際計算的時候,可以通過矩陣來計算,如圖2.6所示。

講完了attention,再來講Multi-Head。對于同一組輸入embedding,我們可以并行做若干組上面的操作,例如,我們可以進行8組這樣的運算,每一組都有WQ,WK,WV矩陣,并且不同組的矩陣也不相同。這樣最終會計算出8組輸出,我們把8組的輸出連接起來,并且乘以矩陣WO做一次線性變換得到輸出,WO也是隨機初始化,通過訓練得到,計算過程如圖2.7所示。這樣的好處,一是多個組可以并行計算,二是不同的組可以捕獲不同的子空間的信息。

到這里就把Transformer的結構講完了,同樣都是做NLP任務,我們來和RNN做個對比。圖2.8是個最基本的RNN結構,還有計算公式。當計算隱向量h4時,用到了輸入x4,和上一步算出來的隱向量h3,h3包含了前面所有節點的信息。h4中包含最多的信息是當前的輸入x4,越往前的輸入,隨著距離的增加,信息衰減得越多。對于每一個輸出隱向量h都是如此,包含信息最多得是當前的輸入,隨著距離拉遠,包含前面輸入的信息越來越少。但是Transformer這個結構就不存在這個問題,不管當前詞和其他詞的空間距離有多遠,包含其他詞的信息不取決于距離,而是取決于兩者的相關性,這是Transformer的第一個優勢。第二個優勢在于,對于Transformer來說,在對當前詞進行計算的時候,不僅可以用到前面的詞,也可以用到后面的詞。而RNN只能用到前面的詞,這并不是個嚴重的問題,因為這可以通過雙向RNN來解決。第三點,RNN是一個順序的結構,必須要一步一步地計算,只有計算出h1,才能計算h2,再計算h3,隱向量無法同時并行計算,導致RNN的計算效率不高,這是RNN的固有結構所造成的,之前有一些工作就是在研究如何對RNN的計算并行化。通過前文的介紹,可以看到Transformer不存在這個問題。通過這里的比較,可以看到Transformer相對于RNN有巨大的優勢。

RNN的結構包含了序列的時序信息,而Transformer卻完全把時序信息給丟掉了。為了解決時序的問題,Transformer的作者用了一個絕妙的辦法,這就是我在前文提到的位置編碼(Positional Encoding)。位置編碼是和word embedding同樣維度的向量,將位置embedding和詞embedding加在一起,作為輸入embedding,如圖2.9所示。位置編碼可以通過學習得到,也可以通過設置一個跟位置或者時序相關的函數得到,比如設置一個正弦或者余弦函數,這里不再多說。

把圖2.1的結構作為一個基本單元,把N個這樣的基本單元順序連起來,就是BERT的算法模型,如圖2.10所示。從前面的描述中可以看到,當輸入有多少個embedding,那么輸出也就有相同數量的embedding,可以采用和RNN采用相同的叫法,把輸出叫做隱向量。在做具體NLP任務的時候,只需要從中取對應的隱向量作為輸出即可。

BERT

在介紹BERT之前,我們先看看另外一套方案。在第一部分說過,BERT并不是第一個提出預訓練加微調的方案,此前還有一套方案叫GPT,這也是BERT重點對比的方案,文章在這,Improving Language Understanding by Generative Pre-Training(hs3-us-west-2.amazonaws.com/)。GPT的模型結構和BERT是相同的,都是圖2.10的結構,只是BERT的模型規模更加龐大。GPT是這么預訓練的,在一個8億單詞的語料庫上做訓練,給出前文,不斷地預測下一個單詞。比如這句話,Winter is coming,當給出第一個詞Winter之后,預測下一個詞is,之后再預測下一個詞coming。不需要標注數據,通過這種無監督訓練的方式,得到一個預訓練模型。

我們再來看看BERT有什么不同。BERT來自于Bidirectional Encoder Representations from Transformers首字母縮寫,這里提到了一個雙向(Bidirectional)的概念。BERT在一個33億單詞的語料庫上做預訓練,語料庫就要比GPT大了幾倍。預訓練包括了兩個任務,第一個任務是隨機地扣掉15%的單詞,用一個掩碼MASK代替,讓模型去猜測這個單詞;第二個任務是,每個訓練樣本是一個上下句,有50%的樣本,下句和上句是真實的,另外50%的樣本,下句和上句是無關的,模型需要判斷兩句的關系。這兩個任務各有一個loss,將這兩個loss加起來作為總的loss進行優化。下面兩行是一個小栗子,用括號標注的是扣掉的詞,用[MASK]來代替。

正樣本:我[MASK](是)個算法工程師,我服務于WiFi萬能鑰匙這家[MASK](公司)。

負樣本:我[MASK](是)個算法工程師,今天[MASK](股票)又跌了。

我們來對比下GPT和BERT兩種預訓練方式的優劣。GPT在預測詞的時候,只預測下一個詞,因此只能用到上文的信息,無法利用到下文的信息。而BERT是預測文中扣掉的詞,可以充分利用到上下文的信息,這使得模型有更強的表達能力,這也是BERT中Bidirectional的含義。在一些NLP任務中需要判斷句子關系,比如判斷兩句話是否有相同的含義。BERT有了第二個任務,就能夠很好的捕捉句子之間的關系。圖3.1是BERT原文中對另外兩種方法的預訓練對比,包括GPT和ELMo。ELMo采用的還是LSTM,這里我們不多講ELMo。這里會有讀者困惑,這里的結構圖怎么跟圖2.10不一樣?如果熟悉LSTM的同學,看到最右邊的ELMo,就會知道那些水平相連的LSTM其實只是一個LSTM單元。左邊的BERT和GPT也是一樣,水平方向的Trm表示的是同一個單元,圖中那些復雜的連線表示的是詞與詞之間的依賴關系,BERT中的依賴關系既有前文又有后文,而GPT的依賴關系只有前文。

講完了這兩個任務,我們再來看看,如何表達這么復雜的一個訓練樣本,讓計算機能夠明白。圖3.2表示“my dog is cute, he likes playing.”的輸入形式。每個符號的輸入由3部分構成,一個是詞本身的embedding;第二個是表示上下句的embedding,如果是上句,就用A embedding,如果是下句,就用B embedding;最后,根據Transformer模型的特點,還要加上位置embedding,這里的位置embedding是通過學習的方式得到的,BERT設計一個樣本最多支持512個位置;將3個embedding相加,作為輸入。需要注意的是,在每個句子的開頭,需要加一個Classification(CLS)符號,后文中會進行介紹。

完成預訓練之后,就要針對特定任務就行微調了,這里描述一下論文中的4個例子,看圖3.4。首先說下分類任務,分類任務包括對單句子的分類任務,比如判斷電影評論是喜歡還是討厭;多句子分類,比如判斷兩句話是否表示相同的含義。圖3.4(a)(b)是對這類任務的一個示例,左邊表示兩個句子的分類,右邊是單句子分類。在輸出的隱向量中,取出CLS對應的向量C,加一層網絡W,并丟給softmax進行分類,得到預測結果P,計算過程如圖3.3中的計算公式。在特定任務數據集中對Transformer模型的所有參數和網絡W共同訓練,直到收斂。新增加的網絡W是HxK維,H表示隱向量的維度,K表示分類數量,W的參數數量相比預訓練模型的參數少得可憐。

image-20210428102806542
圖3.4

對于問答任務,如圖3.4(c),以SQuAD v1.1為例,給出一個問題Question,并且給出一個段落Paragraph,然后從段落中標出答案的具體位置。需要學習一個開始向量S,維度和輸出隱向量維度相同,然后和所有的隱向量做點積,取值最大的詞作為開始位置;另外再學一個結束向量E,做同樣的運算,得到結束位置。附加一個條件,結束位置一定要大于開始位置。最后再看NER任務,實體命名識別,比如給出一句話,對每個詞進行標注,判斷屬于人名,地名,機構名,還是其他。如圖3.4(d)所示,加一層分類網絡,對每個輸出隱向量都做一次判斷。可以看到,這些任務,都只需要新增少量的參數,然后在特定數據集上進行訓練即可。從實驗結果來看,即便是很小的數據集,也能取得不錯的效果。

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,882評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,208評論 3 414
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,746評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,666評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,477評論 6 407
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,960評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,047評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,200評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,726評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,617評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,807評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,327評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,049評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,425評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,674評論 1 281
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,432評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,769評論 2 372

推薦閱讀更多精彩內容