圖解BERT(NLP中的遷移學習)

dicksonjyl560101發表於2019-04-24

https://www.toutiao.com/a6683264219846017540/


2019-04-24 09:18:30

本文翻譯自Jay Alammar的部落格The Illustrated BERT, ELMo, and co. (How NLP Cracked Transfer Learning)

2018年是機器學習模型處理文字(更準確地說,是自然語言處理或簡稱NLP)的轉折點。我們對以何種方式捕捉潛在語義和關係的來表示單詞和句子這一問題的理解也在迅速發展。此外,NLP社群中也有人分享了許多了非常強大的模型供你免費下載並在自己的模型和pipeline中使用(它被稱為NLP的ImageNet moment,參考了多年前計算機視覺的快速發展)。


圖解BERT(NLP中的遷移學習)


其中一個最新的里程碑就是BERT的釋出,這被人們看作是NLP新時代的開始。BERT是一個打破了許多基於語言的任務中的記錄。在論文釋出後不久,該模型的團隊還開源了模型的程式碼,並提供了模型的下載版本,這些模型已經在大資料集上進行過了預訓練。這是一個重大的進步,因為它使任何想要構建自然語言處理的機器學習模型的人都可以將這個強大的預訓練好的模型作為一個隨時可用的元件使用——從而節省了從頭開始訓練模型所需的時間、精力、知識和資源。


圖解BERT(NLP中的遷移學習)


使用BERT的兩個步驟。第一步:下載預訓練好的模型;第二步:在特定任務上進行微調

BERT也是基於最近在NLP社群中湧現的許多聰明的想法,包括 Semi-supervised Sequence Learning (by Andrew Dai 和 Quoc Le), ELMo (by Matthew Peters 和來自 AI2 and UW CSE的研究人員), ULMFiT (by fast.ai 創始人 Jeremy Howard 和大牛 Sebastian Ruder), OpenAI transformer (by OpenAI 研究員Radford, Narasimhan, Salimans, and Sutskever), 以及Transformer (Vaswani et al)等.

要正確理BERT是什麼,我們需要了解許多概念。倒不如先看看BERT有哪些用途。

一、例子:句子分類

最直接的想法就是使用BERT進行單個文字的分類。這個模型看起來是這樣的:


圖解BERT(NLP中的遷移學習)


要訓練這樣的模型,您需要重點訓練一個分類器,在訓練階段對BERT模型的改動非常小。這種訓練過程稱為微調(fine-tuning),其根源在於 Semi-supervised Sequence Learning 和ULMFiT。

對於不熟悉這個概念的人來說,由於我們討論的是分類器,所以在這個任務中涉及到的是機器學習中的監督學習。這意味著我們需要一個標記好的資料集來訓練這樣的模型。以垃圾郵件分類為例,標記的資料集將是一個電子郵件訊息列表和一個標籤(標註“垃圾郵件”或“非垃圾郵件”)。


圖解BERT(NLP中的遷移學習)


類似的任務場景還有:

  • 情感分析
  • 輸入: 一條影評/商品評價。
  • 輸出: 正面評價還是負面評價?
  • 資料集如: SST
  • 事實核查
  • 輸入:一個句子。
  • 輸出: 是不是一個斷言
  • 更難的任務:
  • 輸入: 一句斷言。
  • 輸出: 真的還是假的
  • Full Fact 組織構建了一個自動事實核查工具。這個工具的流程中包含了一個分類器,這個分類器讀取新聞文章來檢測斷言.
  • 視訊: Sentence embeddings for automated factchecking - Lev Konstantinovskiy.

二、模型架構

現在您已經有了一個BERT的用例,接下來讓我們進一步瞭解它是如何工作的。


圖解BERT(NLP中的遷移學習)


Google在論文中提到了兩個不同模型規模的BERT:

  • BERT BASE –和OpenAI Transformer模型的規模差不多,方便與其進行效能比較
  • BERT LARGE – 一個達到目前多個benchmark的SO他的巨大的模型

BERT基本上就是一個訓練好的Transformer編碼器棧。關於Transformer的內容可以看看 圖解Transformer這篇博文。Transformer是BERT的基礎,下面我們也會涉及到這個概念。


圖解BERT(NLP中的遷移學習)


兩種規模的BERT模型都有許多編碼器層 (在論文中稱為“Transformer塊”) – BERT Base有12個這樣的結構,BERT Large有24個。編碼器中也有前饋網路 (BERT Base中的是768個隱層神經元,BERT Large中的是1024個隱層神經元), 以及注意力層中使用了比Transformer那篇論文中更多的“頭” (BERT Base有12個“頭”,BERT Large中有16個)。

模型的輸入


圖解BERT(NLP中的遷移學習)


輸入序列的第一個token是一個特殊的符號[CLS],這裡的CLS代表class。

就像Transformer的編碼器一樣,BERT以一串單詞作為輸入,這些單詞不斷地想編碼器棧上層流動。每一層都要經過自注意力層和前饋網路,然後在將其交給下一個編碼器。


圖解BERT(NLP中的遷移學習)


在體系結構方面,到目前為止,還是與Transformer是相同的(除了一些超引數之外)。接下來在輸出端,我們會看到其和Transformer的不同之處。

模型的輸出

每個位置對應地輸出一個維度為 hidden_size (BERT Base中為768)的向量。對於之前提到的句子分類的例子,我們只關注第一個位置的輸出(也就是被我們用[CLS]符號代替的位置)。


圖解BERT(NLP中的遷移學習)


輸出的這個向量現在可以用作我們選擇的分類器的輸入。論文利用一個單層神經網路作為分類器,就能取得較好的分類效果。


圖解BERT(NLP中的遷移學習)


如果你有更多的標籤(例如,如果你是一個電子郵件服務提供商,你需要將電子郵件標記為“垃圾郵件”、“非垃圾郵件”、“社交”和“促銷”等等),你只需調整分類器這部分的網路,使其具有更多的輸出神經元,然後通過softmax。

三、與卷積網路並行

對於有CV背景的人來說,這種向量傳遞應該讓人想起像VGGNet這樣的網路的卷積部分和網路結構最後的全連線層之間發生的事情。


圖解BERT(NLP中的遷移學習)


四、嵌入表示的新時代

這些新的探索帶來了文字編碼方式的新轉變。到目前為止,在絕大多數的NLP模型中,詞嵌入一直是一個主要的文字表示方法。Word2Vec、Glove等方法已廣泛應用於此類任務。下面先讓我們回顧一下如何使用它們。

回顧一下詞嵌入

為了要讓機器學習模型能夠處理單詞,我們需要以數字的形式表示文字,以便模型在計算中使用。通過使用Word2Vec,我們可以用一個向量來代表單詞,而這一向量還捕捉了一定的語義資訊(如“斯德哥爾摩”和“瑞典”的關係相當於“開羅”與“埃及”的關係)以及語法資訊,或基於語法的關係(例如,“had”和“has”的關係與“was”和“is”的關係是一樣的)。

人們很快意識到,使用大量文字資料進行預訓練學習詞嵌入是一個好主意,而不是在小資料集上模型從零開始訓練。你可以下載預訓練的Word2Vec或GloVe。下面是GloVe訓練得到的“stick”對應的向量表示(嵌入向量維度為200)。


圖解BERT(NLP中的遷移學習)


由於維度很大,在後面的文章中會用下面這種形狀代表向量:


圖解BERT(NLP中的遷移學習)


ELMo: 語境的重要性

如果我們是使用GloVe訓練好的向量作為一個詞,比如“stick”的表示,那麼不管在什麼上下文中,這個表示都是一樣的。在一些研究中 (Peters et. al., 2017, McCann et. al., 2017, Peters et. al., 2018 in the ELMo paper ),研究人員認為像“ stick ”這樣的詞其實有很多意思,具體是什麼意思取決於在什麼語境中用它。那麼為什麼不基於其上下文語境來學習一個詞的嵌入表示呢?也就是即學習到這個詞的上下文的語義,有學習到其他的語境資訊。就此,語境化的詞嵌入模型應運而生。


圖解BERT(NLP中的遷移學習)


語境化的詞嵌入模型能夠基於一個單詞的上下文的意思給出單詞的向量表示[RIP Robin Williams](https://www.youtube.com/watch?v=OwwdgsN9wF8)

ELMo沒有為每個單詞使用固定的嵌入,而是在為每個單詞分配嵌入之前檢視整個句子。它使用針對特定任務的雙向LSTM來建立這些嵌入。


圖解BERT(NLP中的遷移學習)


ELMo為在語境中進行預訓練提供了重要的思路。ELMo LSTM能夠在大資料集上進行訓練,然後作為其他模型的一個部分處理其他的自然語言任務。

ELMo的祕訣是什麼?

ELMo通過訓練預測單詞序列中的下一個單詞來理解語言——這項任務被稱為 語言建模 。這很方便,因為我們有的是大量的文字資料,這樣的模型可以從這些資料中學習,而不需要額外的標籤。


圖解BERT(NLP中的遷移學習)


ELMo進行預訓練的一個步驟:給定輸入“Let’s stick to”, 預測接下來一個詞,這就是語言模型的任務。當模型在大語料上進行預訓練,他就會學習其中的語言模式。它不太可能準確地直接地猜出這個例子中的下一個單詞。更實際一點說,在“hang”這樣的單詞之後,它將為“out”這樣的單詞分配更高的概率(組成 “hang out”) 而不是給“camera”分配更高的概率。

我們可以看到每個LSTM時間步的隱狀態從ELMo的“頭部”後面探出來。這些向量會在預訓練結束後的嵌入過程中會派上用場。

ELMo實際上更進一步,訓練了一個雙向的LSTM——這樣它的語言模型不僅能預測下一個詞,還有預測上一個詞。


圖解BERT(NLP中的遷移學習)


[Great slides](https://www.slideshare.net/shuntaroy/a-review-of-deep-contextualized-word-representations-peters-2018) on ELMo

ELMo通過將隱藏狀態(和初始嵌入)以某種方式(拼接之後加權求和)組合在一起,提出了語境化的詞嵌入。


圖解BERT(NLP中的遷移學習)


五、ULM-FiT:搞懂NLP中的遷移學習

ULM-FiT引入了一些方法來有效地利用模型在預訓練中學到的東西——不僅僅是嵌入,還有語境化的嵌入表示。ULM-FiT引入了一個語言模型和一套針對各種任務有效地對語言模型進行微調的流程。

NLP終於找到了一種方法,可以像CV那樣進行遷移學習了。

六、Transformer:超越LSTM

Transformer的論文和程式碼的釋出,以及它在機器翻譯等任務上取得的成果,開始使一些業內人士認為它是LSTM的替代品。Transformer比LSTM更能處理長期依賴。

Transformer的編碼器-譯碼器結構使其成為機器翻譯的理想模型。但是你會如何使用它來進行句子分類呢?你將如何針對其他特定任務對語言模型進行微調呢?

七、OpenAI Transformer:為語言建模預訓練一個Transformer解碼器

事實證明,我們可以不用一個完整的Transformer來遷移學習並進行微調。我們可以只用Transformer的解碼器就可以了。解碼器是一個很好的選擇,因為它能遮蔽掉後來的詞(當進行逐詞生成翻譯時,這是一個很有用的特性)。


圖解BERT(NLP中的遷移學習)


The OpenAI Transformer 是由Transformer的解碼器棧組成的

這個模型堆疊了12個解碼器層。由於在這種設計中沒有編碼器,因此這些解碼器層也不會有Transformer原文中的那種編碼器-解碼器注意力子層。但是,仍然還是有自注意力層。

有了這種結構,我們可以繼續在相同的語言建模任務上進行訓練模型:使用大量(未標記的)文字來預測下一個單詞。只是,把7000本書的文字扔給模型,讓它學習!書籍非常適合這類任務,因為它允許模型學習相關聯的資訊,而當您使用tweet或文章進行訓練時,您無法獲得這些資訊。


圖解BERT(NLP中的遷移學習)


The OpenAI Transformer現在已經準備好被訓練成能夠預測下一個單詞了

八、在下游任務中使用遷移學習

既然OpenAI Transformer已經經過了預訓練,而且它的各個層也經過了調整,我們就可以開始在下游任務中使用它了。讓我們先來看看句子分類(將郵件資訊分為“垃圾郵件”或“非垃圾郵件”):


圖解BERT(NLP中的遷移學習)


How to use a pre-trained OpenAI transformer to do sentence clasification

OpenAI的論文列出了許多用於處理不同型別任務輸入的輸入變換。下圖顯示了模型的結構和執行不同任務時的輸入變換。


圖解BERT(NLP中的遷移學習)


九、BERT:從解碼器到編碼器

openAI Transformer為我們提供了一個基於Transformer的可微調的預訓練的模型。但是把LSTM換成Transformer還是讓有些東西丟失了。ELMo的語言模型是雙向的,而openAI Transformer則只訓練一個從左到右的語言模型。那麼我們能否建立一個既能從左到右預測又能從右到左預測(同時受上、下文的制約)的基於Transformer的模型呢?

MLM語言模型

“我們將使用Transformer編碼器” ,BERT說。

“這太瘋狂了” ,有人說,“ 每個人都知道雙向條件作用會讓每個詞在多層次的語境中間接地看到自己。

我們將使用掩碼 ”,BERT自信地說。


圖解BERT(NLP中的遷移學習)


BERT遮罩住15%輸入序列中15%的token,然後讓模型預測這些遮罩住的位置是什麼單詞

找到合適的任務來訓練Transformer的編碼器棧是一個複雜的問題,BERT採用了早期文獻(完形填空任務)中的“帶掩碼的語言模型”概念來解決這個問題。

除了遮蔽15%的輸入,BERT還混入一些東西,以改進模型的微調方式。有時它會隨機地將一個單詞替換成另一個單詞,並讓模型預測該位置的正確單詞。

兩個句子的任務

如果你還記得OpenAI Transformer處理不同任務時所做的輸入變換,你會注意到一些任務需要模型處理關於兩個句子的資訊(例如,一個句子是否是另一個句子的複述;再例如假設一個維基百科條目作為輸入,一個關於這個條目的問題作為另一個輸入,我們能回答這個問題嗎?)

為了讓BERT更好地處理多個句子之間的關係,預訓練的過程還有一個額外的任務:給定兩個句子(A和B), B可能是接在A後面出現的句子嗎?


圖解BERT(NLP中的遷移學習)


BERT預訓練的第二個任務是兩個句子的分類任務。

解決特定任務的模型

BERT論文展示了BERT在不同任務上的應用。


圖解BERT(NLP中的遷移學習)


用於特徵提取的BERT

微調的方法並不是使用BERT的唯一方法。就像ELMo一樣,你也可以使用預訓練好的BERT來建立語境化的詞嵌入。然後,您可以將這些嵌入表示餵給現有的模型——論文中也提到,在NER這類任務中,這種用法的最終效果也沒有比用微調的方法的結果差很多。


圖解BERT(NLP中的遷移學習)


哪種向量作為語境化嵌入的效果最好?我認為這取決於具體任務。論文比較了6中選擇(與微調後的96.4分模型相比):


圖解BERT(NLP中的遷移學習)


十、把BERT牽出來遛一遛

試用BERT的最好方法是通過在谷歌Colab上託管的BERT FineTuning with Cloud TPUs notebook。如果你之前從未使用過Cloud TPU,那麼這也是嘗試它們的一個很好的開始,而且BERT程式碼也可以在TPU、CPU和GPU上工作。

下一步可以看看 BERT程式碼實現:

  • 模型在 modeling.py (class BertModel)中定義,而且和原生的Transformer encoder非常相似。
  • run_classifier.py 是一個微調過程的例子。其中構造了一個分類層。如果你想構建自己的分類器,可以看看檔案中的 create_model()方法。
  • 一些預訓練模型可供下載。其中包括了BERT Base和 BERT Large,以及在中文、英文等102種語言的維基百科上預訓練得到的模型。
  • BERT並不是直接處理單詞,而是把 WordPieces作為token。 tokenization.py 是能夠將單詞轉換成wordPieces的指令碼。

你也可以參考 BERT的PyTorch實現。AllenNLP 用這個程式碼讓其他模型也能夠用BERT的嵌入表示

轉自:https://www.cnblogs.com/d0main/p/10165671.html


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/29829936/viewspace-2642362/,如需轉載,請註明出處,否則將追究法律責任。

相關文章