BERT and It's family

大名鼎鼎的芝麻街

預訓練語言模型的縮寫大可能是芝麻街的人物。這顯然是起名藝術大師們的有意爲之。他們甚至均可以拋棄用首字母縮寫的原則去硬湊出芝麻街人名php

上圖所示的模型(除了Big Bird,由於沒有這個模型)他們之間都有一些共同點,就是能經過一個句子的上下文來給一個詞進行Embedding,而能達到這種目的的網絡架構有不少,例如LSTM,Self-attention layers,Tree-based model(注重文法,通常表現不佳,只有在文法結構很是嚴謹的狀況下表現好)等等html

Smaller Model

預訓練語言模型比來比去,變得愈來愈巨大,愈來愈臃腫,愈來愈玩不起。然而,讓模型變小,就比如咱們去到非洲,可讓人民幣在一線城市的購買力變得更多。這就是窮人用的 BERT。例如Distill BERTTiny BERTMobile BERTQ8BERTALBERTgit

授人以魚不如授人以漁,究竟有哪些方法可使Model變小呢?能夠參考李宏毅老師模型壓縮的視頻講解,以及All The Ways You Can Compress BERT這篇文章。常見的方法有如下幾種github

  • Network Pruning 剪枝
  • Knowledge Distillation 知識蒸餾
  • Parameter Quantization 參數量化
  • Architecture Design 結構設計

Network Architecture Improvements

除了模型壓縮之外,近年來比較火的嘗試還有模型架構的設計。比方說Transfomer-XL經過理解跨片斷的內容,能夠處理很是長的序列;ReformerLongformer可使得自注意力的複雜度變小,從 O ( N 2 ) O(N^2) O ( N l o g N ) O(NlogN) 甚至更低markdown

How to Fine-tune

這一部分李宏毅老師講了很是多,但我我的感受有不少都是比較簡單的內容。比方說輸入一個句子如何進行分類,這個你們其實作的都比較多了,常見的作法就是利用[CLS]的輸出後面跟一個線性分類層,又或者是將全部token的輸出求一個Average,再送入線性分類層。上述兩種方法的目的都是要作分類,可是它們的本質區別在於究竟用什麼東西來表明一個句子的Embedding比較好,關於這個能夠看一下Sentence-BERT的論文,或者是Sentence-BERT詳解這篇文章,裏面有一些實驗證實了用哪些東西表明一個句子的向量比較好網絡

Extraction-based QA

可能你們見的很少的是如何利用預訓練模型作Extraction-based QA (Question Answering)任務架構

比方說如今將一篇文檔和一個問題丟入QA Model,模型會輸出兩個整數 s s e e ,這兩個整數表明這個問題的答案就是文檔中第 s s 個詞到第 e e 個詞,即 { d s , . . . , d e } \{d_s,...,d_e\} app

獲得這兩個整數的方式也頗有意思。首先咱們生成兩個向量(上圖中橙色和藍色),用其中一個(橙色)向量去和document全部位置的輸出作一個dot product,以後再通過一個Softmax獲得一系列機率值,咱們取最大機率值所在的下標(其實就是argmax)就獲得了答案的開始位置 s = 2 s=2 ide

答案的結束位置 e e 獲得的方式也差很少,就是用另外一個(藍色)向量去和document全部位置的輸出作一個dot product,一樣通過Softmax以後獲得機率最大值所在的下標。那麼最終答案就是 [ s , e ] [s,e] 這個區間內的單詞oop

回到主題,預訓練語言模型要如何進行微調呢?一種方法是固定預訓練的模型,讓它做爲一個特徵提取器,訓練的時候,只更新後面接的Task-specific模型的參數;另外一種方法是不固定預訓練語言模型的參數,全部參數在訓練過程當中都進行更新。不過就我本人作過的不少實驗來看,後者效果是比前者好的,可是問題在於,不少預訓練模型特別大,常常11G的顯存都不夠,因此不得不採用前一種方法

Combination of Features

咱們知道BERT有不少Encoder Layer,你們常規的作法都是提取最後一層的輸出來作下游任務,但實際上這是最優解嗎?其實就有人在NER任務上作過一個實驗,將不一樣層的輸出進行各類組合,獲得的效果以下

肖涵在 Github 上建立了一個名爲 bert-as-service 的開源項目,該項目旨在使用 BERT 爲您的文本建立單詞嵌入。他嘗試了各類方法來組合這些嵌入,並在項目的 FAQ 頁面上分享了一些結論和基本原理

肖涵的觀點認爲:

  1. 第一層是嵌入層,因爲它沒有上下文信息,所以同一個詞在不一樣語境下的向量是相同的
  2. 隨着進入網絡的更深層次,單詞嵌入從每一層中得到了愈來愈多的上下文信息
  3. 可是,當您接近最後一層時,詞嵌入將開始獲取 BERT 特定預訓練任務的信息(MLM 和 NSP)
  4. 使用倒數第二層比較合理

Why Pre-train Models?

爲何咱們要使用這些預訓練的模型?一個很明顯的道理是,咱們沒那麼多錢去從頭訓練一個比較大的模型,因此直接拿別人訓練好的來用就好了

固然,EMNLP 2019的一篇文章Visualizing and Understanding the Effectiveness of BERT從學術角度仔細分析了爲何要使用預訓練模型,文章代表,預訓練模型能夠大大加速損失的收斂,而不使用預訓練模型,損失比較難降低。能夠理解爲,預訓練模型提供了一種比隨機初始化更好的初始化

另外一個結論是,預訓練模型能夠大大增長模型的泛化能力。上圖表示給模型不一樣參數時,模型訓練後結束點的損失會抵達一個local minima的位置。這個local minima的位置越陡峭,則泛化能力越差,由於輸入稍微變化,它的損失就會有很大的變更;反之,這個local minima越平緩,則泛化能力越強

ELMo

ELMo是目前來講比較知名的雙向網絡。傳統的LSTM只是從左往右過一遍句子,那預測下一個token所依賴的信息就只能取決於它左邊的內容,爲了能真正利用這個token的上下文,咱們能夠從右到左再過一遍句子,即BiLSTM。但實際上還不夠,由於當模型在encode w 1 , w 2 , w 3 , w 4 w_1,w_2,w_3,w_4 的時候,它沒看到句子後面的部分;而在encode w 5 , w 6 , w 7 w_5,w_6,w_7 的時候,也沒考慮到句子前面的部分,因此ELMo在底層進行編碼的時候並非真正的雙向。而在上層,因爲兩邊的embedding進行了concat,此時它才同時看到了雙向的信息

BERT

對於Transformer類模型(典型表明就是BERT),自注意力機制使得它可以同時看到上下文,每個token兩兩之間都能交互,惟一要作的只是隨機地把某個token用[MASK]遮住就能夠了

若是你回溯歷史,回到Word2vec剛剛掀起NLP革命的時候,你會發現CBOW的訓練方式和BERT幾乎同樣,它們的主要區別在於,BERT能關注的範圍長度是可變的,而CBOW的範圍是固定的

Whole Word Masking (WWM)

隨機地mask掉某個token效果是否真的好呢?對於中文來講,詞是由多個字組成的,一個字就是一個token。若是咱們隨機mask掉某個token,模型可能不須要學到不少語義依賴,就能夠很容易地經過前面的字或後面的字來預測這個token。爲此咱們須要把難度提高一點,蓋住的不是某個token,而是某個詞(span),模型須要學到更多語義去把遮住的span預測出來,這即是BERT-wwm。同理,咱們能夠把詞的span再延長一些,拓展成短語級別、實體級別(ERNIE)

SpanBERT

還有一種BERT的改進叫SpanBERT。它每次會蓋住 n n 個token,其中 n n 是根據上圖所示的機率獲得的。實驗結果發現,這種基於機率選擇蓋住多少個token的方式在某些任務上要更好一些

SpanBERT還提出了一種名爲Span Boundary Objective (SBO)的訓練方法。通常咱們訓練只是把masked的tokens給訓練出來。而SBO但願經過被蓋住範圍的左右兩邊的輸出,去預測被蓋住的範圍內有什麼樣的東西。如上圖所示,將 w 3 w_3 w 8 w_8 的輸出以及一個索引送入後續的網絡中,其中這個索引表示咱們但願預測的是span中哪一個位置的詞

XLNet

關於XLNet更詳細的講解能夠看這篇博客。簡單來講,XLNet認爲BERT類模型訓練和測試階段不統一(訓練階段有[MASK]token,測試階段沒有),所以可能會存在某些問題。若是從Autoregressive的角度去看XLNet,其實就是將輸入打亂順序做爲輸入,而後從左往右預測下一個token。若是以AutoEncoder (BERT)的角度去看XLNet,咱們但願根據[MASK]左邊或者右邊的信息去預測[MASK]位置的詞。與BERT不一樣的地方在於,XLNet的輸入沒有[MASK]的存在

MASS / BART

BERT類模型缺少生成句子的能力,因此它不太適合作Seq2Seq的任務,而MASS和BART這兩個模型就解決了BERT不擅長生成的問題。咱們首先把一個句子輸入到Encoder,咱們但願Decoder的output就是Encoder的input,但有一點要注意的是,咱們必須將Encoder的input作必定程度的破壞,由於若是沒有任何破壞,Decoder直接將Encoder的輸入copy過來就好了,它可能學不到什麼有用的東西

MASS的作法是,把輸入的一些部分隨機用[MASK]token遮住。輸出不必定要還原完整的句子序列,只要能把[MASK]的部分預測正確就能夠了

在BART的論文中,它又提出了各式各樣的方法,除了給輸入序列隨機mask之外,還能夠直接刪除某個token,或者隨機排列組合等。關於BART更詳細的講解能夠看這篇文章

UniLM

還有一個模型叫UniLM,它既能夠是編碼器,也能夠是解碼器,還能夠是Seq2Seq。UniLM由不少Transformer堆疊,它同時進行三種訓練,包括BERT那樣做爲編碼器的方式、GPT那樣做爲解碼器的方式、MASS/BART那樣做爲Seq2Seq的方式。它做爲Seq2Seq使用時,輸入被分爲兩個片斷,輸入第一個片斷的時候,該片斷上的token之間能夠互相注意,但第二個片斷,都只能看左邊token

ELECTRA

預測一個東西須要的訓練強度是很大的,ELECTRA想要簡化這件事情,轉爲二分類問題,判斷輸入的某個詞是否被隨機替換了

但問題來了,怎樣把一些詞進行替換,同時保證文法沒錯,語義也不是那麼奇怪的句子呢?由於若是token被替換成了一些奇怪的東西,模型很容易就能發現,ELECTRA就學不到什麼厲害的東西了。論文用了另外一個比較小的BERT去輸出被mask的單詞,這裏不須要用很好的BERT,由於若是BERT效果太好,直接就輸出了和原來一摸同樣的單詞,這也不是咱們指望的。這個架構看上去有點像GAN,但實際上它並非GAN,由於GAN的Generator在訓練的時候,要騙過Discriminator。而這裏的small BERT是本身訓練本身的,只要把被mask的位置預測出來就行了,至於後面的模型預測的對不對和它沒有關係

ELECTRA訓練效果很驚人,在相同的預訓練量下,GLUE上的分數比BERT要好不少,並且它只須要1/4的運算量就能夠達到XLNet的效果

T5

預訓練語言模型須要的資源太多,不是普通人隨便就能夠作的。谷歌有篇論文叫T5,它展示了谷歌龐大的財力和運算資源,這篇文論把各式各樣的預訓練方法都嘗試了一次,而後獲得了一些結論,讓別人沒有研究可作

Reference

相關文章
相關標籤/搜索