預訓練語言模型的前世此生 - 從Word Embedding到BERT

預訓練語言模型的前世此生 - 從Word Embedding到BERT

本篇文章共 24619 個詞,一個字一個字手碼的不容易,轉載請標明出處:
預訓練語言模型的前世此生 - 從Word Embedding到BERT - 二十三歲的有德html

Bert 最近很火,應該是最近最火爆的 AI 進展,網上的評價很高,從模型創新角度看通常,創新不算大。可是架不住效果太好了,基本刷新了不少 NLP 的任務的最好性能,有些任務還被刷爆了,這個纔是關鍵。另一點是 Bert 具有普遍的通用性,就是說絕大部分 NLP 任務均可以採用相似的兩階段模式直接去提高效果,這個第二關鍵。客觀的說,把 Bert 當作最近兩年 NLP 重大進展的集大成者更符合事實。git

本文的主題是預訓練語言模型的前世此生,會大體說下 NLP 中的預訓練技術是一步一步如何發展到 Bert 模型的,從中能夠很天然地看到 Bert 的思路是如何逐漸造成的,Bert 的歷史沿革是什麼,繼承了什麼,創新了什麼,爲何效果那麼好,主要緣由是什麼,以及爲什麼說模型創新不算太大,爲什麼說 Bert 是近年來 NLP 重大進展的集大成者。github

預訓練語言模型的發展並非一蹴而就的,而是伴隨着諸如詞嵌入、序列到序列模型及 Attention 的發展而產生的。api

DeepMind 的計算機科學家 Sebastian Ruder 給出了 21 世紀以來,從神經網絡技術的角度分析,天然語言處理的里程碑式進展,以下表所示:網絡

年份 2013 年 2014 年 2015 年 2016 年 2017 年
技術 word2vec GloVe LSTM/Attention Self-Attention Transformer
年份 2018 年 2019 年 2020 年
技術 GPT/ELMo/BERT/GNN XLNet/BoBERTa/GPT-2/ERNIE/T5 GPT-3/ELECTRA/ALBERT

本篇文章將會經過上表顯示的 NLP 中技術的發展史一一敘述,因爲 19 年後的技術大都是 BERT 的變體,在這裏不會多加敘述,讀者能夠自行加以瞭解。架構

1、預訓練

1.1 圖像領域的預訓練

在介紹圖像領域的預訓練以前,咱們首先介紹下卷積神經網絡(CNN),CNN 通常用於圖片分類任務,而且CNN 由多個層級結構組成,不一樣層學到的圖像特徵也不一樣,越淺的層學到的特徵越通用(橫豎撇捺),越深的層學到的特徵和具體任務的關聯性越強(人臉-人臉輪廓、汽車-汽車輪廓),以下圖所示:app

由此,當領導給咱們一個任務:阿貓、阿狗、阿虎的圖片各十張,而後讓咱們設計一個深度神經網絡,經過該網絡把它們三者的圖片進行分類。框架

對於上述任務,若是咱們親手設計一個深度神經網絡基本是不可能的,由於深度學習一個弱項就是在訓練階段對於數據量的需求特別大,而領導只給咱們合計三十張圖片,顯然這是不夠的。機器學習

雖然領導給咱們的數據量不多,可是咱們是否能夠利用網上現有的大量已作好分類標註的圖片。好比 ImageNet 中有 1400 萬張圖片,而且這些圖片都已經作好了分類標註。ide

上述利用網絡上現有圖片的思想就是預訓練的思想,具體作法就是:

  1. 經過 ImageNet 數據集咱們訓練出一個模型 A
  2. 因爲上面提到 CNN 的淺層學到的特徵通用性特別強,咱們能夠對模型 A 作出一部分改進獲得模型 B(兩種方法):
    1. 凍結:淺層參數使用模型 A 的參數,高層參數隨機初始化,淺層參數一直不變,而後利用領導給出的 30 張圖片訓練參數
    2. 微調:淺層參數使用模型 A 的參數,高層參數隨機初始化,而後利用領導給出的 30 張圖片訓練參數,可是在這裏淺層參數會隨着任務的訓練不斷髮生變化

經過上述的講解,對圖像預訓練作個總結(可參照上圖):對於一個具備少許數據的任務 A,首先經過一個現有的大量數據搭建一個 CNN 模型 A,因爲 CNN的淺層學到的特徵通用性特別強,所以在搭建一個 CNN 模型 B,其中模型 B 的淺層參數使用模型 A 的淺層參數,模型 B 的高層參數隨機初始化,而後經過凍結或微調的方式利用任務 A 的數據訓練模型 B,模型 B 就是對應任務 A 的模型。

1.2 預訓練的思想

有了圖像領域預訓練的引入,咱們在此給出預訓練的思想:任務 A 對應的模型 A 的參數再也不是隨機初始化的,而是經過任務 B 進行預先訓練獲得模型 B,而後利用模型 B 的參數對模型 A 進行初始化,再經過任務 A 的數據對模型 A 進行訓練。注:模型 B 的參數是隨機初始化的。

2、語言模型

想了解預訓練語言模型,首先得了解什麼是語言模型。

語言模型通俗點講就是計算一個句子的機率。也就是說,對於語言序列 \(w_1,w_2,\cdots,w_n\),語言模型就是計算該序列的機率,即 \(P(w_1,w_2,\cdots,w_n)\)

下面經過兩個實例具體瞭解上述所描述的意思:

  1. 假設給定兩句話 「判斷這個詞的磁性」 和 「判斷這個詞的詞性」,語言模型會認爲後者更天然。轉化成數學語言也就是:\(P(判斷,這個,詞,的,詞性) \gt P(判斷,這個,詞,的,磁性)\)
  2. 假設給定一句話作填空 「判斷這個詞的____」,則問題就變成了給定前面的詞,找出後面的一個詞是什麼,轉化成數學語言就是:\(P(詞性|判斷,這個,詞,的) \gt P(磁性|判斷,這個,詞,的)\)

經過上述兩個實例,能夠給出語言模型更加具體的描述:給定一句由 \(n\) 個詞組成的句子 \(W=w_1,w_2,\cdots,w_n\),計算這個句子的機率 \(P(w_1,w_2,\cdots,w_n)\),或者計算根據上文計算下一個詞的機率 \(P(w_n|w_1,w_2,\cdots,w_{n-1})\)

下面將介紹語言模型的兩個分支,統計語言模型和神經網絡語言模型。

2.1 統計語言模型

統計語言模型的基本思想就是計算條件機率

給定一句由 \(n\) 個詞組成的句子 \(W=w_1,w_2,\cdots,w_n\),計算這個句子的機率 \(P(w_1,w_2,\cdots,w_n)\) 的公式以下(條件機率乘法公式的推廣,鏈式法則):

\[\begin{align*} P(w_1,w_2,\cdots,w_n) & = P(w_1)P(w_2|w_1)P(w_3|w_1,w_2)\cdots p(w_n|w_1,w_2,\cdots,w_{n-1}) \\ & = \prod_i P(w_i|w1,w_2,\cdots,w_{i-1}) \end{align*} \]

對於上一節提到的 「判斷這個詞的詞性」 這句話,利用上述的公式,能夠獲得:

\[\begin{align*} & P(判斷,這個,詞,的,詞性) = \\ & P(判斷)P(這個|判斷)P(詞|判斷,這個) \\ & P(的|判斷,這個,詞)P(詞性|判斷,這個,詞,的)P(判斷,這個,詞,的,詞性) \end{align*} \]

對於上一節提到的另一個問題,當給定前面詞的序列 「判斷,這個,詞,的」 時,想要知道下一個詞是什麼,能夠直接計算以下機率:

\[P(w_{next}|判斷,這個,詞,的)\quad\text{公式(1)} \]

其中,\(w_{next} \in V\) 表示詞序列的下一個詞,\(V\) 是一個具備 \(|V|\) 個詞的詞典(詞集合)。

對於公式(1),能夠展開成以下形式:

\[P(w_{next}|判斷,這個,詞,的) = \frac{count(w_{next},判斷,這個,詞,的)}{count(判斷,這個,詞,的)} \quad\text{公式(2)} \]

對於公式(2),能夠把字典 \(V\) 中的多有單詞,逐一做爲 \(w_{next}\),帶入計算,最後取最大機率的詞做爲 \(w_{next}\) 的候選詞。

若是 \(|V|\) 特別大,公式(2)的計算將會很是困難,可是咱們能夠引入馬爾科夫鏈的概念(固然,在這裏只是簡單講講如何作,關於馬爾科夫鏈的數學理論知識能夠自行查看其餘參考資料)。

假設字典 \(V\) 中有 「火星」 一詞,能夠明顯發現 「火星」 不可能出如今 「判斷這個詞的」 後面,所以(火星,判斷,這個,詞,的)這個組合是不存在的,而且詞典中會存在不少相似於 「火星」 這樣的詞。

進一步,能夠發現咱們把(火星,判斷,這個,詞,的)這個組合判斷爲不存在,是由於 「火星」 不可能出如今 「詞的」 後面,也就是說咱們能夠考慮是否把公式(1)轉化爲

\[P(w_{next}|判斷,這個,詞,的) \approx P(w_{next}|詞,的)\quad\text{公式(3)} \]

公式(3)就是馬爾科夫鏈的思想:假設 \(w_{next}\) 只和它以前的 \(k\) 個詞有相關性\(k=1\) 時稱做一個單元語言模型,\(k=2\) 時稱爲二元語言模型。

能夠發現經過馬爾科夫鏈後改寫的公式計算起來將會簡單不少,下面咱們舉個簡單的例子介紹下如何計算一個二元語言模型的機率。

其中二元語言模型的公式爲:

\[P(w_i|w_{i-1})=\frac{count(w_{i-1},w_i)}{count(w_{i-1})}\quad\text{公式(4)} \]

假設有一個文本集合:

「詞性是動詞」
「判斷單詞的詞性」
「磁性很強的磁鐵」
「北京的詞性是名詞」

對於上述文本,若是要計算 \(P(詞性|的)\) 的機率,經過公式(4),須要統計 「的,詞性」 同時按序出現的次數,再除以 「的」 出現的次數:

\[P(詞性|的) = \frac{count(的,詞性)}{count(的)} = \frac{2}{3}\quad\text{公式(5)} \]

上述文本集合是咱們自定製的,然而對於絕大多數具備現實意義的文本,會出現數據稀疏的狀況,例如訓練時未出現,測試時出現了的未登陸單詞

因爲數據稀疏問題,則會出現機率值爲 0 的狀況(填空題將沒法從詞典中選擇一個詞填入),爲了不 0 值的出現,會使用一種平滑的策略——分子和分母都加入一個非 0 正數,例如能夠把公式(4)改成:

\[P(w_i|w_{i-1}) = \frac{count(w_{i-1},w_i)+1}{count(w_{i-1})+|V|}\quad\text{公式(6)} \]

神經網絡語言模型

上一節簡單的介紹了統計語言模型,而且在結尾處講到統計語言模型存在數據稀疏問題,針對該問題,咱們也提出了平滑方法來應對這個問題。

神經網絡語言模型則引入神經網絡架構來估計單詞的分佈,而且經過詞向量的距離衡量單詞之間的類似度,所以,對於未登陸單詞,也能夠經過類似詞進行估計,進而避免出現數據稀疏問題

上圖爲神經網絡語言模型結構圖,它的學習任務是輸入某個句中單詞 \(w_t = bert\) 前的 \(t-1\) 個單詞,要求網絡正確預測單詞 「bert」,即最大化:

\[P(w_t=bert|w_1,w_2,\cdots,w_{t-1};\theta)\quad\text{公式(7)} \]

上圖所示的神經網絡語言模型分爲三層,接下來咱們詳細講解這三層的做用:

  1. 神經網絡語言模型的第一層,爲輸入層。首先將前 \(n-1\) 個單詞用 Onehot 編碼(例如:0001000)做爲原始單詞輸入,以後乘以一個隨機初始化的矩陣 Q 後得到詞向量 \(C(w_i)\),對這 \(n-1\) 個詞向量處理後獲得輸入 \(x\),記做 \(x=(C(w_1),C(w_2),\cdots,C(w_{t-1}))\)
  2. 神經網絡語言模型的第二層,爲隱層,包含 \(h\) 個隱變量,\(H\) 表明權重矩陣,所以隱層的輸出爲 \(Hx+d\),其中 \(d\) 爲偏置項。而且在此以後使用 \(tanh\) 做爲激活函數。
  3. 神經網絡語言模型的第三層,爲輸出層,一共有 \(|V|\) 個輸出節點(字典大小),直觀上講,每一個輸出節點 \(y_i\) 是詞典中每個單詞機率值。最終獲得的計算公式爲:\(y = softmax(b+Wx+U\tanh(d+Hx))\),其中 \(W\) 是直接從輸入層到輸出層的權重矩陣,\(U\) 是隱層到輸出層的參數矩陣。

3、詞向量

在描述神經網絡語言模型的時候,提到 Onehot 編碼和詞向量 \(C(w_i)\),可是並無具體說起他們究竟是什麼玩意。

因爲他們對於將來 BERT 的講解很是重要,因此在這裏重開一章來描述詞向量究竟是什麼,如何表示。

3.1 獨熱(Onehot)編碼

把單詞用向量表示,是把深度神經網絡語言模型引入天然語言處理領域的一個核心技術。

在天然語言處理任務中,訓練集大多爲一個字或者一個詞,把他們轉化爲計算機適合處理的數值類數據很是重要。

早期,人們想到的方法是使用獨熱(Onehot)編碼,以下圖所示:

對於上圖的解釋,假設有一個包含 8 個次的字典 \(V\),「time」 位於字典的第 1 個位置,「banana」 位於字典的第 8 個位置,所以,採用獨熱表示方法,對於 「time」 的向量來講,除了第 1 個位置爲 1,其他位置爲 0;對於 「banana」 的向量來講,除了第 8 個位置爲 1,其他位置爲 0。

可是,對於獨熱表示的向量,若是採用餘弦類似度計算向量間的類似度,能夠明顯的發現任意二者向量的類似度結果都爲 0,即任意兩者都不相關,也就是說獨熱表示沒法解決詞之間的類似性問題。

3.2 Word Embedding

因爲獨熱表示沒法解決詞之間類似性問題,這種表示很快就被詞向量表示給替代了,這個時候聰明的你可能想到了在神經網絡語言模型中出現的一個詞向量 \(C(w_i)\),對的,這個 \(C(w_i)\) 其實就是單詞對應的 Word Embedding 值,也就是咱們這節的核心——詞向量。

在神經網絡語言模型中,咱們並無詳細解釋詞向量是如何計算的,如今讓咱們重看神經網絡語言模型的架構圖:

上圖所示有一個 \(V×m\) 的矩陣 \(Q\),這個矩陣 \(Q\) 包含 \(V\) 行,\(V\) 表明詞典大小,每一行的內容表明對應單詞的 Word Embedding 值。

只不過 \(Q\) 的內容也是網絡參數,須要學習得到,訓練剛開始用隨機值初始化矩陣 \(Q\),當這個網絡訓練好以後,矩陣 \(Q\) 的內容被正確賦值,每一行表明一個單詞對應的 Word embedding 值。

可是這個詞向量有沒有解決詞之間的類似度問題呢?爲了回答這個問題,咱們能夠看看詞向量的計算過程:

\[\begin{bmatrix} 0&0&0&1&0 \end{bmatrix} \begin{bmatrix} 17&24&1\\ 23&5&7\\ 4&6&13\\ 10&12&19\\ 11&18&25 \end{bmatrix} = \begin{bmatrix} 10&12&19 \end{bmatrix} \quad\text{公式(8)} \]

經過上述詞向量的計算,能夠發現第 4 個詞的詞向量表示爲 \([10\,12\,19]\)

若是再次採用餘弦類似度計算兩個詞之間的類似度,結果再也不是 0 ,既能夠必定程度上描述兩個詞之間的類似度。

下圖給了網上找的幾個例子,能夠看出有些例子效果仍是很不錯的,一個單詞表達成 Word Embedding 後,很容易找出語義相近的其它詞彙。

4、Word2Vec 模型

2013 年最火的用語言模型作 Word Embedding 的工具是 Word2Vec ,後來又出了Glove(因爲 Glove 和 Word2Vec 的做用相似,並對 BERT 的講解沒有什麼幫助,以後再也不多加敘述),Word2Vec是怎麼工做的呢?看下圖:

Word2Vec 的網絡結構其實和神經網絡語言模型(NNLM)是基本相似的,只是這個圖長得清晰度差了點,看上去不像,其實它們是親兄弟。不過這裏須要指出:儘管網絡結構相近,並且都是作語言模型任務,可是他們訓練方法不太同樣。

Word2Vec 有兩種訓練方法:

  1. 第一種叫 CBOW,核心思想是從一個句子裏面把一個詞摳掉,用這個詞的上文和下文去預測被摳掉的這個詞;
  2. 第二種叫作 Skip-gram,和 CBOW 正好反過來,輸入某個單詞,要求網絡預測它的上下文單詞。

而你回頭看看,NNLM 是怎麼訓練的?是輸入一個單詞的上文,去預測這個單詞。這是有顯著差別的。

爲何 Word2Vec 這麼處理?緣由很簡單,由於 Word2Vec 和 NNLM 不同,NNLM 的主要任務是要學習一個解決語言模型任務的網絡結構,語言模型就是要看到上文預測下文,而 Word Embedding只是 NNLM 無意插柳的一個副產品;可是 Word2Vec 目標不同,它單純就是要 Word Embedding 的,這是主產品,因此它徹底能夠隨性地這麼去訓練網絡。

爲何要講 Word2Vec 呢?這裏主要是要引出 CBOW 的訓練方法,BERT 其實跟它有關係,後面會講解它們之間的關係,固然它們的關係 BERT 做者沒說,是我猜的,至於我猜的對不對,你看完這篇文章以後能夠自行判斷。

5、天然語言處理的預訓練模型

忽然在文章中插入這一段,其實就是給出一個問題:Word Embedding 這種作法能算是預訓練嗎?這其實就是標準的預訓練過程。要理解這一點要看看學會 Word Embedding 後下遊任務是怎麼使用它的。

假設如上圖所示,咱們有個NLP的下游任務,好比 QA,就是問答問題,所謂問答問題,指的是給定一個問題 X,給定另一個句子 Y,要判斷句子 Y 是不是問題 X 的正確答案。

問答問題假設設計的網絡結構如上圖所示,這裏不展開講了,懂得天然懂,不懂的也不要緊,由於這點對於本文主旨來講不關鍵,關鍵是網絡如何使用訓練好的 Word Embedding 的。

它的使用方法其實和前面講的 NNLM 是同樣的,句子中每一個單詞以 Onehot 形式做爲輸入,而後乘上學好的 Word Embedding 矩陣 Q,就直接取出單詞對應的 Word Embedding 了。

這乍看上去好像是個查表操做,不像是預訓練的作法是吧?其實否則,那個Word Embedding矩陣Q其實就是網絡 Onehot 層到 embedding 層映射的網絡參數矩陣。

因此你看到了,使用 Word Embedding 等價於什麼?等價於把 Onehot 層到 embedding 層的網絡用預訓練好的參數矩陣 Q 初始化了。這跟前面講的圖像領域的低層預訓練過程實際上是同樣的,區別無非 Word Embedding 只能初始化第一層網絡參數,再高層的參數就無能爲力了

下游NLP任務在使用 Word Embedding 的時候也相似圖像有兩種作法,一種是 Frozen,就是 Word Embedding 那層網絡參數固定不動;另一種是 Fine-Tuning,就是 Word Embedding 這層參數使用新的訓練集合訓練也須要跟着訓練過程更新掉。

上面這種作法就是18年以前NLP領域裏面採用預訓練的典型作法,而且 Word Embedding 其實對於不少下游 NLP 任務是有幫助的,只是幫助沒有大到閃瞎忘記戴墨鏡的圍觀羣衆的雙眼而已。

6、RNN 和 LSTM

爲何要在這裏穿插一個 RNN(Recurrent Neural Network) 和 LSTM(Long Short-Term Memory) 呢?

由於接下來要介紹的 ELMo(Embeddings from Language Models) 模型在訓練過程當中使用了雙向長短時間記憶網絡(Bi-LSTM)。

固然,這裏只是簡單地介紹,想要詳細瞭解的能夠去查看網上鋪天蓋地的參考資料。

6.1 RNN

傳統的神經網絡沒法獲取時序信息,然而時序信息在天然語言處理任務中很是重要

例如對於這一句話 「我吃了一個蘋果」,「蘋果」 的詞性和意思,在這裏取決於前面詞的信息,若是沒有 「我吃了一個」 這些詞,「蘋果」 也能夠翻譯爲喬布斯搞出來的那個被咬了一口的蘋果。

也就是說,RNN 的出現,讓處理時序信息變爲可能。

RNN 的基本單元結構以下圖所示:

上圖左邊部分稱做 RNN 的一個 timestep,在這個 timestep 中能夠看到,在 \(t\) 時刻,輸入變量 \(x_t\),經過 RNN 的一個基礎模塊 A,輸出變量 \(h_t\),而 \(t\) 時刻的信息,將會傳遞到下一個時刻 \(t+1\)

若是把模塊按照時序展開,則會如上圖右邊部分所示,由此能夠看到 RNN 爲多個基礎模塊 A 的互連,每個模塊都會把當前信息傳遞給下一個模塊

RNN 解決了時序依賴問題,但這裏的時序通常指的是短距離的,首先咱們先介紹下短距離依賴和長距離依賴的區別:

  • 短距離依賴:對於這個填空題 「我想看一場籃球____」,咱們很容易就判斷出 「籃球」 後面跟的是 「比賽」,這種短距離依賴問題很是適合 RNN。
  • 長距離依賴:對於這個填空題 「我出生在中國的瓷都景德鎮,小學和中學離家都很近,……,個人母語是____」,對於短距離依賴,「個人母語是」 後面能夠緊跟着 「漢語」、「英語」、「法語」,可是若是咱們想精確答案,則必須回到上文中很長距離以前的表述 「我出生在中國的瓷都景德鎮」,進而判斷答案爲 「漢語」,而 RNN 是很難學習到這些信息的。

6.2 RNN 的梯度消失問題

在這裏我簡單講解下 RNN 爲何不適合長距離依賴問題。

如上圖所示,爲RNN模型結構,前向傳播過程包括:

  • 隱藏狀態:\(h^{(t)} = \sigma (z^{(t)}) = \sigma(Ux^{(t)} + Wh^{(t-1)} + b)\) ,此處激活函數通常爲 \(tanh\)
  • 模型輸出:\(o^{(t)} = Vh^{(t)} + c\)
  • 預測輸出:\(\hat{y}^{(t)} = \sigma(o^{(t)})\) ,此處激活函數通常爲softmax。
  • 模型損失:\(L = \sum_{t = 1}^{T} L^{(t)}\)

RNN 全部的 timestep 共享一套參數 \(U,V,W\),在 RNN 反向傳播過程當中,須要計算 \(U,V,W\) 等參數的梯度,以 \(W\) 的梯度表達式爲例(假設 RNN 模型的損失函數爲 \(L\)):

\[\frac{\partial L}{\partial W} = \sum_{t = 1}^{T} \frac{\partial L}{\partial y^{(T)}} \frac{\partial y^{(T)}}{\partial o^{(T)}} \frac{\partial o^{(T)}}{\partial h^{(T)}} \left( \prod_{k=t + 1}^{T} \frac{\partial h^{(k)}}{\partial h^{(k - 1)}} \right) \frac{\partial h^{(t)}}{\partial W} \ \\ = \sum_{t = 1}^{T} \frac{\partial L}{\partial y^{(T)}} \frac{\partial y^{(T)}}{\partial o^{(T)}} \frac{\partial o^{(T)}}{\partial h^{(T)}} \left( \prod_{k=t+1}^{T} tanh^{'}(z^{(k)}) W \right) \frac{\partial h^{(t)}}{\partial W} \ \\ \quad\text{公式(9)} \]

對於公式(9)中的 \(\left( \prod_{k=t + 1}^{T} \frac{\partial h^{(k)}}{\partial h^{(k - 1)}} \right) = \left( \prod_{k=t+1}^{T} tanh^{'}(z^{(k)}) W \right)\)\(\tanh\) 的導數老是小於 1 的,因爲是 \(T-(t+1)\) 個 timestep 參數的連乘,若是 \(W\) 的主特徵值小於 1,梯度便會消失;若是 \(W\) 的特徵值大於 1,梯度便會爆炸。

須要注意的是,RNN和DNN梯度消失和梯度爆炸含義並不相同。

RNN中權重在各時間步內共享,最終的梯度是各個時間步的梯度和,梯度和會愈來愈大。所以,RNN中總的梯度是不會消失的,即便梯度越傳越弱,也只是遠距離的梯度消失。 從公式(9)中的 \(\left( \prod_{k=t+1}^{T} tanh^{'}(z^{(k)}) W \right)\) 能夠看到,RNN所謂梯度消失的真正含義是,梯度被近距離(\(t+1 趨向於 T\))梯度主導,遠距離(\(t+1 遠離 T\))梯度很小,致使模型難以學到遠距離的信息。

6.3 LSTM

爲了解決 RNN 缺少的序列長距離依賴問題,LSTM 被提了出來,首先咱們來看看 LSTM 相對於 RNN 作了哪些改進:

如上圖所示,爲 LSTM 的 RNN 門控結構(LSTM 的 timestep),LSTM 前向傳播過程包括:

  • 遺忘門:決定了丟棄哪些信息,遺忘門接收 \(t-1\) 時刻的狀態 \(h_{t-1}\),以及當前的輸入 \(x_t\),通過 Sigmoid 函數後輸出一個 0 到 1 之間的值 \(f_t\)
    • 輸出: \(f_{t} = \sigma(W_fh_{t-1} + U_fx_{t} + b_f)\)
  • 輸入門:決定了哪些新信息被保留,並更新細胞狀態,輸入們的取值由 \(h_{t-1}\)\(x_t\) 決定,經過 Sigmoid 函數獲得一個 0 到 1 之間的值 \(i_t\),而 \(\tanh\) 函數則創造了一個當前細胞狀態的候選 \(a_t\)
    • 輸出:\(i_{t} = \sigma(W_ih_{t-1} + U_ix_{t} + b_i)\) , \(\tilde{C_{t} }= tanhW_ah_{t-1} + U_ax_{t} + b_a\)
  • 細胞狀態:舊細胞狀態 \(C_{t-1}\) 被更新到新的細胞狀態 \(C_t\) 上,
    • 輸出:\(C_{t} = C_{t-1}\odot f_{t} + i_{t}\odot \tilde{C_{t} }\)
  • 輸出門:決定了最後輸出的信息,輸出門取值由 \(h_{t-1}\)\(x_t\) 決定,經過 Sigmoid 函數獲得一個 0 到 1 之間的值 \(o_t\),最後經過 \(\tanh\) 函數決定最後輸出的信息
    • 輸出:\(o_{t} = \sigma(W_oh_{t-1} + U_ox_{t} + b_o)\) , \(h_{t} = o_{t}\odot tanhC_{t}\)
  • 預測輸出:\(\hat{y}_{t} = \sigma(Vh_{t}+c)\)

6.4 LSTM 解決 RNN 的梯度消失問題

明白了 RNN 梯度消失的緣由以後,咱們看 LSTM 如何解決問題的呢?

RNN 梯度消失的緣由是,隨着梯度的傳導,梯度被近距離梯度主導,模型難以學習到遠距離的信息。具體緣由也就是 \(\prod_{k=t+1}^{T}\frac{\partial h_{k}}{\partial h_{k - 1}}\) 部分,在迭代過程當中,每一步 \(\frac{\partial h_{k}}{\partial h_{k - 1}}\) 始終在 [0,1) 之間或者始終大於 1。

而對於 LSTM 模型而言,針對 \(\prod _{k=t+1}^{T} \frac{\partial C_{k}}{\partial C_{k-1}}\) 求得:

\[\begin{align} & \frac{\partial C_{k}}{\partial C_{k-1}} = f_k + other \\ & \prod _{k=t+1}^{T} \frac{\partial C_{k}}{\partial C_{k-1}} = f_{k}f_{k+1}...f_{T} + other \\ \end{align} \]

在 LSTM 迭代過程當中,針對 \(\prod_{k=t+1}^{T} \frac{\partial C_{k}}{\partial C_{k-1}}\) 而言,每一步\(\frac{\partial C_{k}}{\partial C_{k-1}}\) 能夠自主的選擇在 [0,1] 之間,或者大於1,由於 \(f_{k}\) 是可訓練學習的。那麼總體 \(\prod _{k=t+1}^{T} \frac{\partial C_{k}}{\partial C_{k-1}}\) 也就不會一直減少,遠距離梯度不至於徹底消失,也就可以解決 RNN 中存在的梯度消失問題。

LSTM 遺忘門值 \(f_t\) 能夠選擇在 [0,1] 之間,讓 LSTM 來改善梯度消失的狀況。也能夠選擇接近 1,讓遺忘門飽和,此時遠距離信息梯度不消失;也能夠選擇接近 0,此時模型是故意阻斷梯度流,遺忘以前信息。

另外須要強調的是LSTM搞的這麼複雜,除了在結構上自然地克服了梯度消失的問題,更重要的是具備更多的參數來控制模型;經過四倍於RNN的參數量,能夠更加精細地預測時間序列變量。

此外,我記得有一篇文章講到,LSTM 在 200左右長度的文本上,就已經捉襟見肘了

7、ELMo 模型

7.1 ELMo 的預訓練

在講解 Word Embedding 時,細心地讀者必定已經發現,這些詞表示方法本質上是靜態的,每個詞都有一個惟一肯定的詞向量,不能根據句子的不一樣而改變,沒法處理天然語言處理任務中的多義詞問題。

如上圖所示,例如多義詞 Bank,有兩個經常使用含義,可是 Word Embedding 在對 bank 這個單詞進行編碼的時候,是區分不開這兩個含義的。

由於儘管這兩句含有 bank 的句子中 bank 上下文環境中出現的單詞不一樣,可是在用語言模型訓練的時候,不論什麼上下文的句子通過 Word2Vec,都是預測相同的單詞 bank,而同一個單詞佔用的是同一行的參數空間,這會致使兩種不一樣的上下文信息都會編碼到相同的 Word Embedding 空間裏,進而致使Word Embedding 沒法區分多義詞的不一樣語義。

因此對於好比 Bank 這個詞,它事先學好的 Word Embedding 中混合了幾種語義 ,在應用中來了個新句子,即便從上下文中(好比句子包含 money 等詞)明顯能夠看出它表明的是 「銀行」 的含義,可是對應的 Word Embedding 內容也不會變,它仍是混合了多種語義。

針對 Word Embedding 中出現的多義詞問題,ELMo 提供了一個簡潔優雅的解決方案。

ELMo 的本質思想是:我事先用語言模型學好一個單詞的 Word Embedding,此時多義詞沒法區分,不過這不要緊。在我實際使用 Word Embedding 的時候,單詞已經具有了特定的上下文了,這個時候我能夠根據上下文單詞的語義再去調整單詞的 Word Embedding 表示,這樣通過調整後的 Word Embedding 更能表達在這個上下文中的具體含義,天然也就解決了多義詞的問題了。因此 ELMo 自己是個根據當前上下文對 Word Embedding 動態調整的思路。

ELMo 採用了典型的兩階段過程:

  1. 第一個階段是利用語言模型進行預訓練;
  2. 第二個階段是在作下游任務時,從預訓練網絡中提取對應單詞的網絡各層的 Word Embedding 做爲新特徵補充到下游任務中。

上圖展現的是其第一階段預訓練過程,它的網絡結構採用了雙層雙向 LSTM,目前語言模型訓練的任務目標是根據單詞 \(w_i\) 的上下文去正確預測單詞 \(w_i\)\(w_i\) 以前的單詞序列 Context-before 稱爲上文,以後的單詞序列 Context-after 稱爲下文。

圖中左端的前向雙層 LSTM 表明正方向編碼器,輸入的是從左到右順序的除了預測單詞外 \(W_i\) 的上文 Context-before;右端的逆向雙層 LSTM 表明反方向編碼器,輸入的是從右到左的逆序的句子下文Context-after;每一個編碼器的深度都是兩層 LSTM 疊加。

這個網絡結構其實在 NLP 中是很經常使用的。使用這個網絡結構利用大量語料作語言模型任務就能預先訓練好這個網絡,若是訓練好這個網絡後,輸入一個新句子 \(s_{new}\) ,句子中每一個單詞都能獲得對應的三個 Embedding:

  • 最底層是單詞的 Word Embedding;
  • 往上走是第一層雙向 LSTM 中對應單詞位置的 Embedding,這層編碼單詞的句法信息更多一些;
  • 再往上走是第二層 LSTM 中對應單詞位置的 Embedding,這層編碼單詞的語義信息更多一些。

也就是說,ELMo 的預訓練過程不只僅學會單詞的 Word Embedding,還學會了一個雙層雙向的 LSTM 網絡結構,而這二者後面都有用。

7.2 ELMo 的 Feature-based Pre-Training

上面介紹的是 ELMo 的第一階段:預訓練階段。那麼預訓練好網絡結構後,如何給下游任務使用呢?

上圖展現了下游任務的使用過程,好比咱們的下游任務仍然是 QA 問題,此時對於問句 X:

  1. 咱們能夠先將句子 X 做爲預訓練好的 ELMo 網絡的輸入,這樣句子 X 中每一個單詞在 ELMO 網絡中都能得到對應的三個 Embedding;
  2. 以後給予這三個 Embedding 中的每個 Embedding 一個權重 a,這個權重能夠學習得來,根據各自權重累加求和,將三個 Embedding 整合成一個;
  3. 而後將整合後的這個 Embedding 做爲 X 句在本身任務的那個網絡結構中對應單詞的輸入,以此做爲補充的新特徵給下游任務使用。
  4. 對於上圖所示下游任務 QA 中的回答句子 Y 來講也是如此處理。

由於 ELMo 給下游提供的是每一個單詞的特徵形式,因此這一類預訓練的方法被稱爲 「Feature-based Pre-Training」。

至於爲什麼這麼作可以達到區分多義詞的效果,緣由在於在訓練好 ELMo 後,在特徵提取的時候,每一個單詞在兩層 LSTM 上都會有對應的節點,這兩個節點會編碼單詞的一些句法特徵和語義特徵,而且它們的 Embedding 編碼是動態改變的,會受到上下文單詞的影響,周圍單詞的上下文不一樣應該會強化某種語義,弱化其它語義,進而就解決了多義詞的問題。

8、Attention

上面巴拉巴拉了一堆,都在爲 BERT 的講解作鋪墊,而接下來要敘述的 Attention 和 Transformer 一樣如此,它們都只是 BERT 構成的一部分。

8.1 人類的視覺注意力

Attention 是注意力的意思,從它的命名方式看,很明顯借鑑了人類的注意力機制,所以,咱們首先介紹人類的視覺注意力。

視覺注意力機制是人類視覺所特有的大腦信號處理機制。人類視覺經過快速掃描全局圖像,得到須要重點關注的目標區域,也就是通常所說的注意力焦點,然後對這一區域投入更多注意力資源,以獲取更多所須要關注目標的細節信息,而抑制其餘無用信息。

這是人類利用有限的注意力資源從大量信息中快速篩選出高價值信息的手段,是人類在長期進化中造成的一種生存機制,人類視覺注意力機制極大地提升了視覺信息處理的效率與準確性。

上圖形象化展現了人類在看到一副圖像時是如何高效分配有限的注意力資源的,其中紅色區域代表視覺系統更關注的目標,很明顯對於上圖所示的場景,人們會把注意力更多投入到人的臉部,文本的標題以及文章首句等位置。

深度學習中的注意力機制從本質上講和人類的選擇性視覺注意力機制相似,核心目標也是從衆多信息中選擇出對當前任務目標更關鍵的信息。

8.2 Attention 的本質思想

從人類的視覺注意力能夠看出,注意力模型 Attention 的本質思想爲:從大量信息中有選擇地篩選出少許重要信息並聚焦到這些重要信息上,忽略不重要的信息。

在詳細講解 Attention以前,咱們在講講 Attention的其餘做用。以前咱們講解 LSTM 的時候說到,雖然 LSTM 解決了序列長距離依賴問題,可是單詞超過 200 的時候就會失效。而 Attention 機制能夠更加好的解決序列長距離依賴問題,而且具備並行計算能力。如今不明白這點不重要,隨着咱們對 Attention 的慢慢深刻,相信你會明白。

首先咱們得明確一個點,注意力模型從大量信息 Values 中篩選出少許重要信息,這些重要信息必定是相對於另一個信息 Query 而言是重要的,例如對於上面那張嬰兒圖,Query 就是觀察者。也就是說,咱們要搭建一個注意力模型,咱們必須得要有一個 Query 和一個 Values,而後經過 Query 這個信息從 Values 中篩選出重要信息。

經過 Query 這個信息從 Values 中篩選出重要信息,簡單點說,就是計算 Query 和 Values 中每一個信息的相關程度。

再具體點,Attention 一般能夠進行以下描述,表示爲將 Query(Q) 和 key-value pairs(把 Values 拆分紅了鍵值對的形式) 映射到輸出上,其中 query、每一個 key、每一個 value 都是向量,輸出是 V 中全部 values 的加權,其中權重是由 Query 和每一個 key 計算出來的,計算方法分爲三步:

  1. 第一步:計算比較 Q 和 K 的類似度,用 f 來表示:\(f(Q,K_i)\quad i=1,2,\cdots,m\),通常第一步計算方法包括四種
    1. 點乘(Transformer 使用):\(f(Q,K_i) = Q^T K_i\)
    2. 權重:\(f(Q,K_i) = Q^TWK_i\)
    3. 拼接權重:\(f(Q,K_i) = W[Q^T;K_i]\)
    4. 感知器:\(f(Q,K_i)=V^T \tanh(WQ+UK_i)\)
  2. 第二步:將獲得的類似度進行 softmax 操做,進行歸一化:\(\alpha_i = softmax(\frac{f(Q,K_i)}{\sqrt d_k})\)
    1. 這裏簡單講解除以 \(\sqrt d_k\) 的做用:假設 \(Q\) , \(K\) 裏的元素的均值爲0,方差爲 1,那麼 \(A^T=Q^TK\) 中元素的均值爲 0,方差爲 d。當 d 變得很大時, \(A\) 中的元素的方差也會變得很大,若是 \(A\) 中的元素方差很大(分佈的方差大,分佈集中在絕對值大的區域),在數量級較大時, softmax 將幾乎所有的機率分佈都分配給了最大值對應的標籤,因爲某一維度的數量級較大,進而會致使 softmax 將來求梯度時會消失。總結一下就是 \(\operatorname{softmax}\left(A\right)\) 的分佈會和d有關。所以 \(A\) 中每個元素乘上 \(\frac{1}{\sqrt{d_k}}\) 後,方差又變爲 1,而且 \(A\) 的數量級也將會變小。
  3. 第三步:針對計算出來的權重 \(\alpha_i\),對 \(V\) 中的全部 values 進行加權求和計算,獲得 Attention 向量:\(Attention = \sum_{i=1}^m \alpha_i V_i\)

8.3 Self Attention 模型

上面已經講了 Attention 就是從一堆信息中篩選出重要的信息,如今咱們來經過 Self Attention 模型來詳細講解如何找到這些重要的信息。

Self Attention 模型的架構以下圖所示,接下來咱們將按照這個模型架構的順序來逐一解釋。

首先能夠看到 Self Attention 有三個輸入 Q、K、V:對於 Self Attention,Q、K、V 來自句子 X 的 詞向量 x 的線性轉化,即對於詞向量 x,給定三個可學習的矩陣參數 \(W_Q,W_k,W_v\),x 分別右乘上述矩陣獲得 Q、K、V

接下來爲了表示的方便,咱們先經過向量的計算敘述 Self Attention 計算的流程,而後再描述 Self Attention 的矩陣計算過程

  1. 第一步,Q、K、V 的獲取

    上圖操做:兩個單詞 Thinking 和 Machines。經過線性變換,即 \(x_i\)\(x_2\) 兩個向量分別與\(W_q,W_k,W_v\) 三個矩陣點乘獲得 ${q_1,q_2},{k_1,k_2},{v_1,v_2} $ 共 6 個向量。矩陣 Q 則是向量 \(q_1,q_2\) 的拼接,K、V 同理。

  2. 第二步,MatMul

    1. 上圖操做:向量 \({q_1,k_1}\) 作點乘獲得得分 112, \({q_1,k_2}\) 作點乘獲得得分96。注意:這裏是經過 \(q_1\) 這個信息找到 \(x_1,x_2\) 中的重要信息。

  3. 第三步和第四步,Scale + Softmax

    上圖操做:對該得分進行規範,除以 \(\sqrt {d_k} = 8\)

  4. 第五步,MatMul

用得分比例 [0.88,0.12] 乘以 \([v_1,v_2]\) 值獲得一個加權後的值,將這些值加起來獲得 \(z_1\)

上述所說就是 Self Attention 模型所作的事,仔細感覺一下,用 \(q_1\)\(K=[k_1,k_2]\) 去計算一個 Thinking 相對於 Thinking 和 Machine 的權重,再用權重乘以 Thinking 和 Machine 的 \(V=[v_1,v_2]\) 獲得加權後的 Thinking 和 Machine 的 \(V=[v_1,v_2]\),最後求和獲得針對各單詞的輸出 \(z_1\)

同理能夠計算出 Machine 相對於 Thinking 和 Machine 的加權輸出 \(z_2\),拼接 \(z_1\)\(z_2\) 便可獲得 Attention 值 \(Z=[z_1,z_2]\),這就是 Self Attention 的矩陣計算,以下所示。

以前的例子是單個向量的運算例子。這張圖展現的是矩陣運算的例子,輸入是一個 [2x4] 的矩陣(句子中每一個單詞的詞向量的拼接),每一個運算是 [4x3] 的矩陣,求得 Q、K、V。

Q 對 K 轉製作點乘,除以 \(\sqrt d_k\),作一個 softmax 獲得合爲 1 的比例,對 V 作點乘獲得輸出 Z。那麼這個 Z 就是一個考慮過 Thinking 周圍單詞 Machine 的輸出。

注意看這個公式,\(QK^T\) 其實就會組成一個 word2word 的 attention map!(加了 softmax 以後就是一個合爲 1 的權重了)。好比說你的輸入是一句話 "i have a dream" 總共 4 個單詞,這裏就會造成一張 4x4 的注意力機制的圖:

這樣一來,每個單詞對應每個單詞都會有一個權重,這也是 Self Attention 名字的來源,即 Attention 的計算來源於 Source(源句) 和 Source 自己,通俗點講就是 Q、K、V 都來源於輸入 X 自己。

8.4 Self Attention 和 RNN、LSTM 的區別

引入 Self Attention 有什麼好處呢?或者說經過 Self Attention 到底學到了哪些規律或者抽取出了哪些特徵呢?咱們能夠經過下述兩幅圖來說解:

從上述兩張圖能夠看出,Self Attention 能夠捕獲同一個句子中單詞之間的一些句法特徵(例如第一張圖展現的有必定距離的短語結構)或者語義特徵(例如第二張圖展現的 its 的指代對象爲 Law)。

有了上述的講解,咱們如今能夠來看看 Self Attention 和 RNN、LSTM 的區別:

  • RNN、LSTM:若是是 RNN 或者 LSTM,須要依次序列計算,對於遠距離的相互依賴的特徵,要通過若干時間步步驟的信息累積才能將二者聯繫起來,而距離越遠,有效捕獲的可能性越小
  • Self Attention:
    • 經過上述兩幅圖,很明顯的能夠看出,引入 Self Attention 後會更容易捕獲句子中長距離的相互依賴的特徵,由於 Self Attention 在計算過程當中會直接將句子中任意兩個單詞的聯繫經過一個計算步驟直接聯繫起來,因此遠距離依賴特徵之間的距離被極大縮短,有利於有效地利用這些特徵
    • 除此以外,Self
      Attention 對於一句話中的每一個單詞均可以單獨的進行 Attention 值的計算,也就是說 Self Attention 對計算的並行性也有直接幫助做用,而對於必須得依次序列計算的 RNN 而言,是沒法作到並行計算的。

上述所說的,則是爲什麼 Self Attention 逐漸替代 RNN、LSTM 被普遍使用的緣由所在。

8.5 Masked Self Attention 模型

趁熱打鐵,咱們講講 Transformer 將來會用到的 Masked Self Attention 模型,這裏的 Masked 就是要在作語言模型(或者像翻譯)的時候,不給模型看到將來的信息,它的結構以下圖所示:

上圖中和 Self Attention 重複的部分此處就不講了,主要講講 Mask 這一塊。

假設在此以前咱們已經經過 scale 以前的步驟獲得了一個 attention map,而 mask 就是沿着對角線把灰色的區域用0覆蓋掉,不給模型看到將來的信息,以下圖所示:

詳細來講:

  1. "i" 做爲第一個單詞,只能有和 "i" 本身的 attention;
  2. "have" 做爲第二個單詞,有和 "i、have" 前面兩個單詞的 attention;
  3. "a" 做爲第三個單詞,有和 "i、have、a" 前面三個單詞的 attention;
  4. "dream" 做爲最後一個單詞,纔有對整個句子 4 個單詞的 attention。

而且在作完 softmax 以後,橫軸結果合爲 1。以下圖所示:

具體爲何要 mask,將來再講解 Transformer 的時候咱們會詳細解釋。

8.6 Multi-head Self Attention 模型

因爲 Transformer 使用的都是 Self Attention 的進階版 Multi-head Self Attention,咱們簡單講講 Multi-head Self Attention 的架構,而且在該小節結尾處講講它的優勢。

Multi-Head Attention 就是把 Self Attention的過程作 H 次,而後把輸出 Z 合起來。論文中,它的結構圖以下:

咱們仍是以上面的形式來解釋,首先,咱們使用 8 組不一樣的 \(W_Q^i,W_k^i,W_V^i\quad i=1,2,\cdots,8\) ,重複 8 次和 Self Attention 類似的操做,獲得 8 個 \(Z_i\) 矩陣:

爲了使得輸出與輸入結構相同,拼接矩陣 \(Z_i\) 後乘以一個線性 \(W_0\) 獲得最終的Z:

看完了 Multi-head Self Attention 的架構,發現它與 Self Attention 的區別,在於用了 \(n\)\(W_Q^i,W_k^i,W_V^i\quad i=1,2,\cdots,n\) 獲得 \(n\)\(Q_i,K_i,V_i \quad i=1,2,\cdots,n\)

能夠經過下圖看看 multi-head attention 的整個流程:

上述操做有什麼好處呢?使用多套參數,多套參數至關於把原始信息 Source 放入了多個子空間中,也就是捕捉了多個信息,對於使用 multi-head(多頭) attention 的簡單回答就是,多頭保證了 attention 能夠注意到不一樣子空間的信息,捕捉到更加豐富的特徵信息。其實本質上是論文原做者發現這樣效果確實好。

9、Position Embedding

在 Attention 和 RNN、LSTM 的對比中,咱們說到 Attention 解決了長距離依賴問題,而且能夠支持並行化,可是它就真的百利而無一害了嗎?

其實否則,咱們往前回顧,Self Attention 的 Q、K、V 三個矩陣是由同一個輸入 \(X_1=(x_1,x_2,\cdots,x_n)\) 線性轉換而來,也就是說對於這樣的一個被打亂序列順序的 \(X_2=(x_2,x_1,\cdots,x_n)\) 而言,因爲 Attention 值的計算最終會被加權求和,也就是說二者最終計算的 Attention 值都是同樣的,進而也就代表了 Attention 丟掉了 \(X_1\) 的序列順序信息。

如上圖所示,爲了解決 Attention 丟失的序列順序信息,Transformer 的提出者提出了 Position Embedding,也就是對於輸入 \(X\) 進行 Attention 計算以前,在 \(X\) 的詞向量中加上位置信息,也就是說 \(X\) 的詞向量爲 \(X_{final\_embedding} = Embedding + Positional\, Embedding\)

可是如何獲得 \(X\) 的位置向量呢?

其中位置編碼公式以下圖所示:

其中 pos 表示位置、i 表示維度、\(d_{model}\)表示位置向量的向量維度 、\(2i、2i+1\) 表示的是奇偶數(奇偶維度),上圖所示就是偶數位置使用 \(\sin\) 函數,奇數位置使用 \(\cos\) 函數。

有了位置編碼,咱們再來看看位置編碼是如何嵌入單詞編碼的(其中 512 表示編碼維度),經過把單詞的詞向量和位置向量進行疊加,這種方式就稱做位置嵌入,以下圖所示:

Position Embedding 自己是一個絕對位置的信息,但在語言模型中,相對位置也很重要。那麼爲何位置嵌入機制有用呢?

咱們不要去關心三角函數公式,能夠看看下圖公式(3)中的第一行,咱們作以下的解釋,對於 「我愛吃蘋果」 這一句話,有 5 個單詞,假設序號分別爲 一、二、三、四、5。

假設 \(pos=1=我、k=2=愛、pos+k=3=吃\),也就是說 \(pos+k=3\) 位置的位置向量的某一維能夠經過 \(pos=1\) 位置的位置向量的某一維線性組合加以線性表示,經過該線性表示能夠得出 「吃」 的位置編碼信息蘊含了相對於前兩個字 「我」 的位置編碼信息。

總而言之就是,某個單詞的位置信息是其餘單詞位置信息的線性組合,這種線性組合就意味着位置向量中蘊含了相對位置信息。

10、Transformer

10.1 Transformer 的結構

萬事俱備,只欠東風,下面咱們來說講咱們的重點之一,Transformer,你能夠先記住這一句話:Transformer 簡單點看其實就是 self-attention 模型的疊加,首先咱們來看看 Transformer 的總體框架。

Transformer 的總體框架以下圖所示:

上圖所示的總體框架乍一眼一看很是複雜,因爲 Transformer 起初是做爲翻譯模型,所以咱們以翻譯舉例,簡化一下上述的總體框架:

從上圖能夠看出 Transformer 至關於一個黑箱,左邊輸入 「Je suis etudiant」,右邊會獲得一個翻譯結果 「I am a student」。

再往細裏講,Transformer 也是一個 Seq2Seq 模型(Encoder-Decoder 框架的模型),左邊一個 Encoders 把輸入讀進去,右邊一個 Decoders 獲得輸出,以下所示:

在這裏,咱們穿插描述下 Encoder-Decoder 框架的模型是如何進行文本翻譯的:

  1. 將序列 \((x_1,x_2,\cdots,x_n)\) 做爲 Encoders 的輸入,獲得輸出序列 \((z_1,z_2,\cdots,z_n)\)
  2. 把 Encoders 的輸出序列 \((z_1,z_2,\cdots,z_n)\) 做爲 Decoders 的輸入,生成一個輸出序列 \((y_1,y_2,\cdots,y_m)\)。注:Decoders 每一個時刻輸出一個結果

第一眼看到上述的 Encodes-Decoders 框架圖,隨之產生問題就是 Transformer 中 左邊 Encoders 的輸出是怎麼和右邊 Decoders 結合的。由於decoders 裏面是有N層的,再畫張圖直觀的看就是這樣:

也就是說,Encoders 的輸出,會和每一層的 Decoder 進行結合

如今咱們取其中一層進行詳細的展現:

經過上述分析,發現咱們想要詳細瞭解 Transformer,只要瞭解 Transformer 中的 Encoder 和 Decoder 單元便可,接下來咱們將詳細闡述這兩個單元。

10.2 Encoder

有了上述那麼多知識的鋪墊,咱們知道 Eecoders 是 N=6 層,經過上圖咱們能夠看到每層 Encoder 包括兩個 sub-layers:

  • 第一個 sub-layer 是 multi-head self-attention,用來計算輸入的 self-attention;
  • 第二個 sub-layer 是簡單的前饋神經網絡層 Feed Forward;

注意:在每一個 sub-layer 咱們都模擬了殘差網絡(在下面的數據流示意圖中會細講),每一個sub-layer的輸出都是 \(LayerNorm(x+Sub\_layer(x))\),其中 \(sub\_layer\) 表示的是該層的上一層的輸出

如今咱們給出 Encoder 的數據流示意圖,一步一步去剖析

  1. 深綠色的 \(x_1\) 表示 Embedding 層的輸出,加上表明 Positional Embedding 的向量以後,獲得最後輸入 Encoder 中的特徵向量,也就是淺綠色向量 \(x_1\)
  2. 淺綠色向量 \(x_1\) 表示單詞 「Thinking」 的特徵向量,其中 \(x_1\) 通過 Self-Attention 層,變成淺粉色向量 \(z_1\)
  3. \(x_1\) 做爲殘差結構的直連向量,直接和 \(z_1\) 相加,以後進行 Layer Norm 操做,獲得粉色向量 \(z_1\)
    1. 殘差結構的做用:避免出現梯度消失的狀況
    2. Layer Norm 的做用:爲了保證數據特徵分佈的穩定性,而且能夠加速模型的收斂
  4. \(z_1\) 通過前饋神經網絡(Feed Forward)層,通過殘差結構與自身相加,以後通過 LN 層,獲得一個輸出向量 \(r_1\)
    1. 該前饋神經網絡包括兩個線性變換和一個ReLU激活函數:\(FFN(x) = max(0,xW_1+b_1)W_2+b2\)
  5. 因爲 Transformer 的 Encoders 具備 6 個 Encoder,\(r_1\) 也將會做爲下一層 Encoder 的輸入,代替 \(x_1\) 的角色,如此循環,直至最後一層 Encoder。

須要注意的是,上述的 \(x、z、r\) 都具備相同的維數,論文中爲 512 維。

10.3 Decoder

Decoders 也是 N=6 層,經過上圖咱們能夠看到每層 Decoder 包括 3 個 sub-layers:

  • 第一個 sub-layer 是 Masked multi-head self-attention,也是計算輸入的 self-attention;
    • 在這裏,先不解釋爲何要作 Masked,後面在 「Transformer 動態流程展現」 這一小節會解釋
  • 第二個 sub-layer 是 Encoder-Decoder Attention 計算,對 Encoder 的輸入和 Decoder 的Masked multi-head self-attention 的輸出進行 attention 計算;
    • 在這裏,一樣不解釋爲何要對 Encoder 和 Decoder 的輸出一同作 attention 計算,後面在 「Transformer 動態流程展現」 這一小節會解釋
  • 第三個 sub-layer 是前饋神經網絡層,與 Encoder 相同。

10.4 Transformer 輸出結果

以上,就講完了 Transformer 編碼和解碼兩大模塊,那麼咱們迴歸最初的問題,將 「機器學習」 翻譯成 「machine learing」,解碼器的輸出是一個浮點型的向量,怎麼轉化成 「machine learing」 這兩個詞呢?讓咱們來看看 Encoders 和 Decoders 交互的過程尋找答案:

從上圖能夠看出,Transformer 最後的工做是讓解碼器的輸出經過線性層 Linear 後接上一個 softmax

  • 其中線性層是一個簡單的全鏈接神經網絡,它將解碼器產生的向量 A 投影到一個更高維度的向量 B 上,假設咱們模型的詞彙表是10000個詞,那麼向量 B 就有10000個維度,每一個維度對應一個唯一的詞的得分。
  • 以後的softmax層將這些分數轉換爲機率。選擇機率最大的維度,並對應地生成與之關聯的單詞做爲此時間步的輸出就是最終的輸出啦!

假設詞彙表維度是 6,那麼輸出最大機率詞彙的過程以下:

11、Transformer 動態流程展現

首先咱們來看看拿 Transformer 做翻譯時,如何生成翻譯結果的:

繼續進行:

假設上圖是訓練模型的某一個階段,咱們來結合 Transformer 的完整框架描述下這個動態的流程圖:

  1. 輸入 「je suis etudiant」 到 Encoders,而後獲得一個 \(K_e\)\(V_e\) 矩陣;
  2. 輸入 「I am a student」 到 Decoders ,首先經過 Masked Multi-head Attention 層獲得 「I am a student」 的 attention 值 \(Q_d\),而後用 attention 值 \(Q_d\) 和 Encoders 的輸出 \(K_e\)\(V_e\) 矩陣進行 attention 計算,獲得第 1 個輸出 「I」;
  3. 輸入 「I am a student」 到 Decoders ,首先經過 Masked Multi-head Attention 層獲得 「I am a student」 的 attention 值 \(Q_d\),而後用 attention 值 \(Q_d\) 和 Encoders 的輸出 \(K_e\)\(V_e\) 矩陣進行 attention 計算,獲得第 2 個輸出 「am」;
  4. ……

如今咱們來解釋咱們以前遺留的兩個問題。

11.1 爲何 Decoder 須要作 Mask

  • 訓練階段:咱們知道 「je suis etudiant」 的翻譯結果爲 「I am a student」,咱們把 「I am a student」 的 Embedding 輸入到 Decoders 裏面,翻譯第一個詞 「I」 時

    • 若是對 「I am a student」 attention 計算不作 mask,「am,a,student」 對 「I」 的翻譯將會有必定的貢獻
    • 若是對 「I am a student」 attention 計算作 mask,「am,a,student」 對 「I」 的翻譯將沒有貢獻
  • 測試階段:咱們不知道 「我愛中國」 的翻譯結果爲 「I love China」,咱們只能隨機初始化一個 Embedding 輸入到 Decoders 裏面,翻譯第一個詞 「I」 時:

    • 不管是否作 mask,「love,China」 對 「I」 的翻譯都不會產生貢獻
    • 可是翻譯了第一個詞 「I」 後,隨機初始化的 Embedding 有了 「I」 的 Embedding,也就是說在翻譯第二詞 「love」 的時候,「I」 的 Embedding 將有必定的貢獻,可是 「China」 對 「love」 的翻譯毫無貢獻,隨之翻譯的進行,已經翻譯的結果將會對下一個要翻譯的詞都會有必定的貢獻,這就和作了 mask 的訓練階段作到了一種匹配

總結下就是:Decoder 作 Mask,是爲了讓訓練階段和測試階段行爲一致,不會出現間隙,避免過擬合

11.2 爲何 Encoder 給予 Decoders 的是 K、V 矩陣

咱們在講解 Attention 機制中曾提到,Query 的目的是藉助它從一堆信息中找到重要的信息。

如今 Encoder 提供了 \(K_e、V_e\) 矩陣,Decoder 提供了 \(Q_d\) 矩陣,經過 「我愛中國」 翻譯爲 「I love China」 這句話詳細解釋下。

當咱們翻譯 「I」 的時候,因爲 Decoder 提供了 \(Q_d\) 矩陣,經過與 \(K_e、V_e\) 矩陣的計算,它能夠在 「我愛中國」 這四個字中找到對 「I」 翻譯最有用的單詞是哪幾個,並以此爲依據翻譯出 「I」 這個單詞,這就很好的體現了注意力機制想要達到的目的,把焦點放在對本身而言更爲重要的信息上。

  • 其實上述說的就是 Attention 裏的 soft attention機制,解決了曾經的 Encoder-Decoder 框架的一個問題,在這裏很少作敘述,有興趣的能夠參考網上的一些資料。
    • 早期的 Encoder-Decoder 框架中的 Encoder 經過 LSTM 提取出源句(Source) 「我愛中國」 的特徵信息 C,而後 Decoder 作翻譯的時候,目標句(Target)「I love China」 中的任何一個單詞的翻譯都來源於相同特徵信息 C,這種作法是極其不合理的,例如翻譯 「I」 時應該着眼於 「我」,翻譯 「China」 應該着眼於 「中國」,而早期的這種作法並無體現出,然而 Transformer 卻經過 Attention 的作法解決了這個問題。

12、GPT 模型

12.1 GPT 模型的預訓練

在講解 ELMo 的時候,咱們說到 ELMo 這一類預訓練的方法被稱爲 「Feature-based Pre-Training」。而且若是把 ELMo 這種預訓練方法和圖像領域的預訓練方法對比,發現二者模式看上去仍是有很大差別的。

除了以 ELMo 爲表明的這種基於特徵融合的預訓練方法外,NLP 裏還有一種典型作法,這種作法和圖像領域的方式就是看上去一致的了,通常將這種方法稱爲 「基於Fine-tuning的模式」,而 GPT 就是這一模式的典型開創者,下面先讓咱們看看 GPT 的網絡結構。

GPT 是 「Generative Pre-Training」 的簡稱,從名字看其含義是指的生成式的預訓練。

GPT也採用兩階段過程:

  1. 第一個階段:利用語言模型進行預訓練;
  2. 第二個階段:經過 Fine-tuning 的模式解決下游任務。

上圖展現了 GPT 的預訓練過程,其實和 ELMo 是相似的,主要不一樣在於兩點:

  1. 首先,特徵抽取器用的不是 RNN,而是用的 Transformer,它的特徵抽取能力要強於RNN,這個選擇很明顯是很明智的;
  2. 其次,
    1. GPT 的預訓練雖然仍然是以語言模型做爲目標任務,可是採用的是單向的語言模型,所謂 「單向」 的含義是指:語言模型訓練的任務目標是根據 \(w_i\) 單詞的上下文去正確預測單詞 \(w_i\)\(w_i\) 以前的單詞序列Context-before稱爲上文,以後的單詞序列Context-after稱爲下文。
    2. ELMo 在作語言模型預訓練的時候,預測單詞 \(w_i\) 同時使用了上文和下文,而 GPT 則只採用 Context-before 這個單詞的上文來進行預測,而拋開了下文。
    3. GPT 這個選擇如今看不是個太好的選擇,緣由很簡單,它沒有把單詞的下文融合進來,這限制了其在更多應用場景的效果,好比閱讀理解這種任務,在作任務的時候是能夠容許同時看到上文和下文一塊兒作決策的。若是預訓練時候不把單詞的下文嵌入到 Word Embedding 中,是很吃虧的,白白丟掉了不少信息。

12.2 GPT 模型的 Fine-tuning

上面講的是 GPT 如何進行第一階段的預訓練,那麼假設預訓練好了網絡模型,後面下游任務怎麼用?它有本身的個性,和 ELMO 的方式大有不一樣。

上圖展現了 GPT 在第二階段如何使用:

  1. 首先,對於不一樣的下游任務來講,原本你能夠任意設計本身的網絡結構,如今不行了,你要向 GPT 的網絡結構看齊,把任務的網絡結構改形成和 GPT 同樣的網絡結構。

  2. 而後,在作下游任務的時候,利用第一步預訓練好的參數初始化 GPT 的網絡結構,這樣經過預訓練學到的語言學知識就被引入到你手頭的任務裏來了。

  3. 再次,你能夠用手頭的任務去訓練這個網絡,對網絡參數進行 Fine-tuning,使得這個網絡更適合解決手頭的問題。就是這樣。

這有沒有讓你想起最開始提到的圖像領域如何作預訓練的過程,對,這跟那個預訓練的模式是如出一轍的。

對於 NLP 各類花樣的不一樣任務,怎麼改造才能靠近 GPT 的網絡結構呢?因爲 GPT 對下游任務的改造過程和 BERT 對下游任務的改造極其相似,而且咱們主要目的是爲了講解 BERT,因此這個問題將會在 BERT 那裏獲得回答。

十3、BERT 模型

13.1 BERT:公認的里程碑

BERT 模型能夠做爲公認的里程碑式的模型,可是它最大的優勢不是創新,而是集大成者,而且這個集大成者有了各項突破,下面讓咱們看看 BERT 是怎麼集大成者的。

  • BERT 的意義在於:從大量無標記數據集中訓練獲得的深度模型,能夠顯著提升各項天然語言處理任務的準確率。
  • 近年來優秀預訓練語言模型的集大成者:參考了 ELMO 模型的雙向編碼思想、借鑑了 GPT 用 Transformer 做爲特徵提取器的思路、採用了 word2vec 所使用的 CBOW 方法
  • BERT 和 GPT 之間的區別:
    • GPT:GPT 使用 Transformer Decoder 做爲特徵提取器、具備良好的文本生成能力,然而當前詞的語義只能由其前序詞決定,而且在語義理解上不足
    • BERT:使用了 Transformer Encoder 做爲特徵提取器,並使用了與其配套的掩碼訓練方法。雖然使用雙向編碼讓 BERT 再也不具備文本生成能力,可是 BERT 的語義信息提取能力更強
  • 單向編碼和雙向編碼的差別,以該句話舉例 「今每天氣很{},咱們不得不取消戶外運動」,分別從單向編碼和雙向編碼的角度去考慮 {} 中應該填什麼詞:
    • 單向編碼:單向編碼只會考慮 「今每天氣很」,以人類的經驗,大機率會從 「好」、「不錯」、「差」、「糟糕」 這幾個詞中選擇,這些詞能夠被劃爲大相徑庭的兩類
    • 雙向編碼:雙向編碼會同時考慮上下文的信息,即除了會考慮 「今每天氣很」 這五個字,還會考慮 「咱們不得不取消戶外運動」 來幫助模型判斷,則大機率會從 「差」、「糟糕」 這一類詞中選擇

13.2 BERT 的結構:強大的特徵提取能力

  • 以下圖所示,咱們來看看 ELMo、GPT 和 BERT 三者的區別

    • ELMo 使用自左向右編碼和自右向左編碼的兩個 LSTM 網絡,分別以 \(P(w_i|w_1,\cdots,w_{i-1})\)\(P(w_i|w_{i+1},\cdots,w_n)\) 爲目標函數獨立訓練,將訓練獲得的特徵向量以拼接的形式實現雙向編碼,本質上仍是單向編碼,只不過是兩個方向上的單向編碼的拼接而成的雙向編碼
    • GPT 使用 Transformer Decoder 做爲 Transformer Block,以 \(P(w_i|w_1,\cdots,w_{i-1})\) 爲目標函數進行訓練,用 Transformer Block 取代 LSTM 做爲特徵提取器,實現了單向編碼,是一個標準的預訓練語言模型,即便用 Fine-Tuning 模式解決下游任務。
    • BERT 也是一個標準的預訓練語言模型,它以 \(P(w_i|w_1,\cdots,w_{i-1},w_{i+1},\cdots,w_n)\) 爲目標函數進行訓練,BERT 使用的編碼器屬於雙向編碼器
      • BERT 和 ELMo 的區別在於使用 Transformer Block 做爲特徵提取器,增強了語義特徵提取的能力;
      • BERT 和 GPT 的區別在於使用 Transformer Encoder 做爲 Transformer Block,而且將 GPT 的單向編碼改爲雙向編碼,也就是說 BERT 捨棄了文本生成能力,換來了更強的語義理解能力。

BERT 的模型結構以下圖所示:

從上圖能夠發現,BERT 的模型結構其實就是 Transformer Encoder 模塊的堆疊。在模型參數選擇上,論文給出了兩套大小不一致的模型。

\(BERT_{BASE}\) :L = 12,H = 768,A = 12,總參數量爲 1.1 億

\(BERT_{LARGE}\):L = 24,H = 1024,A = 16,總參數量爲 3.4 億

其中 L 表明 Transformer Block 的層數;H 表明特徵向量的維數(此處默認 Feed Forward 層中的中間隱層的維數爲 4H);A 表示 Self-Attention 的頭數,使用這三個參數基本能夠定義 BERT的量級。

BERT 參數量級的計算公式:

\[\begin{align*} & 詞向量參數+ 12 * (Multi-Heads參數 + 全鏈接層參數 + layernorm參數)\\ & = (30522+512 + 2)* 768 + 768 * 2 \\ & + 12 * (768 * 768 / 12 * 3 * 12 + 768 * 768 + 768 * 3072 * 2 + 768 * 2 * 2) \\ & = 108808704.0 \\ & \approx 110M \end{align*} \]

訓練過程也是很花費計算資源和時間的,總之表示膜拜,普通人即使有 idea 沒有算力也只能跪着。

13.3 BERT 之無監督訓練

和 GPT 同樣,BERT 也採用二段式訓練方法:

  1. 第一階段:使用易獲取的大規模無標籤餘料,來訓練基礎語言模型;
  2. 第二階段:根據指定任務的少許帶標籤訓練數據進行微調訓練。

不一樣於 GPT 等標準語言模型使用 \(P(w_i|w_1,\cdots,w_{i-1})\) 爲目標函數進行訓練,能看到全局信息的 BERT 使用 \(P(w_i|w_1,\cdots,w_{i-1},w_{i+1},\cdots,w_n)\) 爲目標函數進行訓練。

而且 BERT 用語言掩碼模型(MLM)方法訓練詞的語義理解能力;用下句預測(NSP)方法訓練句子之間的理解能力,從而更好地支持下游任務。

13.4 BERT之語言掩碼模型(MLM)

BERT 做者認爲,使用自左向右編碼和自右向左編碼的單向編碼器拼接而成的雙向編碼器,在性能、參數規模和效率等方面,都不如直接使用深度雙向編碼器強大,這也是爲何 BERT 使用 Transformer Encoder 做爲特徵提取器,而不使用自左向右編碼和自右向左編碼的兩個 Transformer Decoder做爲特徵提取器的緣由。

因爲沒法使用標準語言模型的訓練模式,BERT 借鑑完形填空任務和 CBOW 的思想,使用語言掩碼模型(MLM )方法訓練模型。

MLM 方法也就是隨機去掉句子中的部分 token(單詞),而後模型來預測被去掉的 token 是什麼。這樣實際上已經不是傳統的神經網絡語言模型(相似於生成模型)了,而是單純做爲分類問題,根據這個時刻的 hidden state 來預測這個時刻的 token 應該是什麼,而不是預測下一個時刻的詞的機率分佈了。

隨機去掉的 token 被稱做掩碼詞,在訓練中,掩碼詞將以 15% 的機率被替換成 [MASK],也就是說隨機 mask 語料中 15% 的 token,這個操做則稱爲掩碼操做。注意:在CBOW 模型中,每一個詞都會被預測一遍。

可是這樣設計 MLM 的訓練方法會引入弊端:在模型微調訓練階段或模型推理(測試)階段,輸入的文本中將沒有 [MASK],進而致使產生由訓練和預測數據誤差致使的性能損失。

考慮到上述的弊端,BERT 並無總用 [MASK] 替換掩碼詞,而是按照必定比例選取替換詞。在選擇 15% 的詞做爲掩碼詞後這些掩碼詞有三類替換選項:

  • 80% 練樣本中:將選中的詞用 [MASK] 來代替,例如:
「地球是[MASK]八大行星之一」
  • 10% 的訓練樣本中:選中的詞不發生變化,該作法是爲了緩解訓練文本和預測文本的誤差帶來的性能損失,例如:
「地球是太陽系八大行星之一」
  • 10% 的訓練樣本中:將選中的詞用任意的詞來進行代替,該作法是爲了讓 BERT 學會根據上下文信息自動糾錯,例如:
「地球是蘋果八大行星之一」

做者在論文中提到這樣作的好處是,編碼器不知道哪些詞須要預測的,哪些詞是錯誤的,所以被迫須要學習每個 token 的表示向量,另外做者也表示雙向編碼器比單項編碼器訓練要慢,進而致使BERT 的訓練效率低了不少,可是實驗也證實 MLM 訓練方法可讓 BERT 得到超出同期全部預訓練語言模型的語義理解能力,犧牲訓練效率是值得的。

13.5 BERT 之下句預測(NSP)

在不少天然語言處理的下游任務中,如問答和天然語言推斷,都基於兩個句子作邏輯推理,而語言模型並不具有直接捕獲句子之間的語義聯繫的能力,或者能夠說成單詞預測粒度的訓練到不了句子關係這個層級,爲了學會捕捉句子之間的語義聯繫,BERT 採用了下句預測(NSP )做爲無監督預訓練的一部分。

NSP 的具體作法是,BERT 輸入的語句將由兩個句子構成,其中,50% 的機率將語義連貫的兩個連續句子做爲訓練文本(連續句對通常選自篇章級別的語料,以此確保先後語句的語義強相關),另外 50% 的機率將徹底隨機抽取兩個句子做爲訓練文本。

連續句對:[CLS]今每天氣很糟糕[SEP]下午的體育課取消了[SEP]

隨機句對:[CLS]今每天氣很糟糕[SEP]魚快被烤焦啦[SEP]

其中 [SEP] 標籤表示分隔符。 [CLS] 表示標籤用於類別預測,結果爲 1,表示輸入爲連續句對;結果爲 0,表示輸入爲隨機句對。

經過訓練 [CLS] 編碼後的輸出標籤,BERT 能夠學會捕捉兩個輸入句對的文本語義,在連續句對的預測任務中,BERT 的正確率能夠達到 97%-98%。

13.6 BERT 之輸入表示

BERT 在預訓練階段使用了前文所述的兩種訓練方法,在真實訓練中通常是兩種方法混合使用

因爲 BERT 經過 Transformer 模型堆疊而成,因此 BERT 的輸入須要兩套 Embedding 操做:

  1. 一套爲 One-hot 詞表映射編碼(對應下圖的 Token Embeddings);
  2. 另外一套爲位置編碼(對應下圖的 Position Embeddings),不一樣於 Transformer 的位置編碼用三角函數表示,BERT 的位置編碼將在預訓練過程當中訓練獲得(訓練思想相似於Word Embedding 的 Q 矩陣)
  3. 因爲在 MLM 的訓練過程當中,存在單句輸入和雙句輸入的狀況,所以 BERT 還須要一套區分輸入語句的分割編碼(對應下圖的 Segment Embeddings),BERT 的分割編碼也將在預訓練過程當中訓練獲得

對於分割編碼,Segment Embeddings 層只有兩種向量表示。前一個向量是把 0 賦給第一個句子中的各個 token,後一個向量是把 1 賦給第二個句子中的各個 token ;若是輸入僅僅只有一個句子,那麼它的 segment embedding 就是全 0,下面咱們簡單舉個例子描述下:

[CLS]I like dogs[SEP]I like cats[SEP] 對應編碼 0 0 0 0 0 1 1 1 1

[SEP]I Iike dogs and cats[SEP] 對應編碼 0 0 0 0 0 0 0

十4、BERT 下游任務改造

BERT 根據天然語言處理下游任務的輸入和輸出的形式,將微調訓練支持的任務分爲四類,分別是句對分類、單句分類、文本問答和單句標註,接下來咱們將簡要的介紹下 BERT 如何經過微調訓練適應這四類任務的要求。

14.1 句對分類

給定兩個句子,判斷它們的關係,稱爲句對分類,例如判斷句對是否類似、判斷後者是否爲前者的答案。

針對句對分類任務,BERT 在預訓練過程當中就使用了 NSP 訓練方法得到了直接捕獲句對語義關係的能力。

以下圖所示,句對用 [SEP] 分隔符拼接成文本序列,在句首加入標籤 [CLS],將句首標籤所對應的輸出值做爲分類標籤,計算預測分類標籤與真實分類標籤的交叉熵,將其做爲優化目標,在任務數據上進行微調訓練。

針對二分類任務,BERT 不須要對輸入數據和輸出數據的結構作任何改動,直接使用與 NSP 訓練方法同樣的輸入和輸出結構就行。

針對多分類任務,須要在句首標籤 [CLS] 的輸出特徵向量後接一個全鏈接層和 Softmax 層,保證輸出維數與類別數目一致,最後經過 arg max 操做(取最大值時對應的索引序號)獲得相對應的類別結果。

下面給出句對分類似性任務的實例:

任務:判斷句子 「我很喜歡你」 和句子 「我很中意你」 是否類似

輸入改寫:「[CLS]我很喜歡你[SEP]我很中意你」

取 「[CLS]」 標籤對應輸出:[0.02, 0.98]

經過 arg max 操做獲得類似類別爲 1(類別索引從 0 開始),即兩個句子類似

14.2 單句分類

給定一個句子,判斷該句子的類別,統稱爲單句分類,例如判斷情感類別、判斷是否爲語義連貫的句子。

針對單句二分類任務,也無須對 BERT 的輸入數據和輸出數據的結構作任何改動。

以下圖所示,單句分類在句首加入標籤 [CLS],將句首標籤所對應的輸出值做爲分類標籤,計算預測分類標籤與真實分類標籤的交叉熵,將其做爲優化目標,在任務數據上進行微調訓練。

一樣,針對多分類任務,須要在句首標籤 [CLS] 的輸出特徵向量後接一個全鏈接層和 Softmax 層,保證輸出維數與類別數目一致,最後經過 argmax 操做獲得相對應的類別結果。

下面給出語義連貫性判斷任務的實例:

任務:判斷句子「海大球星飯茶吃」 是否爲一句話

輸入改寫:「[CLS]海大球星飯茶吃」

取 「[CLS]」 標籤對應輸出:[0.99, 0.01]

經過 arg max 操做獲得類似類別爲 0,即這個句子不是一個語義連貫的句子

14.3 文本問答

給定一個問句和一個蘊含答案的句子,找出答案在後這種的位置,稱爲文本問答,例如給定一個問題(句子 A),在給定的段落(句子 B)中標註答案的其實位置和終止位置。

文本問答任何和前面講的其餘任務有較大的差異,不管是在優化目標上,仍是在輸入數據和輸出數據的形式上,都須要作一些特殊的處理。

爲了標註答案的起始位置和終止位置,BERT 引入兩個輔助向量 s(start,判斷答案的起始位置) 和 e(end,判斷答案的終止位置)。

以下圖所示,BERT 判斷句子 B 中答案位置的作法是,將句子 B 中的每個次獲得的最終特徵向量 \(T_i'\) 通過全鏈接層(利用全鏈接層將詞的抽象語義特徵轉化爲任務指向的特徵)後,分別與向量 s 和 e 求內積,對全部內積分別進行 softmax 操做,便可獲得詞 Tok m(\(m\in [1,M]\))做爲答案其實位置和終止位置的機率。最後,去機率最大的片斷做爲最終的答案

文本回答任務的微調訓練使用了兩個技巧:

  1. 用全鏈接層把 BERT 提取後的深層特徵向量轉化爲用於判斷答案位置的特徵向量
  2. 引入輔助向量 s 和 e 做爲答案其實位置和終止位置的基準向量,明確優化目標的方向和度量方法

下面給出文本問答任務的實例:

任務:給定問句 「今天的最高溫度是多少」,在文本 「天氣預報顯示今天最高溫度 37 攝氏度」 中標註答案的起始位置和終止位置

輸入改寫:「[CLS]今天的最高溫度是多少[SEP]天氣預報顯示今天最高溫度 37 攝氏度」

BERT Softmax 結果:

篇章文本 天氣 預報 顯示 今天 最高溫 37 攝氏度
起始位置機率 0.01 0.01 0.01 0.04 0.10 0.80 0.03
終止位置機率 0.01 0.01 0.01 0.03 0.04 0.10 0.80

對 Softmax 的結果取 arg max,獲得答案的起始位置爲 6,終止位置爲 7,即答案爲 「37 攝氏度」

14.4 單句標註

給定一個句子,標註每一個次的標籤,稱爲單句標註。例如給定一個句子,標註句子中的人名、地名和機構名。

單句標註任務和 BERT 預訓練任務具備較大差別,但與文本問答任務較爲類似。

以下圖所示,在進行單句標註任務時,須要在每一個詞的最終語義特徵向量以後添加全鏈接層,將語義特徵轉化爲序列標註任務所需的特徵,單句標註任務須要對每一個詞都作標註,所以不須要引入輔助向量,直接對通過全鏈接層後的結果作 Softmax 操做,便可獲得各種標籤的機率分佈。

因爲 BERT 須要對輸入文本進行分詞操做,獨立詞將會被分紅若干子詞,所以 BERT 預測的結果將會是 5 類(細分爲 13 小類):

  • O(非人名地名機構名,O 表示 Other)
  • B-PER/LOC/ORG(人名/地名/機構名初始單詞,B 表示 Begin)
  • I-PER/LOC/ORG(人名/地名/機構名中間單詞,I 表示 Intermediate)
  • E-PER/LOC/ORG(人名/地名/機構名終止單詞,E 表示 End)
  • S-PER/LOC/ORG(人名/地名/機構名獨立單詞,S 表示 Single)

將 5 大類的首字母結合,可得 IOBES,這是序列標註最經常使用的標註方法。

下面給出命名實體識別(NER)任務的示例:

任務:給定句子 「愛因斯坦在柏林發表演講」,根據 IOBES 標註 NER 結果

輸入改寫:「[CLS]愛 因 斯坦 在 柏林 發表 演講」

BERT Softmax 結果:

BOBES 斯坦 柏林 發表 演講
O 0.01 0.01 0.01 0.90 0.01 0.90 0.90
B-PER 0.90 0.01 0.01 0.01 0.01 0.01 0.01
I-PER 0.01 0.90 0.01 0.01 0.01 0.01 0.01
E-PER 0.01 0.01 0.90 0.01 0.01 0.01 0.01
S-LOC 0.01 0.01 0.01 0.01 0.01 0.01 0.01

對 Softmax 的結果取 arg max,獲得最終地 NER 標註結果爲:「愛因斯坦」 是人名;「柏林」 是地名

14.5 BERT效果展現

不管如何,從上述講解能夠看出,NLP 四大類任務均可以比較方便地改形成 Bert 可以接受的方式,總之不一樣類型的任務須要對模型作不一樣的修改,可是修改都是很是簡單的,最多加一層神經網絡便可。這實際上是 Bert 的很是大的優勢,這意味着它幾乎能夠作任何NLP的下游任務,具有普適性,這是很強的。

可是講了這麼多,一個新模型好很差,效果纔是王道。那麼Bert 採用這種兩階段方式解決各類 NLP 任務效果如何?

在 11 個各類類型的 NLP 任務中達到目前最好的效果,某些任務性能有極大的提高。

十5、預訓練語言模型總結

到這裏咱們能夠再梳理下幾個模型之間的演進關係。

從上圖可見,Bert 其實和 ELMO 及 GPT 存在千絲萬縷的關係,好比若是咱們把 GPT 預訓練階段換成雙向語言模型,那麼就獲得了 Bert;而若是咱們把 ELMO 的特徵抽取器換成 Transformer,那麼咱們也會獲得Bert。

因此你能夠看出:Bert最關鍵兩點,一點是特徵抽取器採用 Transformer;第二點是預訓練的時候採用雙向語言模型。

那麼新問題來了:對於 Transformer 來講,怎麼才能在這個結構上作雙向語言模型任務呢?乍一看上去好像不太好搞。我以爲吧,其實有一種很直觀的思路,怎麼辦?看看 ELMO 的網絡結構圖,只須要把兩個 LSTM 替換成兩個 Transformer,一個負責正向,一個負責反向特徵提取,其實應該就能夠。

固然這是我本身的改造,Bert 沒這麼作。那麼 Bert 是怎麼作的呢?咱們前面不是提過 Word2Vec 嗎?我前面確定不是漫無目的地提到它,提它是爲了在這裏引出那個 CBOW 訓練方法,所謂寫做時候埋伏筆的 「草蛇灰線,伏脈千里」,大概就是這個意思吧?

前面提到了 CBOW 方法,它的核心思想是:在作語言模型任務的時候,我把要預測的單詞摳掉,而後根據它的上文 Context-Before 和下文 Context-afte r去預測單詞。

其實 Bert 怎麼作的?Bert 就是這麼作的。從這裏能夠看到方法間的繼承關係。固然 Bert 做者沒提 Word2Vec 及 CBOW 方法,這是個人判斷,Bert 做者說是受到完形填空任務的啓發,這也極可能,可是我以爲他們要是沒想到過 CBOW 估計是不太可能的。

從這裏能夠看出,在文章開始我說過 Bert 在模型方面其實沒有太大創新,更像一個最近幾年 NLP 重要技術的集大成者,緣由在於此,固然我不肯定你怎麼看,是否定同這種見解,並且我也不關心你怎麼看。其實 Bert 自己的效果好和普適性強纔是最大的亮點。

最後,我講講我對Bert的評價和見解,我以爲 Bert 是 NLP 裏裏程碑式的工做,對於後面 NLP 的研究和工業應用會產生長久的影響,這點毫無疑問。可是從上文介紹也能夠看出,從模型或者方法角度看,Bert 借鑑了 ELMO,GPT 及 CBOW,主要提出了 Masked 語言模型及 Next Sentence Prediction,可是這裏 Next Sentence Prediction 基本不影響大局,而 Masked LM 明顯借鑑了 CBOW 的思想。因此說 Bert 的模型沒什麼大的創新,更像最近幾年 NLP 重要進展的集大成者,這點若是你看懂了上文估計也沒有太大異議,若是你有大的異議,槓精這個大帽子我隨時準備戴給你。

若是概括一下這些進展就是:首先是兩階段模型,第一階段雙向語言模型預訓練,這裏注意要用雙向而不是單向,第二階段採用具體任務 Fine-tuning 或者作特徵集成;第二是特徵抽取要用Transformer 做爲特徵提取器而不是 RNN 或者 CNN;第三,雙向語言模型能夠採起 CBOW 的方法去作(固然我以爲這個是個細節問題,不算太關鍵,前兩個因素比較關鍵)。Bert 最大的亮點在於效果好及普適性強,幾乎全部 NLP 任務均可以套用 Bert 這種兩階段解決思路,並且效果應該會有明顯提高。能夠預見的是,將來一段時間在 NLP 應用領域,Transformer 將佔據主導地位,並且這種兩階段預訓練方法也會主導各類應用。

另外,咱們應該弄清楚預訓練這個過程本質上是在作什麼事情,本質上預訓練是經過設計好一個網絡結構來作語言模型任務,而後把大量甚至是無窮盡的無標註的天然語言文本利用起來,預訓練任務把大量語言學知識抽取出來編碼到網絡結構中,當手頭任務帶有標註信息的數據有限時,這些先驗的語言學特徵固然會對手頭任務有極大的特徵補充做用,由於當數據有限的時候,不少語言學現象是覆蓋不到的,泛化能力就弱,集成儘可能通用的語言學知識天然會增強模型的泛化能力。如何引入先驗的語言學知識其實一直是 NLP 尤爲是深度學習場景下的 NLP 的主要目標之一,不過一直沒有太好的解決辦法,而 ELMO/GPT/Bert 的這種兩階段模式看起來無疑是解決這個問題天然又簡潔的方法,這也是這些方法的主要價值所在。

對於當前 NLP 的發展方向,我我的以爲有兩點很是重要:

  1. 一個是須要更強的特徵抽取器,目前看 Transformer 會逐漸擔當大任,可是確定仍是不夠強的,須要發展更強的特徵抽取器;
  2. 第二個就是如何優雅地引入大量無監督數據中包含的語言學知識,注意我這裏強調地是優雅,而不是引入,此前至關多的工做試圖作各類語言學知識的嫁接或者引入,可是不少方法看着讓人牙疼,就是我說的不優雅。

目前看預訓練這種兩階段方法仍是頗有效的,也很是簡潔,固然後面確定還會有更好的模型出現。

完了,這就是預訓練語言模型的前世此生。

因爲我的剛入門 NLP 方向,就不妄自總結,上述總結所有來自知乎文章:從Word Embedding到Bert模型—天然語言處理中的預訓練技術發展史-張俊林

十6、參考資料

我只是知識的搬運工,想詳細瞭解各個知識點的讀者能夠自行選擇參考下列資料。

相關文章
相關標籤/搜索