# 李宏毅_ELMO, BERT, GPT ###### tags: `Hung-yi Lee` `NTU` `ELMO, BERT, GPT` ## ELMO, BERT, GPT [課程連結](https://www.youtube.com/watch?v=UYPa347-DdE) 機器如何看懂人類的文字,課程說明目前比較知名的三種模型。 ### 1-of-N Encoding ![](https://i.imgur.com/p3ltAX1.png) 最早要讓機器懂人類的詞彙,我們的作法是每一個詞彙就是一個符號,每一個符號都有一個獨特的編碼,也就是1-of-N Encoding。 每一個詞彙都用一個向量來表示,如上圖所示,假設世界上只有五個詞彙,那就有五個向量來各別表示它們。這麼做的缺點是,機器無法知道詞彙之間是否存在關聯性,是否都為動物,是否都為水果之類的。 後續發展出Word Class,但這麼做很顯然的太粗糙,即使同為動物,但還是有種族之分。 最後有了Word Embedding,每一個詞彙都以一個向量來表示,每一個維度都是詞彙的某種屬性,而語意相近的詞彙在高維空間中它們會是相近的。 ### Word Embedding ![](https://i.imgur.com/4oJiVb6.png) Word Embedding可以想成是某成抽特徵的方法。 ### A word can have multiple senses. ![](https://i.imgur.com/AU281FJ.png) 上面案例,四個bank是不同的token但是相同的type。 同一個詞彙可能會有不同的意義,過往在實作Word Embedding的時候,每一個type都有一個embedding,因此不同的token有相同的type,那它所對應的就是相同的embedding,也就是說,過去所假設的是,所有不同的token只要擁有相同的type,那它們的語意就是相同的。 但事實並非如此,即使是不同token擁有相同的type,它們還是可能存在不相同的意義。 ### A word can have multiple senses. ![](https://i.imgur.com/zp2ZWbC.png) 上面例子來看,前兩個句子的bank以上下文來看,它們所指的皆為銀行,但後面兩個句子的bank所指的卻是河堤的意思。 過去傳統的embedding來說,每一個type是一個embedding,而這四個bank都會有一模一樣的embedding,因為我們假設這四個bank有相同的語意。但事實並非如此,我們希望機器給不同意思的token,即使擁有相同的type也要給它們不同的embedding。 過往的作法可能就是查查字典,然後知道bank有兩個意思之後就讓它們有兩個embedding,但有些字典會告訴你,bank還有另外的意思,像是blook bank,雖然一樣擁有儲存的概念,但本意上卻不是銀行,但其中存在著微妙的差異。 ### 一樣?不一樣? ![](https://i.imgur.com/4y5FJ6E.png) 一樣是尼祿,都是羅馬帝國第五任皇帝。 一樣都是加賀號護衛艦。 但它們,好像一樣,又好像不一樣。 ### Contextualized Word Embedding ![](https://i.imgur.com/W3hKrY0.png) 因此,我們希望機器可以每一個token都擁有一個embedding。我們希望上下文愈相近的token都擁有相同的embedding,而不是一個type一個embedding。 延續一開始的範例,我們希望三個bank可以各自擁有它們的embedding,即使它們的type是一樣的,而這樣的作法就稱為**Contextualized Word Embedding**。只是語意上,money in the bank與own blook bank的bank是比較相近,因此它們的embedding之間的距離也會比較接近。 ### Embeddings from Language model(ELMO) ![](https://i.imgur.com/H5tUIZY.png) [論文連結_Deep contextualized word representations](https://arxiv.org/abs/1802.05365) ELMO是一個RNN-base的language model。RNN-base的模型所學習到的就是預測下一個token會是什麼,你所需要做的就是給它一堆文本學習。 訓練完之後你就擁有Contextualized Word Embedding,我們可以將RNN的hidden layer視為現在輸入的那個詞彙的Contextualized Word Embedding(例如,輸入退了,經過RNN所得的embedding即為Contextualized Word Embedding)。 一樣是退了,高燒退了與臣退了所得的embedding就會不一樣。因為在輸出退了的embedding的時候RNN會參考句語的上下文。 這就是ELMO的基本概念。 ### Embeddings from Language model(ELMO) ![](https://i.imgur.com/m21Hmv3.png) 如果擔心單向的訓練只會單純的考慮到前文的上下文的話,那就使用雙向的RNN,從句子的後面開始往前,那就可以考慮完整句子的上下文了。 這時候要取得"退了"這個詞彙的Contextualized Word Embedding,只需要將兩端的embedding接起來就可以同時取得前後完整句子的上下文。 ### ELMO ![](https://i.imgur.com/WDMKTxu.png) ELMO也可以很Deep,這時候遇到的問題是,每一層都會有一個embedding,該用那一層?在ELMO的論文中有提到,就是全都用。 ### ELMO ![](https://i.imgur.com/ePN0W8k.png) 每一層都會有一個Contextualized Word Embedding,每一個詞彙都會有多層的Contextualized Word Embedding的值,這時候要將所有的Contextualized Word Embedding加起來,ELMO的作法是將這些Contextualized Word Embedding做加權總和。 假設現在的ELMO有兩層,那作法就是將兩層的output分別乘上$\alpha1, \alpha2$再相加即可。其中$\alpha1, \alpha2$是由模型自己學習出來的。 在還沒有使用ELMO抽出來的embedding之前是不會知道$\alpha1, \alpha2$的值,先設定好要執行的任務,再將參數$\alpha1, \alpha2$與任務一起訓練,然後才得到$\alpha1, \alpha2$,總之就是視為模型的一部份,一起訓練學習而得。 因此不同的任務所用的$\alpha1, \alpha2$就不同,ELMO論文實驗說明(上面簡報右圖),用於接下來的down stream task的三個來源,分別為圖上Token(沒有Contextualized Embedding)、LSTM1(ELMO第一層Embedding)、LSTM2(ELMO第二層Embedding),分別計算上述三個的加權和,會因為不同的任務(SRL, Coref, SNLI, SQuAD, SST-5)而學習到不同的權重(以顏色的深淺~(圖下進度條)~代表需求度)。 我們發現,Coref與SQuAD特別需要LSTM1的Contextualized Word Embedding,其它任務來看對各層的需求是比較平均的,因此不同的任務就需要抽不同的Contextualized Word Embedding來用。 Coref:將代名詞所指射的名詞找出,"他"代表句子中的誰的概念。 SQuAD:QA ### Bidirectional Encoder Representations from Transformers(BERT) ![](https://i.imgur.com/AIN4jYr.png) 在聽BERT之前請記得先看過Transformer: * [影片連結](https://www.youtube.com/watch?v=ugWDIIOHtPA) * [筆記連結](https://hackmd.io/@shaoeChen/rJlRfP7mL) BERT是Transformer的Encoder,訓練BERT只需要一堆的句子,不需要有標記資料就可以train出一個encoder。 大致來說BERT就是給定一個句子,每一個句子都會輸出一個embedding,而它的架構就跟Transformer的encoder是一樣的。 另外,實作上,如果訓練的是中文,那以"字"為單位會比用"詞彙"來的恰當,也就是不以"潮水"為單位,而是"潮"、"水"。想法上,如果以詞做為輸入,那整個one-hot encoder的維度會太大,而且中文的詞量恐怕無法窮舉。但如果以字來表示的話,那字是有限的,而且常用字也不過數千個,即使one-hot encoder也不會造成維度過高的問題。 因此雖然課程上是以詞彙為例,但記得實作上以"字"為單位。 ### Training of BERT ![](https://i.imgur.com/vHHndIP.png) 文獻上有兩種訓練方法,第一種為Masked LM:即,輸入給BERT的詞彙會有15%的詞彙會被置換為一個特殊的token,這個token稱為"MASK"。也就是蓋掉句子裡面15%的資訊。BERT要做的就是猜這些被蓋掉的詞彙是那幾個詞彙。 作法如下說明:假設輸入的第二個詞彙是被蓋掉的,所有的input經過BERT得到一個output-embedding,然後將被蓋掉的那個詞彙丟到Linear Multi-class Classifier裡面,讓這個Classifier猜這個被蓋掉的是那一個詞彙。但是,因為這是一個Linear model,因此它很弱,要它能猜的出來就必需要BERT能夠抽出一個很好的representation,因此BERT所抽出來的embedding會跟上下文間的詞彙的embedding是相近的。 ### Training of BERT ![](https://i.imgur.com/Na0QM9K.png) 第二種方法為Next Sentence Prediction:即,給BERT兩個句子,讓BERT預測這兩個句子是否為接在一起的句子。舉例來說,兩個句子,"醒醒吧"、"你沒有妹妹",要讓BERT判斷這兩個句子是否接在一起。這時候會引入兩個特殊符號: 1. 兩個句子的中間會引入一個特殊符號"SET",這意味著讓BERT知道兩個句子的中間交界 2. 在句子起始處加入一個特殊符號"CLS",這意味著讓BERT知道這邊我們要做分類,這個特殊符號的output就是判斷後面的句子是否應該接在一起,這個classifier是跟整個架構一起訓練的 可以發現,"CLS"放在起始而不是結尾,這是因為BERT的內部是Transformer的encoder,裡面是Self-attention,不管天涯海角,句子都會有相關聯,因此放起始處還是可以取得所有訊息的context。 文獻上記錄著,兩個方法一起用的效果最好。基本上可以將BERT視為一種抽feature的方法,經過BERT取得embedding,就可以拿著這個embedding來做你想做的事情。 ### How to user BERT - Case 1 ![](https://i.imgur.com/B4RkeS3.png) 在BERT的論文中並非單純的將BERT視為抽feature的工具,而是與整個任務一起訓練,論文中說明了四種範例,這邊說明第一種。 假設任務input-sentence, output-class:舉例來說,輸入一個句子,判斷它的情緒是正面還是負面,或是文章分類。這時候"CLS"的output就可以去predict是那一個類別。 目前網路上已經有中文的BERT,因此取用的話,對於classifier的部份是重新訓練,而BERT的部份則是微調即可。 ### How to user BERT - Case 2 ![](https://i.imgur.com/3YMogGF.png) 第二種範例,input-sentence,output-每一個word的class:舉例來說,Slot filling,決定每一個單詞應該放在那。這時候每一個input的output(embedding)都會經過一個classifier來決定它應該是那一個類別。 BERT與classifier是一起學習的,一樣的BERT是微調,而classifier是重新訓練。 ### How to user BERT - Case 3 ![](https://i.imgur.com/6gCFX7h.png) 第三種範例,input-兩個句子,output-class:舉例來說,要機器學會推論,給機器一個前提,一個假設,要機器回答對或不對,或者不知道,這是一個只有三個類別的分類問題。 一樣的在起始處放一個"CLS",它的output就是用來給classifier預測對、不對、不知道 ### How to user BERT - Case 4 ![](https://i.imgur.com/U8khR4S.png) 第四種範例,是解一種Extraction-based的問題,也就是QA。就跟以前考英聽一樣,聽一段很長的話,然後問機器問題,希望可以得到答案,可以注意到,答案都是在文章有出現的。 這種問題的解法,給定文章-$D$與問題-$Q$(以token sequence表示),假設$D$有N個token,而$Q$有M個token,兩個input經過QA Model得到兩個output-$s, e$(皆為整數),這兩個整數代表問題的答案落在第$s \ sim e$個token間。 舉例來說,簡報上的問題一,答案gravity是第17個word,因此output為$s=17, e=17$,而within a cloud的話假設是第77到第79個word,那output就是$s=77, e=79$。 ### How to user BERT - Case 4 ![](https://i.imgur.com/lriWnI9.png) ![](https://i.imgur.com/Eb1PBVP.png) 解QA Model的作法: 1. 給定問題$q$與文章$d$,中間以"SEP"接起來,起始一個"CLS" 2. 文章裡面的每一個詞彙經過BERT都會有一個embedding 3. 讓機器去學習兩個vector(紅、藍),其維度與output的embedding一樣 4. vector(紅)與文章的每一個詞彙做點積計算(dot product)得到scalar 5. 將得到的scalar經過softmax讓文章裡面的每一個詞彙都得到一個分數(範例$d_2$最高,因此$s=2$) 6. vector(藍)與文章的每一個詞彙做點積計算(dot product)得到scalar 7. 將得到的scalar經過softmax讓文章裡面的每一個詞彙都得到一個分數(範例$d_3$最高,因此$e=3$) 8. 取得答案$s=2, e=3$,即$d_2, d_3$ 如果這時候得到的答案是$e=3, s=2$,那應該就要回答此題無解。一樣的BERT只要微調,兩個vector是重頭訓練的。 ### Enhanced Representation through Knowledge Integration(ERNIE) ![](https://i.imgur.com/aNXustD.png) ERNIE是專門為中文所設計,因為BERT是單純的隨機蓋掉幾個WORD,這對中文而言太好猜出,因此ERNIE的概念是蓋掉一個詞彙。 ### What does BERT learn? ![](https://i.imgur.com/UhSynLB.png) [論文連結_BERT Rediscovers the Classical NLP Pipeline](https://arxiv.org/abs/1905.05950) [WHAT DO YOU LEARN FROM CONTEXT? PROBING FOR SENTENCE STRUCTURE IN CONTEXTUALIZED WORD REPRESENTATIONS ](https://openreview.net/pdf?id=SJzSgnRcKX) BERT每一層所學的就像是NLP的pipeline,先決定詞性,再決定文法,找出代名詞所指射的名詞...等。所以可以看的到,橫軸所代表的是不同的layer,縱軸則NLP的pipeline,不同的pipeline所output的embedding做weighted sum的反應會有所不同。舉例來說,POS的時候所需的可能是中間的10~13層。 ### Multilingual BERT ![](https://i.imgur.com/Llpnb6O.png) Google利用維基百科的資料,訓練一個BERT以104種語言進行訓練,雖然沒有進行翻譯的訓練,但透過看104種語言的文章,模型自己學習到了部份語言之間的對應關係。舉例來說,你給BERT去學著做英文文章分類,這時候它會同時自己學會中文文章的分類。 ### Generative Pre-Training(GPT) ![](https://i.imgur.com/EJrUJRG.png) GPT是一個非常巨大的language model,以上圖來看確實巨大,參數量也嚇人。GPT就是Transformer的decoder。 ### Zero-shot Learning? ![](https://i.imgur.com/tb6nTGJ.png) GPT2可以在完全沒有訓練資料的情況下完成幾件事: * Reading Comprehension(QA) * 給定一篇文章$d$,問問題$Q:$,問它$A:$,就會得到答案 * Summarization * 給定一篇文章,問"TL;DL:",就可以得到一篇摘要 * Translation * 給定兩個英、法句子,最後只要再給一個英文句子,GPT2就會給你法文句子 GPT2可以做到zero-shot learning,這人讓感到非常神奇,而且效果還不錯,以右上趨勢圖來看(縱軸為F1-score,橫軸為GPT2參數量),在1542M參數量的時候可以達到DrQA的效能(上圖為Reading Comprehension的結果)。 GPT2是利用40G的資料所訓練出來的結果,或許是因為在文章內含有"A:"類的QA,因此只要看到"A:",GPT2就會自動的給你答案。 ### Visualization ![](https://i.imgur.com/Kwozzf5.png) 上圖是對GPT2的可視化觀察,右邊的圖所代表的說明:左邊為下一層的結果,右邊為上一層要被attention的對象,可以看的到"She"所atten的是"nurse",而"He"所atten的是"The docker" 左邊的圖則是對不同層的不同head的分析,可以看的到,左邊很多都atten到右邊第一個詞彙,這有一種可能,就是不需要atten,因此機器自己學到這種情況就atten到第一個詞彙就可以。 ### OpenAI ![](https://i.imgur.com/vDTRKFL.png) GPT2是OpenAI所訓練,上圖就是讓GPT2自己生成一篇文章的結果,給定上面的一個起頭,下面都是由機器所生成,這也是為什麼GPT2的形象是獨角獸的原因。 ### Demo ![](https://i.imgur.com/9iBknCH.png) [Transformer Demo](https://talktotransformer.com/) 所用的是完整版的GPT2,與課程時候相比已有更新。