从 Word2Vec 到 BERT
作者丨張寒
學校丨復旦大學碩士生
研究方向丨自然語言處理
如果讀完本文你覺得對數學公式很懵,強烈建議去 Jay Alammar 的博客看一下,他的博客主要是對每個概念做可視化的,看了會茅塞頓開,簡直是寶藏!每篇文章我也會放上他相對應的概念的地址。
1
Word2Vec
The Illustrated Word2Vec:
https://jalammar.github.io/illustrated-word2vec/
“You shall know a word by the company it keeps” (J. R. Firth 1957: 11)
一種重要的語言學思想是 Firth 在 1957 年提出的,一個詞語的意思應該由它的上下文來表示。
在 word2vec 出現之前,一種簡單的對詞的表示是 One-hot 向量表示,即一個位置是 1,其余位置都是 0,這種表示方法的最大缺點在于沒辦法表示出詞語之間的相似性。
到了 2013 年,Tomas Mikolov 連放幾篇劃時代的論文,其中最為重要的是兩篇,[1] 首次提出了 CBOW 和 Skip-gram 模型,進一步的在 [2] 中,又介紹了幾種優化訓練的方法,包括 Hierarchical Softmax(當然,這個方法早在 2003 年,Bengio 就在他提出 NNLM 論文中的 Future Work 部分提到了這種方法,并于 2005 年把它系統化發表了一篇論文), Negative Sampling 和 Subsampling 技術。
放出兩篇論文后,當時仍在谷歌工作的 Mikolov 又馬不停蹄的放出了大殺器——word2vec 工具,并在其中開源了他的方法。順便提一下的是,很多人以為 word2vec 是一種模型和方法,其實 word2vec 只是一個工具,背后的模型是 CBOW 或者 Skip-gram,并且使用了 Hierarchical Softmax 或者 Negative Sampling 這些訓練的優化方法。所以準確說來,word2vec 并不是一個模型或算法,只不過 Mikolov 恰好在當時把他開源的工具包起名叫做 word2vec 而已。
Language Models
首先,我們需要建立一個模型來表示一個句子的出現的概率,例如“The cat jumped over the puddle”,一個好的語言模型會給這樣一個句子高的概率,因為這個句子是通順的沒有語法錯誤的,而“stock boil fish is toy”就會得到一個很低的概率,我們記 n 個詞組成的一個句子序列的概率為:
如果假設所有的詞都是相互獨立的,那么就叫做 unigram 模型:
但是我們知道每一個詞不會是獨立的,它和前面的詞是有很大關系的,那么假設每一個詞與前一個詞相關,就得到 bigram 模型:
以此類推,但這樣的模型有著明顯的缺點:1)缺乏長期的依賴,因為只能建模到 n-1 個詞;2)隨著 n 的加大,計算和存儲要求呈指數上漲;3)單純基于統計詞頻,泛化能力差。
語言模型讓我們理解了一個序列怎么用概率來表示,接下來我們看兩個可以學習這些概率的模型。
CBOW
在前面舉的例子中,對于句子“The cat jumped over the puddle”,我們把 {“The", "cat","over","the","puddle"} 當作上下文,把“jumped”當作中心詞,這樣的一種模型叫做 Continuous Bag of Words (CBOW) Model。
我們創建兩個矩陣,和,其中 n 是提前定義好的任意長度的向量空間的大小,V 是輸入詞矩陣,第 i 列表示的是詞的 n 維向量表示,我們記第 i 列為,同樣的,U 是輸出詞矩陣,第 j 行表示的是詞的 n 維向量表示,我們記第 j 行為,值得注意的是這里每一個詞其實會學習兩個向量,其實簡單的說 CBOW 就是根據上下文來預測中心詞,而每一個詞會學習到兩個向量,一個是詞出現在上下文時的向量 input vector v,和詞出現在中心詞時的向量 output vector u。
下面我們來具體看看 CBOW 是怎么做的:
1. 首先我們生成大小為 m 的上下文詞的 one-hot 向量表示:,這里面每一個 x 是一個 |V|x1 維的上下文單詞的 one-hot 表示,前面 m/2 個,后面 m/2 個;
2. 通過與 V 矩陣相乘,得到每一個上下文詞的詞向量表示,即:
3. 對所有的上述向量做平均,得到:
4. 通過這個均值向量和 U?矩陣相乘,去得到一個”分數向量“,即,因為相似向量的點乘結果是很高的,所以優化模型時就會把相似詞的向量表示越來越靠近,去得到一個高的分數;
5. 把分數轉變成概率表示;
6. 我們希望產生的這個概率分布,跟真實的概率分布很接近,這個真實概率分布其實也就是真實中心詞的 One-hot 向量表示,所以其實就是希望真實中心詞的預測概率接近 1。
以上就是在我們如果有 V, U 矩陣時,模型是如何工作的,那么怎么得到這個兩個矩陣呢?首先建立一個目標函數,這里使用交叉熵:
實際上 y 是 One-hot 向量,所以可以簡化為:
而,,綜上最小化目標函數就等價于得到預測中心詞最好的那個模型的參數,也就是 V, U?矩陣:
接下來用 SGD 優化目標函數,去更新所有相關的詞向量和:
Skip-gram
另一種方法是給定中心詞"jumped",模型會去預測或者生成周圍的上下文詞,這種模型叫做 Skip-gram model,SG 和 CBOW 是完全反過來的模型,我們首先有一個中心詞的 one-hot 向量表示 x,然后輸出詞的向量表示是,U, V 矩陣和前面 CBOW 中一樣:
1. 首先生成中心詞的 ont-hot 向量,;
2. 通過和 V 矩陣相乘得到中心詞的詞向量表示;
3. 通過和 U 矩陣相乘得到“分數向量”,;
4. 把“分數”轉變成概率,這里,要轉變成 2m 個 |V|x1 的上下文詞的向量;
5. 我們希望以上結果,跟真實概率足夠的接近。
不同于 CBOW,SG 在生成目標函數的時候用了一個假設,假設給定中心詞,所有輸出的詞都是完全獨立的。
通過這樣的目標函數,用 SGD 去迭代更新參數,同時目標函數也可以記為:
Optimization Method
Mikolov 對于 SG 的評價是這些公式是“impractical”的,他的言下之意是計算復雜度依然和詞典大小有關,而這通常都意味著非常非常大,于是在論文 [2] 中首先提到了 Hierachical Softmax,基本思想就是首先將詞典中的每個詞按照詞頻大小構建出一棵 Huffman 樹,保證詞頻較大的詞處于相對比較淺的層,詞頻較低的詞相應的處于 Huffman 樹較深層的葉子節點,每一個詞都處于這棵 Huffman 樹上的某個葉子節點。
接著提出了 Negative Sampling 負采樣的思想,普通 softmax 的計算量太大就是因為它把詞典中所有其他非目標詞都當做負例了,而負采樣的思想特別簡單,就是每次按照一定概率隨機采樣一些詞當做負例,從而就只需要計算這些負采樣出來的負例了。
對于 SG,新的目標函數變成了:
對于 CBOW,新的目標函數變成了:
仔細和普通 softmax 進行比較便會發現,將原來的 |V| 分類問題變成了 K 分類問題,這便把詞典大小對時間復雜度的影響變成了一個常數項。
GloVe
上述 word2vec 方法,缺點是基于固定大小的窗口,對局部的語料進行特征提取,其實在 word2ve c出現之前, LSA(Latent Semantic Analysis)是一種比較早的 count-based 的詞向量表征工具,它也是基于 co-occurance matrix 的,只不過采用了基于奇異值分解(SVD)的矩陣分解技術對大矩陣進行降維,而我們知道 SVD 的復雜度是很高的,所以它的計算代價比較大。還有一點是它對所有單詞的統計權重都是一致的 ,而 GloVe 就結合了兩者的優點。
GloVe 的實現:?
1. 首先根據語料庫去構建一個 co-ocurrence matrix 共現矩陣,其中每一個元素代表單詞和上下文詞在特定的上下文窗口內共同出現的次數,并且 GloVe 還提出了一個 decreasing weighting ,就是基于兩個詞在上下文窗口中的距離 d,去給一個權重 1/d,也就是說距離遠的兩個詞,占總計數的權重就小;
2. 構建詞向量和共現矩陣之間的近似關系,目標函數為:?
其中:
這個目標函數基本形式就是簡單的 mean square loss,只不過多了一個權重函數,感興趣的話 [3] 中可以看下作者是怎么得到這個公式的。
word2vec 的方法極大的促進了 NLP 的發展,利用預訓練好的詞向量來初始化網絡結構的第一層幾乎已經成了標配,尤其是在只有少量監督數據的情況下,如果不拿預訓練的 embedding 初始化第一層,要么你是土豪,可以有大量的人工去標注數據,要么就是在蠻干。word2vec 開啟了一種全新的 NLP 模型訓練方式,遷移學習。
Reference
[1] https://arxiv.org/pdf/1301.3781.pdf
[2] http://papers.nips.cc/paper/5021-distributed-representations-of-words-and-phrases-and-their-compositionality.pdf
[3] https://nlp.stanford.edu/pubs/glove.pdf
[4]?http://web.stanford.edu/class/cs224n/
[5] https://zhuanlan.zhihu.com/p/50443871
2
Transformer
The Illustrated Transformer:
https://jalammar.github.io/illustrated-transformer/
Seq2Seq + Attention
在說明 Transformer 之前,還是有必要簡述一下 attention 機制,RNN, LSTM, Seq2Seq 就不再贅述。
我們知道 Seq2Seq 是由一個 encoder 和一個 decoder 構成, 編碼器負責把源序列編碼成向量,解碼器是一個語言模型,負責根據編碼的信息生成目標序列 。這個結構的問題在于,編碼器需要把整個 Source sentence 的信息全部編碼起來,這是 seq2seq 架構的瓶頸所在,attention 機制就是解決這個瓶頸的一種方法,Attention 機制的核心想法就是:在解碼器的每一個時間步,都和編碼器直接連接,然后只關注 source sentence 中的特定的一部分。
假設編碼器的 hidden states 分別為。在解碼器的第一個時間步,解碼器的 hidden state 為,我們通過點乘得到當前時間步的 attention scores:
再通過 softmax 轉換成 attention distribution(是一個概率分布,和為 1):
然后用這個概率分布去和編碼器的所有 hidden states 加權求和,得到 attention output:
最后把 attention output 和解碼器的 hidden state 合并起來得到,然后去執行不用 attention 機制的 seq2seq 一樣的做法就好了。
這樣就得到了解碼器的第一個時間步的輸出,后面以此類推,每一個時間步都會去“看一下”source sentence,去決定對哪一部分給予比較大的 attention。
這就是 seq2seq+attention 機制的概念,然后這樣的結構終歸是要按照序列順序去 encoding 的,不好做分布式的計算,于是有了直接拋棄 RNN,LSTM 的 self-attention 機制,以及應用了這個機制的 Transformer [1]。
Transformer Architecture
大多數有效的處理序列的模型都是基于 encoder-decoder 架構的,給定序列 x,經過 encoder 編碼成隱藏向量 z,再通過 decoder 每個時間步的去生成序列 y,Transformer 通過在 encoder 和 decoder 中都使用堆疊的 self-attention 和 point-wise 和全連接層,來延續了這樣的整體架構:
Encoder and Decoder Stacks?
Encoder:編碼器是由 6 個相同的層組成,每一層有兩個子層,第一個子層是一個 Multi-head self-attention 機制,第二層是一個簡單的,位置對應的全連接神經網絡,還加入了每一個子層都加入了殘差網絡 + normalization 層,所以每一個子層的輸出其實可以看作,Sublayer(x) 是子層自己的函數,為了容易計算這些殘差層,模型中的所有子層,包括 embedding 層,輸出都是維。
Decoder:解碼器也是由 6 個相同的層組成,在編碼器的那兩個子層的基礎上又加入了一個層,用于對 encoder 的輸出做 multi-head attention,和 encoder 一樣,每一個子層也都加入了殘差結構和標準化層,還加入 mask 操作。
Decoder 的 attention 實際上包含兩部分,第一部分是帶有 mask 的 Self-attention,通過 mask 的作用將 decode 階段的 attention 限定只會 attention 到已經生成過的詞上,因此叫做 Mask Self-attention;第二部分是普通的 Self-attention 操作,不過這個時候的 K 和 V 矩陣已經替換為 Encoder 的輸出結果,所以本質上并不是一個 Self-attention 了,self-attention 的 Q, K, V 都來自于自身。?
不懂沒關系,下面來詳細剖析下 Transformer 的結構:?
首先把 input sentence 做 input embedding 后的結果當作輸入給第一個 encoder,這里有一個 positional encoding 稍后再說,那么到達第一個 encoder 的第一個 sub-layer,下面我們先說下什么是 Self-Attention。
Self-Attention in Detail
一個 attention 內部機制可以看作一個 query,應用到一組 key-value 對上的操作,其中一個 query 和所有 keys, values 都是向量,結果可以看作是對 values 的加權求和,其中每個 value 的權重是通過當前 query 和對應的 key 做點乘得到的(Scaled Dot-Product Attention), 而 Multi-Head Attention 就是多個 attention layer 并行計算的。
接下來首先看單個 self-attention 如何使用這些向量去計算:
1. 第 1 步,為每一個 encoder 的輸入向量 x 創建 3 個向量,分別為 query, key, value,怎么來的呢?就是用輸入向量和三個權重矩陣相乘,得到三個向量 q, k, v;
2. 第 2 步是計算“分數”,假設我們在計算 self-attention 中的第一個詞,這時我們要計算輸入序列中所有其他詞和第一個詞之間的“分數”,“分數”決定了我們在 encode 第一個詞的時候,對其他詞分別給多少的“關注度”,“分數”是通過 q, k 的點乘計算的,比如當在 encode 第一個詞時,就需要把 q1 和每一個位置的 k 點乘,得到“分數”矩陣,如第一個分數是 q1k1,第二個分數是 q1k2......;
3. 第 3、4 步是把分數除以,即除以 k 向量的維度開根號,paper 中用的,所以就是除以 8,這樣可以得到更多穩定的梯度,然后把分數矩陣通過 softmax 轉變成概率,這個概率衡量了你想要表達多少某一個位置這個詞的信息。顯然,當前位置的詞會得到最大的 softmax score,但是有時在關注與當前位置相關的另一個詞時是有用的;
4. 第 5 步,把 softmax score 和每一個 value 向量相乘,目的是保留一些想要關注的部分,拋棄不相關的部分,比如乘 0.0001;
5. 第 6 步,把上述加權 value 向量求和,這樣就得到了 self-attention 層的在當前位置的輸出(比如第一個詞)。
實際的使用中,往往輸入的是一個矩陣 X,那么把 q, k, v 都換成矩陣就好了記一組 queries 為矩陣 Q,keys 和 values 也表示成矩陣和,我們的輸出可以記為:
Multi-Head Attention?
作者還介紹了一種 Multi-head attention 機制,這個機制在兩個方面提升了表現:?
1. 它擴展了模型關注不同的位置的能力。確實,在前面單個詞的例子中已經說過,對第一個詞得到的結果 z1,雖然也能給每一個詞一些權重,但是顯然是它自己的權重最大,這個在翻譯比如:“ The animal didn’t cross the street because it was too tired ”時有用,我們想知道“it”指代的是誰;
2. 它給了 attention layer 多個“表示子空間”,Multi-head attention 不是一組,而是多組權重矩陣(paper 中是 8 個),每一組開始時都是隨機初始化的,然后訓練模型,每一組都會把輸入 embedding 向量或者是低一級的 encoders/decoders 的輸出向量,映射到不同的表示子空間。
用這樣的機制,我們得到了 8 個不同的 Z 輸出矩陣,然后下一個 deed-forward layer 只接受一個矩陣(每一行是一個詞的向量),所以我們這樣處理:?
直接把 8 個輸出矩陣拼接起來,再與一個權重矩陣 WO 相乘,得到一個輸出矩陣,這個句子收集到了所有 attention heads 的信息,我們把這個發給后面的 FFNN。
整個流程如下圖:
The Residuals and Normalization Layer?
至此我們以及知道第一個 encoder 的第一個 sub-layer 里 Multi-head attention 是怎么回事,接下來以上生成的 Z 矩陣還要通過一個殘差 + normalization 層,所以第一個子層的輸出其實可以看作 LayerNorm (x+MultiHead(x))。
再接下來到第二個 sub-layer,是一個 Feed Forward Neural Netword,加上跟第一個子層相同的殘差 + normalization 層,所以第二個子層可以看作 LayerNorm (x+FFNN(x)),這里值得注意的是,全連接層對于 Z 矩陣中的每一個向量是分布式進行的,不過權重是一樣的,下圖很好的說明了這一點:
現在我們已經完全縷清第一個 encoder 是怎么樣進行的,后面的 5 個 encoder 都以此類推,到最后一個 encoder 產生的結果,會被 decoder 使用,至此 encoding 部分結束,接下來看 decoding 才是重頭戲。
decoder 首先接受第一個輸入,一般是一個起始符例如 </s>,這是來到第一個 decoder 的第一個 sub-layer,這里跟前面說的 encoder 的 Multi-Head Attention,都屬于 self-attention,區別是這里加了一個 Mask 操作,讓輸出序列只能基于當前位置的前面的序列做預測,具體做法是給后面序列一個負無窮的分數,這樣在計算 softmax 時就是 0。
到了第一個 decoder 的第二個 sub-layer,這里的“Encoder-Decoder Attention”layer,實際上不屬于 self attention,因為它的 queries 來自下面的 sub-layer 的輸出,而 keys 和 values 來自 encoder 的輸出 Z,Z 會 transformed into a set of K, V,提供給 6 個的每一個 decoder 中間的“Encoder-Decoder Attention”layer 使用。
接下來第一個 decoder 的 FFNN 層,和前面 encoder 的一樣,不再贅述。
至此一個 decoder 的內部結構結束,重復 6 個一樣的 decoder 后,來到了最后的 Linear and Softmax Layer。
The Final Linear and Softmax Layer?
The Linear layer 是一個簡單的全連接神經網絡,把 decoders 生成的輸出,映射到一個很大的向量,叫做 Logits vector。
假設模型訓練集有 10000 個唯一的英文單詞,那 Logits vector 就有 10000 個單元,每個單元表示唯一單詞的分數,再經過一個 softmax 層,把分數轉變成概率,最高概率的單詞將被選擇出來,作為當前時間步的輸出。
Positional Encoding?
補充一點前面沒說的,已我們前面敘述的做法,input sentence 的順序信息被完全忽略了,然而往往這個信息還是很有用的,所以加入了一個 positional encoding 機制,即給每個 input embedding 在額外加上一個位置向量,位置向量會在詞向量中加入了單詞的位置信息,這樣 Transformer 就能區分不同位置的單詞了。
這個位置向量怎么來呢?有兩種辦法:1)基于數據去學習;2)自己設計編碼規則,作者采用的是第二種,給出的是如下公式:
至于實現可以去 Google 開源的 tensor2tensor 里的 get_timing_signal_1d() 函數去找:
https://github.com/tensorflow/tensor2tensor/blob/23bd23b9830059fbc349381b70d9429b5c40a139/tensor2tensor/layers/common_attention.py
結論
以上為 Transformer 的整個 forward pass 的過程,訓練過程中再去做 backward pass 更新參數,值得一提的是在選擇最終 output sentence 有兩種辦法 greedy search 或 beam search,這個在我上文對 Attention 機制的理解里有提到過。
Reference
[1]?https://jalammar.github.io/illustrated-transformer/
[2]?https://arxiv.org/abs/1706.03762
[3]?http://web.stanford.edu/class/cs224n/
[4]?https://zhuanlan.zhihu.com/p/50443871
3
BERT
The Illustrated BERT:
https://jalammar.github.io/illustrated-bert/
Introduction
語言模型在很多 NLP tasks 上都很有用,其中包括句子級別的任務,分析句子之間的關系,也有單詞級別的任務,比如命名實體識別,問答系統。
在 BERT (Bidirectional Encoder Representations from Transformers) 出現之前,有兩種在下游任務應用 pre-trained 語言表示的方法,分別是以 ELMo 為代表的 feature-based 方法,在特定任務使用特定結構,其中包含 pre-trained 表示好的特征作為附加特征,還有一種 fine-tuning 方法,以 GPT 為代表,在下游任務中用簡單的 fine-tuning 來訓練之前所有 pre-trained 的參數。兩種方法在 pre-training 時目標函數是一致的,都使用單向語言模型去學習語言表示。?
而單向的標準語言模型,嚴重限制了尤其是 fine-tuning 類方法的語言表示能力,有的模型里例如 GPT,使用從左到右的結構,在 Transformer 的 self-attention layer 每個詞只能注意之前出現過的詞,這種優化是句子級別的,當應用到單詞級別的任務時又是不對的,每個詞應該和上下文都有關,所以構建雙向結構來關聯上下文是很重要的。
BERT
整個 BERT 分為兩步,pre-training 和 fine-tuning,在 pre-training 部分,在不同的 pre-training 任務中在未標記數據上進行訓練,在 fine-tuning 部分,模型先使用 pre-trained 的參數初始化,然后在下游任務中用標記數據對所有參數進行微調,雖然初始化用的都是相同的 pre-trained 參數,但是在下游不同任務中可以有不同的 fine-tuned 模型。
Model Architecture:BERT 作者使用的 Transformer 就是之前說過的普通的 Transformer,作者構建了兩個模型,一個 BERT BASE,12 個 Transformer 模塊層,768 個隱層,12 個 self-attention 中的 head,總參數 110M,一個 BERT LARGE,24 個 Transformer 模塊層,1024 個隱層,16 個 self-attention 中的 head,總參數 340M。
Input/Output Representations:為了使 BERT 能適應各式各樣的下游任務,我們的輸入表示要能夠用一個序列清晰的同時可以表示一個單句子和一個句子對(比如(問題,答案)),這時在 BERT 中的“sequence”不再是單一的語言意義上的一個句子,而是任意跨度的連續文本。
在序列開頭永遠放一個 [CLS] 標記,在分類任務的時候這個表示類別,不是分類任務可以忽略,對于句子對,用了兩個方法區分,第一,每個句子后插如一個 [SEP] 標記,第二,加入一個序列向量用來區分一個詞是屬于句子 A 還是句子 B。
實際最后的 input embedding,是三部分向量相加,單詞本身的 Token embedding,單詞歸屬信息的 segment embedding,位置信息的 position embeddings,這里的位置信息,在前面說 Transfomer 時提過,有兩種方法:1)自己訓練;2)自己編碼,Transformer 使用的是第二種,奇怪的 sin、cos 函數編碼位置 ,而這里用的是第一種,初始化,完了也加入到訓練參數中自己去 train。
Pre-training BERT
BERT 使用兩個非監督任務來 pre-train 模型。
TASK1 Masked LM:
為了訓練深度雙向模型,作者使用了一種隨機掩蓋一定百分比的輸入詞的方法,然后去預測這些被掩蓋的詞,叫做“Masked LM” (MLM),其實就可以想象成是完形填空,在作者實驗中使用的是 15% 的詞,也就是說有隨機選擇的 15% 的詞會被 masked 掉,然后去預測這些被 masked 掉的詞是什么,這時實際上已經變成一個單純分類問題了,不是傳統意義上的生成語言模型了,根據這個位置的 hidden state 預測是什么 token,而不是預測下一個詞的概率了。
雖然這樣可以建立一個雙向預訓練模型,但是缺點是這樣預訓練階段和微調階段就產生了不匹配的問題,因為 mask token 在微調階段不會出現,也就是說在預訓練階段你是加了 [mask] 的去訓練,而微調階段沒有加 [mask] 訓練,為了盡可能的把模型調教的忽略這些標記的影響,作者通過如下方式來告訴模型這些是噪聲,請忽略它:?
如果一個 token 被選中,那么我們把這個 token:
1. 80% 的時間換成 [MASK] 標記,即掩蓋掉;
2. 10% 的時間隨機換成另外一個詞(還是要預測正確的詞的);
3. 10% 的時間不變,仍然是原詞 (還是要預測該位置的詞的)。
還有一個問題是只有 15% 的詞被預測,而傳統語言模型是每一個詞都會被預測的,所以 MLM 收斂比較慢。
如上圖,用來通過 cross-entropy 預測原來這個位置的 token 是什么,屬于 Mask LM 任務。
TASK2 Next Sentence Prediction:?
很多下游任務比如 QA,NLI (Natural Language Inference) 都是基于對兩個句子之間的關系去理解的,但是在語言模型里沒有捕捉到這個信息,BERT 中就為了解決這個問題,加了一個 NSP 訓練任務,50% 的時間選擇句子 A 真正的下一個句子 B 作為一個句子對(標記為 IsNext),50% 的時間選擇句子 A 和隨機句子作為句子對(標記為 NotNext),訓練數據就是這樣,雖然很簡單,但是很有效,有點句子級別的負采樣的味道。
如上圖,句子級別的信息被 encoding 在 [CLS] 標記里,這個做法乍一看有點費解,其實 Transformer 是可以無視空間和距離的把全局信息 encoding 進每個位置的,而 [CLS] 作為句子/句對的表示是直接跟分類器的輸出層連接的,因此其作為梯度反傳路徑上的“關卡”,當然會想辦法學習到分類相關的上層特征,如上圖 C,用來做 NSP 任務。
Fine-tuning BERT
對于每個任務,我們只需將特定于任務的輸入和輸出插入 BERT 并對所有參數進行端到端的 fine-tune。
在 fine-tuning 之前只需根據特定任務對結構做簡單的改變,例如針對句子級別的分類任務(例如情感分析),取第一個 [CLS] 的輸出表示,傳給一個 softmax 層得到分類結果輸出;對于單詞級別的分類(例如 NER),取所有 token 的最后層 transformer 輸出,傳給 softmax 層做分類,總之改變都很簡單,就加一層神經網絡就好了。
然后微調很簡單,因為 Transformer 中的 self-attention 機制允許 BERT 通過改變適當的輸入和輸出來對許多下游任務(無論它們涉及單個文本還是文本對)進行建模。
結論
BERT 使用了 MLM+NSP 的多任務學習模式,并利用 Transformer 的 self-attention 機制實現雙向功能,設計了更通用的輸入層和輸出層,適配了多任務下的遷移學習
關于 BERT 還有很多細節沒有深入,后續會再繼續深入。
點擊以下標題查看更多往期內容:?
深度長文:NLP的巨人肩膀(上)
NLP 的巨人肩膀(下):從 CoVe 到 BERT
站在BERT肩膀上的NLP新秀們
后BERT時代的那些NLP預訓練模型
自然語言處理中的語言模型預訓練方法
從三大頂會論文看百變Self-Attention
#投 稿 通 道#
?讓你的論文被更多人看到?
如何才能讓更多的優質內容以更短路徑到達讀者群體,縮短讀者尋找優質內容的成本呢?答案就是:你不認識的人。
總有一些你不認識的人,知道你想知道的東西。PaperWeekly 或許可以成為一座橋梁,促使不同背景、不同方向的學者和學術靈感相互碰撞,迸發出更多的可能性。?
PaperWeekly 鼓勵高校實驗室或個人,在我們的平臺上分享各類優質內容,可以是最新論文解讀,也可以是學習心得或技術干貨。我們的目的只有一個,讓知識真正流動起來。
?????來稿標準:
? 稿件確系個人原創作品,來稿需注明作者個人信息(姓名+學校/工作單位+學歷/職位+研究方向)?
? 如果文章并非首發,請在投稿時提醒并附上所有已發布鏈接?
? PaperWeekly 默認每篇文章都是首發,均會添加“原創”標志
???? 投稿郵箱:
? 投稿郵箱:hr@paperweekly.site?
? 所有文章配圖,請單獨在附件中發送?
? 請留下即時聯系方式(微信或手機),以便我們在編輯發布時和作者溝通
????
現在,在「知乎」也能找到我們了
進入知乎首頁搜索「PaperWeekly」
點擊「關注」訂閱我們的專欄吧
關于PaperWeekly
PaperWeekly 是一個推薦、解讀、討論、報道人工智能前沿論文成果的學術平臺。如果你研究或從事 AI 領域,歡迎在公眾號后臺點擊「交流群」,小助手將把你帶入 PaperWeekly 的交流群里。
▽ 點擊 |?閱讀原文?| 獲取最新論文推薦
總結
以上是生活随笔為你收集整理的从 Word2Vec 到 BERT的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 语音识别:繁华背后,危机初现
- 下一篇: 各国五代机发动机寿命