github項目位址
0 代碼:
- Transformer
- BERT
1 Transformer
1.1 Self-Attention
1.1.1 基本原理

1.1.2 矩陣表示
1.1.3 多頭注意力
1.2 Positional Encoding
在self-attention中并沒有位置資訊,是以需要添加上位置資訊。
在詞嵌入後添加one-hot向量 p i p^i pi。
1.3 Transformer
Transformer 模型主要分為兩大部分,分别是 Encoder 和 Decoder。
編碼元件部分由一堆編碼器(encoder)構成(論文中是将6個編碼器疊在一起)。解碼元件部分也是由相同數量(與編碼器對應)的解碼器(decoder)組成的。
所有的編碼器在結構上都是相同的,但它們沒有共享參數。每個解碼器都可以分解成兩個子層。
從編碼器輸入的句子首先會經過一個自注意力(self-attention)層,這層幫助編碼器在對每個單詞編碼時關注輸入句子的其他單詞。我們将在稍後的文章中更深入地研究自注意力。
自注意力層的輸出會傳遞到前饋(feed-forward)神經網絡中。每個位置的單詞對應的前饋神經網絡都完全一樣(譯注:另一種解讀就是一層視窗為一個單詞的一維卷積神經網絡)。
在每個編碼器中的每個子層(自注意力、前饋網絡)的周圍都有一個殘差連接配接,并且都跟随着一個“層-歸一化”步驟。
解碼器中也有編碼器的自注意力(self-attention)層和前饋(feed-forward)層。除此之外,這兩個層之間還有一個注意力層,用來關注輸入句子的相關部分(和seq2seq模型的注意力作用相似)。
2 ELMo
ELMo 是 Embedding from Language Model 的縮寫,它通過無監督的方式對語言模型進行預訓練來學習單詞表示
它的思路是用深度的雙向 Language Model 在大量未标注資料上訓練語言模型,如下圖所示
3 GPT
Generative Pre-training Transformer
GPT 得到的語言模型參數不是固定的,它會根據特定的任務進行調整(通常是微調),這樣的到的句子表示能更好的适配特定任務。它的思想也很簡單,使用單向 Transformer 學習一個語言模型,對句子進行無監督的 Embedding,然後根據具體任務對 Transformer 的參數進行微調。GPT 與 ELMo 有兩個主要的差別:
- 模型架構不同:ELMo 是淺層的雙向 RNN;GPT 是多層的 transformer encoder
- 針對下遊任務的處理不同:ELMo 将詞嵌入添加到特定任務中,作為附加功能;GPT 則針對所有任務微調相同的基本模型
3.1 無監督的 Pretraining
這裡解釋一下上面提到的單向 Transformer。在 Transformer 的文章中,提到了 Encoder 與 Decoder 使用的 Transformer Block 是不同的。在 Decoder Block 中,使用了 Masked Self-Attention,即句子中的每個詞都隻能對包括自己在内的前面所有詞進行 Attention,這就是單向 Transformer。GPT 使用的 Transformer 結構就是将 Encoder 中的 Self-Attention 替換成了 Masked Self-Attention,具體結構如下圖所示
這裡的位置編碼沒有使用傳統 Transformer 固定編碼的方式,而是動态學習的
3.2 監督的 Fine-Tuning
Pretraining 之後,我們還需要針對特定任務進行 Fine-Tuning。
3.3 改造OpenAI GPT用于下遊NLP任務
針對不同任務,需要簡單修改下輸入資料的格式,例如對于相似度計算或問答,輸入是兩個序列,為了能夠使用 GPT,我們需要一些特殊的技巧把兩個輸入序列變成一個輸入序列
- Classification:對于分類問題,不需要做什麼修改
- Entailment:對于推理問題,可以将先驗與假設使用一個分隔符分開
- Similarity:對于相似度問題,由于模型是單向的,但相似度與順序無關,是以要将兩個句子順序颠倒後,把兩次輸入的結果相加來做最後的推測
- Multiple-Choice:對于問答問題,則是将上下文、問題放在一起與答案分隔開,然後進行預測
4 BERT
Bidirectional Encoder Representation from Transformer
Google 在預訓練 BERT 時讓它同時進行兩個任務:
- 漏字填空(完型填空),學術點的說法是 Masked Language Model
NLP model:Transformer(附ELMo、GPT、BERT)0 代碼:1 Transformer2 ELMo3 GPT4 BERT5 ELMo vs. GPT vs. BERT - 判斷第 2 個句子在原始本文中是否跟第 1 個句子相接(Next Sentence Prediction)
NLP model:Transformer(附ELMo、GPT、BERT)0 代碼:1 Transformer2 ELMo3 GPT4 BERT5 ELMo vs. GPT vs. BERT
4.1 Masked Language Model
在 BERT 中,Masked LM(Masked Language Model)建構了語言模型,簡單來說,就是随機遮蓋或替換一句話裡面的任意字或詞,然後讓模型通過上下文預測那一個被遮蓋或替換的部分,之後做 Loss 的時候也隻計算被遮蓋部分的 Loss,這其實是一個很容易了解的任務,實際操作如下:
- 随機把一句話中 15% 的 token(字或詞)替換成以下内容:
- 這些 token 有 80% 的幾率被替換成 [MASK],例如 my dog is hairy → \rightarrow →my dog is [MASK]
- 有 10% 的幾率被替換成任意一個其它的 token,例如 my dog is hairy → \rightarrow →my dog is apple
- 有 10% 的幾率原封不動,例如 my dog is hairy → \rightarrow →my dog is hairy
- 之後讓模型預測和還原被遮蓋掉或替換掉的部分,計算損失的時候,隻計算在第 1 步裡被随機遮蓋或替換的部分,其餘部分不做損失,其餘部分無論輸出什麼東西,都無所謂
這樣做的好處是,BERT 并不知道 [MASK] 替換的是哪一個詞,而且任何一個詞都有可能是被替換掉的,比如它看到的 apple 可能是被替換的詞。這樣強迫模型在編碼目前時刻詞的時候不能太依賴目前的詞,而要考慮它的上下文,甚至根據上下文進行 “糾錯”。比如上面的例子中,模型在編碼 apple 時,根據上下文 my dog is,應該把 apple 編碼成 hairy 的語義而不是 apple 的語義
4.2 Next Sentence Prediction
我們首先拿到屬于上下文的一對句子,也就是兩個句子,之後我們要在這兩個句子中加一些特殊的 token:
[CLS]上一句話[SEP]下一句話[SEP]
也就是在句子開頭加一個 [CLS],在兩句話之間和句末加 [SEP],具體地如下圖所示
可以看到,上圖中的兩句話明顯是連續的。如果現在有這麼一句話
[CLS]我的狗很可愛[SEP]企鵝不擅長飛行[SEP]
可見這兩句話就不是連續的。在實際訓練中,我們會讓這兩種情況出現的數量為 1:1
- Token Embedding 就是正常的詞向量,即 PyTorch 中的 nn.Embedding()
- Segment Embedding 的作用是用 embedding 的資訊讓模型分開上下句,我們給上句的 token 全 0,下句的 token 全 1,讓模型得以判斷上下句的起止位置
- Position Embedding 和 Transformer 中的不一樣,不是三角函數,而是學習出來的
BERT 預訓練階段實際上是将上述兩個任務結合起來,同時進行,然後将所有的 Loss 相加
4.3 Fine-Tuning
4.3.1 classification
如果現在的任務是 classification,首先在輸入句子的開頭加一個代表分類的符号 [CLS],然後将該位置的 output,丢給 Linear Classifier,讓其 predict 一個 class 即可。整個過程中 Linear Classifier 的參數是需要從頭開始學習的,而 BERT 中的參數微調就可以了
4.3.2 Slot Filling
将句子中各個字對應位置的 output 分别送入不同的 Linear,預測出該字的标簽。其實這本質上還是個分類問題,隻不過是對每個字都要預測一個類别
4.3.3 NLI
即給定一個前提,然後給出一個假設,模型要判斷出這個假設是 正确、錯誤還是不知道。這本質上是一個三分類的問題,和 Case 1 差不多,對 [CLS] 的 output 進行預測即可
4.3.4 QA
舉例來說,如上圖,将一篇文章,和一個問題(這裡的例子比較簡單,答案一定會出現在文章中)送入模型中,模型會輸出兩個數 s,e,這兩個數表示,這個問題的答案,落在文章的第 s 個詞到第 e 個詞。具體流程我們可以看下面這幅圖
首先将問題和文章通過 [SEP] 分隔,送入 BERT 之後,得到上圖中黃色的輸出。此時我們還要訓練兩個 vector,即上圖中橙色和藍色的向量。首先将橙色和所有的黃色向量進行 dot product,然後通過 softmax,看哪一個輸出的值最大,例如上圖中 d 2 d_2 d2對應的輸出機率最大,那我們就認為 s=2
同樣地,我們用藍色的向量和所有黃色向量進行 dot product,最終預測得 d 3 d_3 d3的機率最大,是以 e=3。最終,答案就是 s=2,e=3
5 ELMo vs. GPT vs. BERT
ELMo 和 GPT 最大的問題就是傳統的語言模型是單向的 ——我們根據之前的曆史來預測目前詞。但是我們不能利用後面的資訊。
預訓練模型架構的差異。 BERT使用雙向Transformer。 OpenAI GPT使用從左到右的Transformer。 ELMo使用經過獨立訓練的從左到右和從右到左的LSTM的串聯來生成用于下遊任務的功能。在這三個之中,隻有BERT表示在所有層中同時受左右上下文的制約。除了架構差異之外,BERT和OpenAI GPT是微調方法,而ELMo是基于特性的方法。