前篇介紹的 transformer 在很多 NLP task 打破了 state-of-the-art results,取得了大躍進。而以 transformer 為架構簡單改良的 BERT 更是再度打破了 11 項 NLP task 的 state-of-the-art,再次讓 NLP 往前飛越。
我們一起來看看 BERT 做了什麼改良。
在 Day 10 介紹 word embedding 時簡單提過 ELMo。他跟以往的 word embedding 不同在於他能夠依據一個字在句中的 context 給出不同 embedding,我們稱之為 contextual embedding 或 context-dependent embedding。而更早前的 Word2Vec 和 GloVe 就沒有這種能力,稱之為 context-independent embedding。
ELMo 的架構基礎為 bidirectional LSTM。也就是訓練雙向的 LSTM layers,最後合併結果作為該字的 word embedding。
但這樣的架構雖然有效取得了雙向的資訊以及品質更好的 embedding,他雙向的學習法卻有些膚淺,兩邊你學你的、我學我的,之後直接結合,等於前後方向的資訊沒有多少交流。不過這也不能怪他,因為 RNN 架構上也很難實現深度交流。
不過還記得 transformer 的 encoder 怎麼對 input 進行 encoding 的嗎?沒錯,就是 self-attention。Self-attention 能讓 input 的每個字跟前後所有人都互動到,也因此最後的 embedding 是經過深度交流的。
BERT 就是以此為啟發改進之後的 model,能訓練出更好的 contextual embedding。接著我們就來看看他的架構。
BERT (Bidirectional Encoder Representations from Transformers),和 ELMo 同為兒童節目《芝麻街》的角色。(欸不是,到底為什麼都這樣取名)
從 BERT 的名字就能知道他旨在運用 transformer 的架構訓練 bidirectional representation。但實際上他比以往的 word vector 更多,更像是一個 NLP task 的框架。
訓練 BERT 包含兩步驟:pre-training 和 fine-tuning。在做完 embedding pre-training 後,只需要換掉最上面那層 task-specific layer,用跟你想做的 NLP task 有關的 data 繼續訓練(fine-tuning),就能完成一個效果很好的 model。
也就是除了 output layer,你幾乎不需要動到整個架構的一根寒毛!
—— 從 pre-training 到 fine-tuning。
先來看一下 input。BERT 的 input text 可以是一個句子,或一對句子。而輸入 model 之前轉成 embedding 有三個部分:
—— BERT input representation。
三種合起來就是整個 transformer 的 input 了。
圖中還有兩個特殊 token:
[CLS]
:當作整個 input 的 aggregated embedding[SEP]
:當作兩個句子的分隔[CLS]
embedding 訓練完後可以直接拿去做整個 input 的預測任務,例如情緒預測或邏輯判定。而其他訓練完的 token embedding 則是拿去做跟 token 有關的任務,例如 sequence tagging 或問答。
Pre-training 這步主要把一個 transformer 訓練在兩個 task 上,也就是上面看到的 Mask LM (Masked Language Modeling) 和 NSP (Next Sentence Prediction)。這兩個任務有不同的訓練目標:
在 Mask LM 中,輸入是某些字被遮起來的句子,目標是預測被遮起來的字是什麼。例如:
the man went to the [MASK] to buy a [MASK] of milk
[MASK]
代表被遮住的字,正確 label 分別是 store 和 gallon。
這個 task 需要知道兩邊的資訊才能正確推論,也是為什麼可以訓練出有雙向資訊的 contextual embedding。
實作上 [MASK]
是隨機的,paper 中設定為 15% 的機率會把字換掉。不過每次都把字換成 [MASK]
有個問題:model 只有在遇到 [MASK]
時才需要做預測,其他 token 則只被當成 context 在訓練,所以最終我們要的 token embedding 反而效果不是很好。
為了解決這個問題,paper 中設定 15% 中 80% 是 [MASK]
、10% 是隨機的字、剩下 10% 是原本的字。
NSP 是個很簡單的任務:拿兩個句子 A 和 B,預測 B 是不是 A 的下一句。如此一來 model 就能學會理解兩個句子之間的關聯性。[CLS]
這個 token 的 embedding 就是用 NSP 訓練出來的。
我們用兩個 task 訓練出 token embedding 和 aggregated embedding 後,為了讓這些 embedding 更適合你想做的 task,可以把最上面那層做 Mask LM 和 NSP 的換成做自己的 task,再重新 end-to-end train 一下,一個效果很好的 model 就完成了。
BERT 打破了諸多 state-of-the-art results,而且是大幅超過。包括在 GLUE benchmark 語言理解任務提升 7% accuracy、SQuAD 1.1 問答任務提升 1.5 F1 score、以及 SWAG 常識多選任務提升 8.3% accuracy。
BERT 是一個新框架的雛形,而提出以後也有非常多改良的架構來提升效能。
下面簡單幾句話介紹一下:
BERT 整體架構著重在沿用 pre-trained embedding 在任何 NLP task 上,效果驚人也足以證明 transfer learning 的效用。
想要一個 NLP model 嗎?到這裡找 TensorFlow,或這裡找 PyTorch 的 BERT pre-trained model,下載下來再 fine-tune 在自己的 dataset 就行囉!
[CLS]
的 embedding?哪些適合用其他 token 的 embedding?