本文另兩篇系列
3. 梯子的一級半
除了在word級別的embedding方法上有大量模型和算法的涌現(xiàn),同樣地,在char級別、句子級別和段落級別同樣有大量模型提出。
word2vec開源隨后的第一年,也就是在2014年,還是Mikolov,在他和另一位作者合作的一篇論文《Distributed Representations of Sentences and Documents》中,提出了可以借鑒word2vec思想的兩種結(jié)構(gòu):PV-DM和PV-DBOW,分別對應(yīng)word2vec中的CBOW和Skip-gram.
3.1 PV-DM和PV-DBOW
PV-DM的全稱是Distributed Memory Model of Paragraph Vectors,和CBOW類似,也是通過上下文預(yù)測下一個詞,不過在輸入層的時候,同時也維護(hù)了一個文檔ID映射到一個向量的look-up table,模型的目的便是將當(dāng)前文檔的向量以及上下文向量聯(lián)合輸入模型,并讓模型預(yù)測下一個詞,訓(xùn)練結(jié)束后,對于現(xiàn)有的文檔,便可以直接通過查表的方式快速得到該文檔的向量,而對于新的一篇文檔,那么則需要將已有的look-up table添加相應(yīng)的列,然后重新走一遍訓(xùn)練流程,只不過此時固定好其他的參數(shù),只調(diào)整look-up table,收斂后便可以得到新文檔對應(yīng)的向量了。PV-DBOW的全稱則是Distributed Bag of Words version of Paragraph Vector,和Skip-gram類似,通過文檔來預(yù)測文檔內(nèi)的詞,訓(xùn)練的時候,隨機(jī)采樣一些文本片段,然后再從這個片段中采樣一個詞,讓PV-DBOW模型來預(yù)測這個詞,以此分類任務(wù)作為訓(xùn)練方法,說白了,本質(zhì)上和Skip-gram是一樣的。這個方法有個致命的弱點(diǎn),就是為了獲取新文檔的向量,還得繼續(xù)走一遍訓(xùn)練流程,并且由于模型主要是針對文檔向量預(yù)測詞向量的過程進(jìn)行建模,其實很難去表征詞語之間的更豐富的語義結(jié)構(gòu),所以這兩種獲取文檔向量的方法都未能大規(guī)模應(yīng)用開來。

2015年,多倫多大學(xué)的Kiros等人提出了一個很有意思的方法叫Skip-thoughts,同樣也是借鑒了Skip-gram的思想,但是和PV-DBOW中利用文檔來預(yù)測詞的做法不一樣的是,Skip-thoughts直接在句子間進(jìn)行預(yù)測,也就是將Skip-gram中以詞為基本單位,替換成了以句子為基本單位,具體做法就是選定一個窗口,遍歷其中的句子,然后分別利用當(dāng)前句子去預(yù)測和輸出它的上一句和下一句。對于句子的建模利用的RNN的sequence結(jié)構(gòu),預(yù)測上一個和下一個句子時候,也是利用的一個sequence的RNN來生成句子中的每一個詞,所以這個結(jié)構(gòu)本質(zhì)上就是一個Encoder-Decoder框架,只不過和普通框架不一樣的是,Skip-thoughts有兩個Decoder。在今天看來,這個框架還有很多不完善或者可以改進(jìn)的地方(作者也在論文中分別提到了這些future works),比如輸入的Encoder可以引入attention機(jī)制,從而讓Decoder的輸入不再只是依賴Encoder最后一個時刻的輸出;Encoder和Decoder可以利用更深層的結(jié)構(gòu);Decoder也可以繼續(xù)擴(kuò)大,可以預(yù)測上下文中更多的句子;RNN也不是唯一的選擇,諸如CNN以及2017年谷歌提出的Transformer的結(jié)構(gòu)也可以利用進(jìn)來,后來果不其然谷歌的BERT便借鑒了這一思路,當(dāng)然這是后話了,留下暫且不表。
3.2 Skip-thoughts

2018年的時候,在Skip-thoughts的基礎(chǔ)上,Google Brain的Logeswaran等人將這一思想做了進(jìn)一步改進(jìn),他們認(rèn)為Skip-thoughts的Decoder效率太低,且無法在大規(guī)模語料上很好的訓(xùn)練(這是RNN結(jié)構(gòu)的通病)。所以他們把Skip-thoughts的生成任務(wù)改進(jìn)成為了一個分類任務(wù),具體說來就是把同一個上下文窗口中的句子對標(biāo)記為正例,把不是出現(xiàn)在同一個上下文窗口中的句子對標(biāo)記為負(fù)例,并將這些句子對輸入模型,讓模型判斷這些句子對是否是同一個上下文窗口中,很明顯,這是一個分類任務(wù)。可以說,僅僅幾個月之后的BERT正是利用的這種思路。而這些方法都和Skip-thoughts一脈相承。
3.3 Quick-thoughts
除了Skip-thoughts和Quick-thoughts這兩種不需要人工標(biāo)記數(shù)據(jù)的模型之外,還有一些從監(jiān)督數(shù)據(jù)中學(xué)習(xí)句子表示的方法,比如2017年Facebook的研究人員Conneau等人提出的InferSent框架,它的思想特別簡單,先設(shè)計一個模型在斯坦福的SNLI(Stanford Natural Language Inference)數(shù)據(jù)集上訓(xùn)練,爾后將訓(xùn)練好的模型當(dāng)做特征提取器,以此來獲得一個句子的向量表示,再將這個句子的表示應(yīng)用在新的分類任務(wù)上,來評估句子向量的優(yōu)劣??蚣芙Y(jié)構(gòu)如下圖所示
3.4 InferSent
這個框架最底層是一個Encoder,也就是最終要獲取的句子向量提取器,然后將得到的句子向量通過一些向量操作后得到句子對的混合語義特征,最后接上全連接層并做SNLI上的三分類任務(wù),做過句子匹配任務(wù)的一定知道,這個框架是一個最基本(甚至也是最簡陋)的句子匹配框架。對于底層的Encoder來說,論文作者分別嘗試了7種模型,然后分別以這些模型作為底層的Encoder結(jié)構(gòu),然后在SNLI上進(jìn)行監(jiān)督訓(xùn)練。訓(xùn)練完成后,在新的分類任務(wù)上進(jìn)行評估,最后發(fā)現(xiàn)當(dāng)Encoder使用BiLSTM with max pooling結(jié)構(gòu)時,對于句子的表征性能最好,對于具體細(xì)節(jié)感興趣的可以參考他們的論文《Supervised Learning of Universal Sentence Representations from Natural Language Inference Data》。
3.5 General Purpose Sentence Representation
此外,除了InferSent這種單個任務(wù)的監(jiān)督學(xué)習(xí)外,最新的工作逐漸將多任務(wù)的聯(lián)合學(xué)習(xí)應(yīng)用到獲取句子的表征中,例如Subramanian等人發(fā)表在2018年ICLR上的一篇文章《Learning General Purpose Distributed Sentence Representations via Large Scale Multi-task Learning》中就提出了利用四種不同的監(jiān)督任務(wù)來聯(lián)合學(xué)習(xí)句子的表征,這四種任務(wù)分別是:Natural Language Inference, Skip-thougts, Neural Machine Translation以及Constituency Parsing等,作者的出發(fā)點(diǎn)也特別簡單,通用的句子表征應(yīng)該通過側(cè)重點(diǎn)不同的任務(wù)來聯(lián)合學(xué)習(xí)到,而不是只有一個特定任務(wù)來學(xué)習(xí)句子表征,后來作者在論文中的實驗也確實證明了這點(diǎn)。實驗的具體做法是,先用聯(lián)合學(xué)習(xí)的方法在上述四個任務(wù)上進(jìn)行訓(xùn)練,訓(xùn)練結(jié)束后,將模型的輸出作為句子的表征(或者把這個聯(lián)合學(xué)習(xí)的模型作為特征提取器),然后直接在這個表征上接上非常簡單的全連接層做分類器,并且同時保證最底層的特征提取器中參數(shù)不動(也就是只把它當(dāng)做特征提取器),然后在新的分類任務(wù)上做訓(xùn)練(只訓(xùn)練最后接上的全連接層分類器),最后根據(jù)訓(xùn)練出來的簡單分類器在各自分類任務(wù)的測試集上做評估。最后作者驚喜的發(fā)現(xiàn)很多任務(wù)上他們的簡單分類器都要超過當(dāng)時的最好結(jié)果,并且他們還發(fā)現(xiàn)聯(lián)合訓(xùn)練中不同的任務(wù)對于句子表征中的不同方面有不同的貢獻(xiàn)。
3.6 Universal Sentence Encoder
同樣在2018年,谷歌的Daniel Cer等人在論文《Universal Sentence Encoder》中提出的思路基本和General Purpose Sentence Representation的工作一樣,只不過作者提出了利用Transformer和DAN(上文提到過的和CBOW與fastText都神似的《Deep Unordered Composition Rivals Syntactic Methods for Text Classification》)兩種框架作為句子的Encoder,Transformer結(jié)構(gòu)更為復(fù)雜,參數(shù)更多,訓(xùn)練也相對比較耗時,但是一般來說效果會更好一些;對應(yīng)的,DAN結(jié)構(gòu)簡單,只有兩個隱藏層(甚至可以減小為只需要一個隱藏層),參數(shù)比較少,訓(xùn)練相對比較省時省資源,但是一般來說效果會差一些(并不是絕對,論文中也發(fā)現(xiàn)某些場景下DAN的效果甚至更好)。然后作者既在無標(biāo)記數(shù)據(jù)上訓(xùn)練,也在監(jiān)督數(shù)據(jù)上訓(xùn)練,最后在十個分類任務(wù)上進(jìn)行遷移學(xué)習(xí)的評估。最后作者還放出了他們預(yù)訓(xùn)練好的Encoder,可以供遷移學(xué)習(xí)的句子特征提取器使用(見引用16)。


4. 撥開迷霧——第二級梯子若隱若現(xiàn)
4.1 戈多會來嗎?
上面我們介紹了好幾種獲取句子表征的方法,然而值得注意的是,我們并不是只對如何獲取更好的句子表征感興趣,其實更有趣的是,這些方法在評估他們各自模型性能的時候所采取的方法,回過頭去進(jìn)行梳理,我們發(fā)現(xiàn),無論是稍早些的InferSent,還是2018年提出的Quick-thoughts和Multi-task Learning獲取通用句子表征的方法,他們無一例外的都使用了同一種思路:將得到的句子表征,在新的分類任務(wù)上進(jìn)行訓(xùn)練,而此時的模型一般都只用一個全連接層,然后接上softmax進(jìn)行分類,分類器足夠簡單,足夠淺層,相比那些在這些分類任務(wù)上設(shè)計的足夠復(fù)雜的模型來說簡直不值一提,然而令人大跌眼鏡的是,結(jié)果無一例外的這些簡單的分類器都能夠比肩甚至超越他們各自時代的最好結(jié)果,這不能不說是個驚喜。而創(chuàng)造這些驚喜的背后功臣,就是遷移學(xué)習(xí)。更進(jìn)一步地,遷移學(xué)習(xí)的本質(zhì),就是給爬上“巨人的肩膀”提供了一架結(jié)實的梯子。
具體的,在這些句子級別的任務(wù)中,屬于InferSent和Quick-thoughts這些模型的“巨人肩膀”便是他們各自使用的訓(xùn)練數(shù)據(jù),遷移學(xué)習(xí)最后給他們搭了一個梯子,然而這個梯子并沒有很好上,磕磕絆絆,人類AI算是站在第一級梯子上,試探性的伸出了一只腿,另一只腿即將跨出,只可惜并不知道是否有他們苦苦等待了五年之久的戈多?
4.2 一絲曙光
2017年,Salesforce的Bryan McCann和其他一些人,發(fā)表了一篇文章《Learned in Translation: Contextualized Word Vectors》,在這篇文章中,他們首先用一個Encoder-Decoder框架在機(jī)器翻譯的訓(xùn)練語料上進(jìn)行預(yù)訓(xùn)練,爾后用訓(xùn)練好的模型,只取其中的Embedding層和Encoder層,同時在一個新的任務(wù)上設(shè)計一個task-specific模型,然后將原先預(yù)訓(xùn)練好的Embedding層和Encoder層的輸出作為這個task-specific模型的輸入,最終在新的任務(wù)場景下進(jìn)行訓(xùn)練。他們嘗試了很多不同的任務(wù),包括文本分類,Question Answering,Natural Language Inference和SQuAD等等,并在這些任務(wù)中,與GloVe作為模型的輸入時候的效果進(jìn)行比較,實驗結(jié)果表明他們提出的Context Vectors在不同任務(wù)中不同程度的都帶來了效果的提升。

和上文中提到的諸如Skip-thoughts方法有所不同的是,CoVe更側(cè)重于如何將現(xiàn)有數(shù)據(jù)上預(yù)訓(xùn)練得到的表征遷移到新任務(wù)場景中,而之前的句子級任務(wù)中大多數(shù)都只把遷移過程當(dāng)做一個評估他們表征效果的手段,因此觀念上有所不同。
那么,CoVe似乎通過監(jiān)督數(shù)據(jù)上的預(yù)訓(xùn)練,取得了讓人眼前一亮的結(jié)果,是否可以進(jìn)一步地,撇去監(jiān)督數(shù)據(jù)的依賴,直接在無標(biāo)記數(shù)據(jù)上預(yù)訓(xùn)練呢?
4.3 ELMo
2018年的早些時候,AllenNLP的Matthew E. Peters等人在論文《Deep contextualized word representations》(該論文同時被ICLR和NAACL接受,并且還獲得了NAACL最佳論文獎,可見這篇論文的含金量)中首次提出了ELMo,它的全稱是Embeddings from Language Models,從名稱上可以看出,ELMo為了利用無標(biāo)記數(shù)據(jù),使用了語言模型,我們先來看看它是如何利用語言模型的。

基本框架是一個雙層的Bi-LSTM,不過在第一層和第二層之間加入了一個殘差結(jié)構(gòu)(一般來說,殘差結(jié)構(gòu)能讓訓(xùn)練過程更穩(wěn)定)。做預(yù)訓(xùn)練的時候,ELMo的訓(xùn)練目標(biāo)函數(shù)為
這個式子很清晰,前后有兩個概率,第一個概率是來自于正向的由左到右的RNN結(jié)構(gòu),在每一個時刻上的RNN輸出(也就是這里的第二層LSTM輸出),然后再接一個Softmax層將其變?yōu)楦怕屎x,就自然得到了;與此類似,第二個概率來自反向的由右到左的RNN結(jié)構(gòu),每一個時刻RNN的輸出經(jīng)過Softmax層后也能得到一個概率大小,表示從某個詞的下文推斷該詞的概率大小。
ELMo的基本框架便是2-stacked biLSTM + Residual的結(jié)構(gòu),不過和普通RNN結(jié)構(gòu)的不同之處在于,ELMo借鑒了2016年Google Brain的Rafal Jozefowicz等人發(fā)表的一篇論文《Exploring the Limits of Language Modeling》,其主要改進(jìn)在于輸入層和輸出層不再是word,而是變?yōu)榱艘粋€char-based CNN結(jié)構(gòu),ELMo在輸入層和輸出層考慮了使用同樣的這種結(jié)構(gòu),該結(jié)構(gòu)如下圖示

這樣做有什么好處呢?因為輸入層和輸出層都使用了這種CNN結(jié)構(gòu),我們先來看看輸出層使用這種結(jié)構(gòu)怎么用,以及有什么優(yōu)勢。我們都知道,在CBOW中的普通Softmax方法中,為了計算每個詞的概率大小,使用的如下公式的計算方法
說白了,也就是先通過向量點(diǎn)乘的形式計算得到logits,然后再通過softmax變成概率意義,這本質(zhì)上和普通的分類沒有什么區(qū)別,只不過是一個較大的|V|分類問題?,F(xiàn)在我們假定char-based CNN模型是現(xiàn)成已有的,對于任意一個目標(biāo)詞都可以得到一個向量表示,相應(yīng)的當(dāng)前時刻的LSTM的輸出向量為
,那么便可以通過同樣的方法得到目標(biāo)詞的概率大小
在原論文中,把這種先經(jīng)過CNN得到詞向量,然后再計算Softmax的方法叫做CNN Softmax,而利用CNN解決有三點(diǎn)優(yōu)勢值得注意,第一是,CNN能夠減少普通做Softmax時全連接層中的必須要有的|V|h的參數(shù)規(guī)模,只需要保持CNN內(nèi)部的參數(shù)大小即可,而一般來說,CNN中的參數(shù)規(guī)模都要比|V|h的參數(shù)規(guī)模小得多;另一方面,CNN可以解決OOV(Out-of-Vocabulary)問題,這個在翻譯問題中尤其頭疼;最后一方面,在預(yù)測階段,CNN對于每一個詞向量的計算可以預(yù)先做好,更能夠減輕inference階段的計算壓力。補(bǔ)充一句:普通Softmax在大詞典上的計算壓力,都是因為來自于這種方法需要把一個神經(jīng)網(wǎng)絡(luò)的輸出通過全連接層映射為單個值(而每個類別需要一個映射一次,就是一次h大小的計算規(guī)模,|V|次映射便需要總共|V|*h這么多次的映射規(guī)模),對于每個類別的映射參數(shù)都不同,而CNN Softmax的好處就在于能夠做到對于不同的詞,映射參數(shù)都是共享的,這個共享便體現(xiàn)在使用的CNN中的參數(shù)都是同一套,從而大大減少參數(shù)的規(guī)模。
同樣的,對于輸入層,ELMo也是用了一樣的CNN結(jié)構(gòu),只不過參數(shù)不一樣而已,和輸出層中的分析類似,輸入層中CNN的引入同樣可以減少參數(shù)規(guī)模(不過《Exploring the Limits of Language Modeling》文中也指出了訓(xùn)練時間會略微增加,因為原來的look-up操作可以做到更快一些),對OOV問題也能夠比較好的應(yīng)對,從而把詞典大小不再限定在一個固定的詞典大小上。最終ELMo的主要結(jié)構(gòu)便如下圖(b)所示,可見輸入層和輸出層都是一個CNN,中間使用Bi-LSTM框架,至于具體細(xì)節(jié)便如上兩張圖中所示。
最后,在大規(guī)模語料上訓(xùn)練完成的這種CNN-BIG-LSTM模型(原文如此叫法),怎么用呢?其實,如果把每一層的輸出結(jié)果拿出來,這里大概有三層的詞向量可以利用:輸入層CNN的輸出,即是LSTM的輸入向量,第一層LSTM的輸出和第二層的輸出向量。又因為LSTM是雙向的,因此對于任意一個詞,如果LSTM的層數(shù)為L的話,總共可獲得的向量個數(shù)為,表示如下
到這里還只是把ELMo的向量給抽取出來了,具體用的話,對于每一個詞,可以根據(jù)下面的式子得到它的向量,其中是一個scale因子,加入這個因子主要是想要將ELMo的向量于具體任務(wù)的向量分布拉平到同一個分布水平,這個時候便需要這么一個縮放因子了。另外,
便是針對每一層的輸出向量,利用一個softmax的參數(shù)來學(xué)習(xí)不同層的權(quán)值參數(shù),因為不同的任務(wù)需要的詞語意義的粒度也不一致,一般認(rèn)為淺層的表征比較傾向于句法,而高層輸出的向量比較傾向于語義信息,因此通過一個softmax的結(jié)構(gòu)讓任務(wù)自動去學(xué)習(xí)各層之間的權(quán)重,自然也是比較合理的做法。

前面我們說過,無論是基于傳統(tǒng)統(tǒng)計的N-gram還是普通神經(jīng)網(wǎng)絡(luò)的NNLM結(jié)構(gòu),都會有一個很嚴(yán)重的問題,那就是計算復(fù)雜度隨著上下文窗口N大小的增大急劇上升(其中N-gram是指數(shù)上升,NNLM是以的形式增加,
是詞向量的維度,雖然NNLM已經(jīng)改觀了很多,但依然是一個斜率很大的線性增加關(guān)系),后來CBOW和Skip-gram以及再后來的GloVe等等終于做到了計算復(fù)雜度與所選窗口大小無關(guān),只與詞典大小和詞向量維度相關(guān)(不過需要指出的是,這里討論的計算復(fù)雜度只是預(yù)測單個詞的計算時間復(fù)雜度,如果是求整個輸入序列的話,還是避免不了要與序列長度相關(guān),在這一點(diǎn)上和下面要分析的RNN在橫向的時間序列上有一個時間復(fù)雜度,其原因是一致的),并且近些年得益于硬件持續(xù)的摩爾定律發(fā)揮威力,機(jī)器的計算能力也有長足的進(jìn)步,因此在這兩方面因素的作用下,以word2vec為代表的方法大放光彩,引領(lǐng)了一波NLP的發(fā)展浪潮。
然而,在今天看來,無論word2vec中的模型,還是GloVe的模型,模型都過于簡單,它們都受限于所使用的模型表征能力,某種意義上都只能得到比較偏上下文共現(xiàn)意義上的詞向量,并且也很少考慮過詞序?qū)τ谠~的意義的影響(比如CBOW從其名稱來看就是一個bag-of-words,在模型的輸入中沒有詞序的概念)。理論上,RNN結(jié)構(gòu)的計算復(fù)雜度,跟兩個方向上都有關(guān)系,一方面是縱向上,另一方面是橫向上,縱向上主要是RNN結(jié)構(gòu)本身的時間復(fù)雜度,這個復(fù)雜度只與RNN結(jié)構(gòu)內(nèi)部的hidden state維度以及模型結(jié)構(gòu)的復(fù)雜度,在ELMo中的話還跟詞典大小相關(guān)(因為最后一層還是一個詞典大小上的分類問題,以及輸入也需要維護(hù)一個詞典大小的loop up操作);在橫向上的計算復(fù)雜度,就主要是受制于輸入序列的長度,而RNN結(jié)構(gòu)本身因為在時間序列上共享參數(shù),RNN本身的計算復(fù)雜度這一部分不變,因而總的ELMo結(jié)構(gòu)計算復(fù)雜度主要有詞典大小、隱藏層輸出維度大小、模型的結(jié)構(gòu)復(fù)雜度以及最后的輸入序列長度,前三者可以認(rèn)為和之前的模型保持一致,最后的輸入序列長度,也只是與其保持線性關(guān)系,雖然系數(shù)是單個RNN單元的計算復(fù)雜度,斜率依然很大(通常RNN結(jié)構(gòu)的訓(xùn)練都比較費(fèi)時),但是在機(jī)器性能提升的情況下,這一部分至少不是阻礙詞向量技術(shù)發(fā)展的最關(guān)鍵的因素了。
因此,在新的時代下,機(jī)器性能得到更進(jìn)一步提升的背景下,算法人員都急需一種能夠揭示無論詞還是句子更深層語義的方法出現(xiàn),我想ELMo正是順應(yīng)了這種時代的需要而華麗誕生。
ELMo的思想足夠簡單,相比它的前輩們,可以說ELMo并沒有本質(zhì)上的創(chuàng)新,連模型也基本是引用和拼接別人的工作(這似乎從反面證明了真正漂亮的工作從來不是突出各自的模型有多么絢麗,只有無其他亮點(diǎn)的論文,才需要依靠描摹了高清足夠喜人眼球的圖片去吸引評審人的注意力,因此從這個角度去看,似乎可以得出一個啼笑皆非的結(jié)論:論文的漂亮程度與論文圖的漂亮程度呈反比),它的思想在很多年前就已經(jīng)有人在用,并沒有特別新奇的地方。
但同時它的效果又足夠驚艷,它的出現(xiàn),在2018年年初,這個也許在NLP歷史上并沒有多么顯眼的年頭,掀起了一陣不小的波瀾,至少在6項NLP任務(wù)上橫掃當(dāng)時的最好結(jié)果,包括question answering(SQuAD), textual entailment(SNLI), semantic role labelling(SRL), named entity extraction(NER), coreference resolution(Coref), and sentiment analysis(SST-5)。
而后來的故事以及可預(yù)見的將來里,這或許僅僅只是一個開始,就如山洪海嘯前的一朵清秀的漣漪。
4.4 ULMFit
差不多和ELMo同期,另一個同樣非常驚艷的工作也被提出來,這個團(tuán)隊是致力于將深度學(xué)習(xí)普及和易用的Fast AI,而論文的兩位共同作者之一的Jeremy Howard,其實就是Fast AI的創(chuàng)始人,是Kaggle之前的president和首席科學(xué)家,并且親自參與過Kaggle上的很多比賽,長期排在排行榜的第一。在他們的論文《Universal Language Model Fine-tuning for Text Classification》中,他們提出了ULMFit結(jié)構(gòu),其實這本質(zhì)上他們提出的是一個方法,而不是具體的某種結(jié)構(gòu)或模型,只不過正如論文標(biāo)題所言,他們主要把它應(yīng)用在了文本分類的問題中。和ELMo相同的地方在于,ULMFit同樣使用了語言模型,并且預(yù)訓(xùn)練的模型主要也是LSTM,基本的思路也是預(yù)訓(xùn)練完成后去具體任務(wù)上進(jìn)行finetune,但是不同的地方也有很多,分別來講講。
首先,ULMFit的預(yù)訓(xùn)練和finetune過程主要可以分為三個階段,分別是在大規(guī)模語料集上(比如Wikitext 103,有103million個詞)先預(yù)訓(xùn)練,然后再將預(yù)訓(xùn)練好的模型在具體任務(wù)的數(shù)據(jù)上重新利用語言模型來finetune一下(這是第一次finetune,叫做LM finetune),爾后再根據(jù)具體任務(wù)設(shè)計的一個模型上,將預(yù)訓(xùn)練好的模型當(dāng)做這個任務(wù)模型的多層,再一次finetune(這是第二次finetune,如果是分類問題的話可以叫做Classifier finetune),整個過程如下所示:

其次,所使用的模型來自于2017年salesforce發(fā)表的一篇論文《Regularizing and Optimizing LSTM Language Models》(這是一篇很好的文章),在這篇文章中,他們提出了AWD-LSTM(Averaged SGD and Weight-Dropped LSTM),正如名字中所揭示的,這個框架更多的是一種訓(xùn)練方法,主要思想分為兩大塊,其中Averaged SGD是指先將模型訓(xùn)練到一定epoch,然后再將其后的每一輪權(quán)值進(jìn)行平均后,得到最終的權(quán)值,用公式表示就是,普通的SGD方法權(quán)值更新過程為
其中k代表迭代次數(shù),而f則是loss function,這就是普通的一個SGD權(quán)值更新迭代式子,那么ASGD則把它變成了
其中T是一個閾值,而K則是總共的迭代次數(shù),這個式子的意思就是把迭代到第T次之后,對該參數(shù)在其后的第T輪到最后一輪之間的所有值求平均,從而得到最后模型的該參數(shù)值,而相應(yīng)的,普通的SGD則是直接取作為最后模型的參數(shù)值。
除了使用ASGD的方法訓(xùn)練模型之外,在普通的LSTM上一個時刻和下一個時刻之間的隱藏層之間是有連接的,并且這個連接通過一個全連接的矩陣相連,而這個模型則用了DropConnect的方法隨機(jī)drop掉一些連接,從而減少了一些過擬合的風(fēng)險,當(dāng)然在其他的諸如輸入層到隱藏層之間也有正常的dropout操作。
第三,微調(diào)的方法設(shè)計的非常精妙。作者提出了幾種微調(diào)的技巧,它們是:discriminative fine-tuning, slanted triangular learning rates, 以及gradual unfreezing,分別來看一下。
discriminative fine-tune的基本思想是針對不同的層在訓(xùn)練更新參數(shù)的時候,賦予不同的學(xué)習(xí)率。這里的出發(fā)點(diǎn)是,一般來說,對于NLP的深度學(xué)習(xí)模型來說,不同層的表征有不同的物理含義,比如淺層偏句法信息,高層偏語義信息,因此對于不同層的學(xué)習(xí)率不同,自然就是比較合理的了。具體來說,公式是這樣的
這里的便是不同的層
有不同的學(xué)習(xí)率,原文也給出了具體的選擇:先指定最后一層的學(xué)習(xí)率,然后根據(jù)下式得到前面層的學(xué)習(xí)率,基本思想是讓淺層的學(xué)習(xí)率要更小一些。
而對于slanted triangular learning rates來說,主要思想便是在finetune的第一階段,希望能夠先穩(wěn)定住原來已經(jīng)在大規(guī)模語料集上已經(jīng)預(yù)訓(xùn)練好的參數(shù),所以選擇一個比較小的finetune學(xué)習(xí)率;爾后希望能夠逐步加大學(xué)習(xí)率,使得學(xué)習(xí)過程能夠盡量快速;最后,當(dāng)訓(xùn)練接近尾聲時,逐步減小學(xué)習(xí)率,這樣讓模型逐漸平穩(wěn)收斂(這個思想,個人覺得大概借鑒了2017年谷歌提出Transformer時用到的warm up的學(xué)習(xí)率調(diào)節(jié)方法,這個方法也是在訓(xùn)練的時候先將學(xué)習(xí)率逐步增大,爾后再逐步減?。?。因此,這樣一個三段論式的學(xué)習(xí)過程,用圖表示如下
另外一個finetune的技巧是gradual unfreezing,主要思想是把預(yù)訓(xùn)練的模型在新任務(wù)上finetune時,逐層解凍模型,也就是先finetune最后一層,然后再解凍倒數(shù)第二層,把倒數(shù)第二層和最后一層一起finetune,然后再解凍第三層,以此類推,逐層往淺層推進(jìn),最終finetune整個模型或者終止到某個中間層。這樣做的目的也是為了finetune的過程能夠更平穩(wěn)。
當(dāng)然,值得提出的是,因為ULMFiT中包含了兩次finetune,即在新任務(wù)上用語言模型finetune和在新任務(wù)上finetune訓(xùn)練一個最終的task-specifi-model(比如分類器),而論文中主要把discriminative fine-tuning, slanted triangular learning rates這兩個技巧用在了語言模型的finetune階段,把最后一個gradual unfreezing的技巧應(yīng)用在最終task-specifi-model的finetune階段。
通過上面的這些方法,ULMFiT最終在分類任務(wù)上表現(xiàn)驚艷,尤其是只需要100個標(biāo)記數(shù)據(jù),就足夠能夠?qū)W習(xí)到一個表現(xiàn)非常comparable的分類器,不得不說,這個過程中預(yù)訓(xùn)練的語言模型,對最終的表現(xiàn)起到了至關(guān)重要的作用。
4.5 GPT
大規(guī)模語料集上的預(yù)訓(xùn)練語言模型這把火被點(diǎn)燃后,整個業(yè)界都在驚呼,原來預(yù)訓(xùn)練的語言模型遠(yuǎn)不止十年前Bengio和五年前Mikolov只為了得到一個詞向量的威力。然而,當(dāng)大家還在驚呼,沒過幾個月,很快在2018年6月的時候,不再屬于“鋼鐵俠”馬斯克的OpenAI,發(fā)了一個大新聞(相關(guān)論文是《Improving Language Understanding by Generative Pre-Training》),往這把火勢正猛的烈焰上加了一劑猛料,從而將這把火推向了一個新的高潮。
OpenAI的猛料配方里,第一劑主料便是谷歌于2017年年中的時候提出的Transformer框架(《Attention Is All You Need》),因此,讓我們先來弄明白Transformer里面都有什么東西。私以為,Transformer里最為核心的機(jī)制是Self-attention,正是因為Self-attention的存在,才使得Transformer在做類似翻譯問題的時候,可以讓其Encoder不用做序列輸入,而是將整個序列一次全輸入,并且超長序列的輸入也變得可能。而具體到Self-attention中,可以用下圖表示

簡單說來,輸入為句子的矩陣,先分別通過三個全連接矩陣將輸入矩陣變化為三個矩陣,分別為Q, K和V,然后通過Q和K的計算得到一些權(quán)值,將這些權(quán)值加權(quán)求和到V矩陣上,便可以得到一個新的矩陣表示。而Self-attention機(jī)制中的多頭機(jī)制便是將這樣的操作分別進(jìn)行多次,這樣能讓句子的表征充分學(xué)習(xí)到不同的側(cè)重點(diǎn),最終將這些多頭學(xué)習(xí)出來的表征concat到一起,然后再同一個全連接網(wǎng)絡(luò),便可以得到這個句子的最終Self-attention下新的表示。將其中的每一個頭的操作過程用公式表示如下,需要注意的是softmax是針對矩陣的row方向上進(jìn)行操作得到的。所以,說白了,這個公式表示的意思就是針對V進(jìn)行加權(quán)求和,加權(quán)的權(quán)值通過Q和K的點(diǎn)乘得到。

不過其實Self-attention和普通的attention機(jī)制在形式上幾乎完全等價。主要區(qū)別在于,對于普通的attention機(jī)制,輸入可能有多個,并且下式在求得中的
實際上是一個全連接網(wǎng)絡(luò)(當(dāng)然這只是其中一種計算方法,也可以用dot attention的方式得到),將式子右邊的部分(也就是attention的輸入)映射為一個值,從而可以根據(jù)這個值計算attention的權(quán)值大小。除此之外,普通的attention和self-attention并沒有本質(zhì)不同,最大的區(qū)別還是在于在自我輸入上計算attention權(quán)值大小。

在Transformer的Encoder中,還有一些其他的設(shè)計,比如加入position embedding(因為Transformer的Encoder中不是時序輸入詞序列,因此position embedding也是主要的位置信息);Residual結(jié)構(gòu),使得模型的訓(xùn)練過程更為平穩(wěn),此外還有normalization層,接著便是feed forward層(本質(zhì)上是一個兩層的全連接網(wǎng)絡(luò),中間加一個ReLu的激活函數(shù))。Decoder的結(jié)構(gòu)與此類似,只不過在進(jìn)行decode的時候,會將Encoder這邊的輸出作為Decoder中Self-attention時候的K和V。

對于decode的過程,具體來看,大致過程如下。

(對具體實現(xiàn)細(xì)節(jié)不關(guān)心的可以略過此段)但是Decoder實際上還有很多細(xì)節(jié),一般來說,訓(xùn)練的時候Decoder中的輸入可以用矩陣的形式一次完成當(dāng)前整個序列的decode過程,因為ground truth已經(jīng)提前知道,只需要做好每個詞的mask就好(為了避免待預(yù)測的詞影響到當(dāng)前的輸入),然而在做inference的時候,Decoder必須按照序列輸入,因為在生成每一個詞的時候,必須先生成它的前一個詞,無法一次將整個序列全部生成(當(dāng)然理論上也可以,但是效果并不好)。在矩陣運(yùn)算過程中,Decoder中有許多的mask操作,參與運(yùn)算的三個矩陣Q,K和V都要做許多的mask操作,主要有兩方面的作用:一方面是消除輸入句子本身長度之外的padding的影響,另一方面是decoder必須要求不能提前看到待生成的詞。除了mask操作,另外,值得注意的是,和Encoder中只有一種類型的Self-attention不同的,Decoder的attention實際上包含兩部分,第一部分是帶有mask的Self-attention,通過mask的作用將decode階段的attention限定只會attention到已經(jīng)生成過的詞上,因此叫做Mask Self-attention;第二部分是普通的Self-attention操作,不過這個時候的K和V矩陣已經(jīng)替換為Encoder的輸出結(jié)果,所以本質(zhì)上并不是一個Self-attention了。
下面的動圖很好的表現(xiàn)了decoding過程,生成每一個詞的時候,既和Encoder的輸出信息有關(guān),也和已經(jīng)生成過的詞相關(guān)。

大體介紹完Transformer后,再來看看GPT中的是怎么用Transformer的。按照論文中的說法,GPT中使用的Transformer是只用了Decoder,因為對于語言模型來講,確實不需要Encoder的存在,而具體模型,他們參考了2018年早些時候谷歌發(fā)表的一篇論文《Generating Wikipedia by Summarizing Long Sequences》(而GPT名稱中的Generative該詞便是來自于這篇文章,因為這二者都有用到生成式的方法來訓(xùn)練模性,也就是生成式的Decoder),關(guān)于這篇論文中提到的T-DMCA(Transformer Decoder with Memory-Compressed Attention),實際上就是一個Decoder,只不過這篇文章中要做超長的序列輸入(可以長達(dá)11000個詞),為了能夠高效節(jié)省時間和內(nèi)存的處理如此長的序列,做了一些Memory-Compressed的工作,主要是兩方面:一方面是把一個batch內(nèi)部的序列按長度進(jìn)行分組,然后分別在每個組內(nèi)部進(jìn)行self-attention操作,這樣可以避免將一些很短的句子也padding到整個語料的最大長度;另一方面,通過CNN的操作,把K和V壓縮到序列長度更小的一個矩陣,同時保持Q不變,這樣也能相當(dāng)程度上減少計算量。
除了這些具體的模型細(xì)節(jié)外,GPT本質(zhì)上就是用了語言模型的目標(biāo)函數(shù)來優(yōu)化和訓(xùn)練Transformer-Decoder,這個和上文提到過的語言模型保持一致。利用語言模型的目標(biāo)函數(shù)預(yù)訓(xùn)練完成后,進(jìn)階這便可以在具體的任務(wù)上進(jìn)行finetune,和ULMFiT中的finetune分為兩個階段的方法不一樣的是,GPT直接把這兩個過程糅合到一個目標(biāo)函數(shù)中,如
其中是task-specific的目標(biāo)函數(shù),
則是語言模型的目標(biāo)函數(shù)。論文中說這種聯(lián)合學(xué)習(xí)的方式能夠讓訓(xùn)練效果更好。而在具體如何做遷移學(xué)習(xí)的方面,GPT大概也同樣借鑒了上面提到的《Generating Wikipedia by Summarizing Long Sequences》論文中的做法,非常巧妙的將整個遷移學(xué)習(xí)的框架做到非常的精簡和通用。分類問題中,直接在原序列的開始和末尾添加表示開始和末尾的符號,在Text Entailment問題中(比如Natural Language Inference),將Premise和Hypothesis通過一個中間分隔符“$”連接起來成為一個序列,爾后同樣在開頭和末尾添加標(biāo)記符號,文本相似問題中,因為序列1和序列2沒有先后關(guān)系,因此將先后關(guān)系相反的兩個序列作為輸入,在Question Aswering中,將query和每一個候選的answer都分別連接成一個序列作為輸入,最后按各自的打分進(jìn)行排序。因此,這套輸入的表示方法,基本可以使用同一個輸入框架來表征許多文本問題(以至于后來的BERT直接借用了這套做法)。除此之外,在輸出層,只需要接入一個很簡單的全連接層或者M(jìn)LP便可以,根本不需要非常復(fù)雜的模型設(shè)計。而整個finetune階段,新加入的參數(shù)極少,只有輸出層以及輸入層中添加的一些特殊標(biāo)記(比如分隔符)。
正是因為有了輸入層和輸出層的這種通用化設(shè)計考慮,一旦中間的Transformer(當(dāng)然,正如前文所說,這里的Transformer在使用語言模型進(jìn)行預(yù)訓(xùn)練的時候只有Decoder部分,然而在將其當(dāng)做文本特征提取器的時候,相應(yīng)的也可以很便利的將其變成Encoder)表征能力足夠強(qiáng)大,遷移學(xué)習(xí)在NLP任務(wù)中的威力也會變得更為強(qiáng)大。
果不其然,GPT在其公布的結(jié)果中,一舉刷新了12項NLP任務(wù)中的9項榜單,效果不可謂不驚艷。然而對于OpenAI來講,GPT底層模型使用的是谷歌提出的Tranformer,正是依靠了Transformer的強(qiáng)大表征能力,使得最終的效果有了一個堅實的基礎(chǔ),然而僅僅過了四個月之后的BERT橫空出世,同樣也是用了Transformer,同樣是谷歌,甚至很多思想也是直接借鑒GPT,GPT作為與BERT氣質(zhì)最為接近的工作,同時也是BERT的前輩,得到的待遇差別如此之大,不知道GPT是否有些可惜和遺憾,相比BERT,GPT并沒有帶來特別巨大的反響,他的驚艷亮相,迅速變?yōu)樗锏囊宦晲烅懀破鹆艘魂嚌i漪后迅速消散,將整個舞臺讓位于正值青春光艷照人的BERT,頗有點(diǎn)“成也蕭何敗也蕭何”的味道。