圖解當前最強語言模型BERT:NLP是如何攻克遷移學習的?

選自jalammar.github.io

機器之心編譯

參與:Panda

前段時間,谷歌發佈了基於雙向Transformer的大規模預訓練語言模型BERT,該預訓練模型能高效抽取文本信息並應用於各種NLP任務,該研究憑藉預訓練模型刷新了11項NLP任務的當前最優性能記錄。技術博主JayAlammar近日發文通過圖解方式生動地講解了BERT的架構和方法基礎。

2018年是機器學習模型處理文本(更準確地說是自然語言處理,簡稱NLP)的一個轉折點。如何最好地表徵詞和句子以便最好地理解其潛在含義和關係?我們對此的概念理解正在快速演進。此外,NLP社區也一直都在提出強大的新組件——你可以免費下載它們並將其用在你自己的模型和流程中(這被稱為NLP的ImageNet時刻,是指這類似於多年前用於計算機視覺任務的機器學習的加速發展)。

圖解當前最強語言模型BERT:NLP是如何攻克遷移學習的?

ULM-FiT和CookieMonster沒任何直接聯繫,但我想不到其它東西……

這一領域最近的里程碑是BERT的發佈,人們將這一事件譽為NLP新時代的開端。BERT這種模型打破了多項模型處理基於語言的任務的紀錄。在描述該模型的論文發佈之後不久,其研究團隊還開源了該模型的代碼,併發布了可供下載的模型版本——已經在大規模數據集上經過預訓練。這是一個重大的進展,因為它讓任何人都可以構建涉及語言處理的機器學習模型,並將這種強大工具用作其中的組件——這能節省從頭開始訓練語言處理模型所需的時間、精力、知識和資源。

圖解當前最強語言模型BERT:NLP是如何攻克遷移學習的?

BERT的開發分為兩個步驟。你可以下載在步驟1中預訓練過的模型(在無標註數據上訓練過);只需考慮針對步驟2進行調整。

BERT的開發基礎包含很多NLP社區內近期湧現出的聰明思路,其中包括但不限於半監督序列學習(來自AndrewDaiandQuocLe)、ELMo(來自MatthewPeters以及AI2和華盛頓大學計算機科學與工程系的研究者)、ULMFiT(來自fast.ai創始人JeremyHoward和SebastianRuder)、OpenAItransformer(來自OpenAI的研究者Radford、Narasimhan、Salimans和Sutskever)、Transformer(Vaswanietal)。

要恰當地瞭解BERT究竟是什麼,你需要了解很多概念。所以我們先來看看可以如何使用BERT,之後再介紹涉及該模型的概念。

示例:句子分類

使用BERT最直接的方式是將其用於分類單個文本。該模型看起來會是這樣的:

為了訓練這樣一個模型,你主要必須訓練分類器(Classifier),而讓BERT模型在訓練過程中有儘可能小的變化。這個訓練階段被稱為微調(Fine-Tuning),而且源自半監督序列學習和ULMFiT。

為不熟悉這一主題的人解釋一下:因為我們正在談論分類器,那麼我們就處於機器學習的監督學習領域。也就是說我們需要一個有標註的數據集來訓練模型。對於這個垃圾郵件分類器示例,有標註的數據集即為郵件信息和對應標籤構成的列表(每條郵件信息被標註為「垃圾郵件」或「非垃圾郵件」)。

圖解當前最強語言模型BERT:NLP是如何攻克遷移學習的?

這種用例的其它示例包括:

情感分析

輸入:電影/產品評論。輸出:這個評論是正面的還是負面的?

示例數據集:SST:https://nlp.stanford.edu/sentiment/

事實檢查

輸入:句子。輸出:「事實聲明」或「非事實聲明」。

更雄心勃勃且更有未來感的示例:輸入:稱述句。輸出:「真」或「假」。

FullFact是一家組織機構為公共利益構建的一款自動事實檢查工具。其一部分工作流程是讓分類器閱讀新聞並檢查聲明的事實(將文本分類為「事實聲明」或「非事實聲明」),之後再進行事實查證(這個事情現在是人類在做,希望未來能讓機器做)。

視頻:用於自動化事實查證的句子嵌入:https://www.youtube.com/watch?v=ddf0lgPCoSo

模型架構

現在你的腦子裡已經有一個有關BERT使用方式的示例用例了,現在我們來仔細看看它的工作方式。

圖解當前最強語言模型BERT:NLP是如何攻克遷移學習的?

這篇論文為BERT提出了兩種大小的模型:

BERTBASE:與OpenAITransformer大小相當,這是為了比較兩者的表現而構建的。

BERTLARGE:一個非常巨大的模型,實現了當前最佳。

BERT基本上就是一個經過訓練的TransformerEncoder的堆棧。現在該向你推薦我之前解釋Transformer的文章了:https://jalammar.github.io/illustrated-transformer/;Transformer模型是BERT以及我們後面將會討論的很多概念的基礎概念。

圖解當前最強語言模型BERT:NLP是如何攻克遷移學習的?

這兩種大小的BERT模型都有很多編碼器層(這篇論文稱之為TransformerBlocks)——Base版有12層,Large版有24層。相比於Transformer初始論文的參考實現的默認配置(6個編碼器層、512個隱藏單元和8個注意頭),它們還有更大的前饋網絡(分別有768和1024個隱藏單元)和更多注意頭(attentionhead,分為有12和16個)。

模型輸入

首個輸入的token由一個特殊的[CLS]token填補,原因後面就會明瞭。CLS表示Classification。

與Transformer的簡單純粹的編碼器一樣,BERT以詞序列為輸入,這些詞會在其堆棧中不斷向上流動。每一層都會應用自注意,並會通過一個前饋網絡傳遞它的結果,然後將其移交給下一個編碼器。

在架構方面,直到這部分為止都與Transformer完全相同(除了規模大小,見上述的配置)。在輸出的位置,我們開始看到不同。

模型輸出

每個位置都會輸出一個大小為hidden_size(BERTBase為768)的向量。對於我們上面看到的句子分類示例,我們僅關注第一個位置的輸出(即我們傳遞了特殊的[CLS]token的位置)。

圖解當前最強語言模型BERT:NLP是如何攻克遷移學習的?

現在,這個向量就可以被用作我們所選擇的分類器的輸入。這篇論文僅使用單層神經網絡作為分類器就取得了非常優良的結果。

圖解當前最強語言模型BERT:NLP是如何攻克遷移學習的?

如果你有更多標籤(比如如果你的電子郵件服務會將郵件標註為「垃圾郵件」、「非垃圾郵件」、「社交」、「廣告」),那麼你只需要調整分類器網絡使其具有更多輸出神經元,然後通過softmax即可。

對比卷積網絡

如果你有計算機視覺的背景,你可能會發現這種向量傳遞類似於VGGNet等網絡的卷積部分與網絡末端的全連接分類部分之間的情況。

嵌入的新時代

這些新進展帶來了詞編碼方式的轉變。到目前為止,詞嵌入一直都是推動NLP模型解決語言任務的主要力量。word2vec和GloVe等方法在這類任務上得到了廣泛的應用。我們先來看看之前的做法,然後再看現在有什麼變化。

回顧詞嵌入

要讓機器學習模型能處理詞,首先需要將詞表示成某種數值形式,以便模型進行計算。Word2Vec表明我們可以使用向量(某種數值列表)來恰當地表徵詞,使得這些表徵能具備詞之間的語義或含義關係(比如能說明詞的含義是否相似或相反,像是「斯德哥爾摩」和「瑞典」這一組詞與「開羅」和「埃及」這一組詞之間具有同樣的關係)以及句法或基於語法的關係(比如「had」和「has」之間的關係與「was」和「is」之間的關係一樣)。

這一領域很快認識到,使用在大規模文本數據上預訓練後的詞嵌入是一個很棒的思路,而不是在通常很小的數據集上與模型一起訓練詞嵌入。因此,人們就可以下載詞以及使用Word2Vec或GloVe預訓練後生成的詞嵌入了。下面是詞「stick」的GloVe嵌入示例(嵌入向量大小為200):

詞「stick」的GloVe詞嵌入,這是一個由200個浮點數(四捨五入到兩位小數)構成的向量。這裡給出的並不完整,總共有200個值。

因為這些向量很大而且都是數字,所以本文會使用下面的簡單圖形來表示它們:

ELMo:上下文很重要

如果我們使用這種GloVe表示方法,那麼不管上下文如何,詞「stick」都會表示成這個向量。很多NLP研究者意識到了這種操作並不穩妥,比如Peterset.al.,2017、McCannet.al.,2017以及Peterset.al.,2018的ELMo論文。根據使用的場景,「stick」可能具有多種含義。為什麼不根據其所處的語境/上下文來確定詞嵌入呢——這樣既能獲得該詞在上下文中的含義,還能得到其它語境信息?為此,語境化詞嵌入誕生了。

圖解當前最強語言模型BERT:NLP是如何攻克遷移學習的?

語境化詞嵌入能根據詞在句子語境中的含義給予其不同的嵌入。

ELMo並不為每個詞使用一個固定的嵌入,而是會在為句子中的詞分配嵌入之前檢查整個句子。它使用了一個在特定任務上訓練的雙向LSTM來創建這些嵌入。

圖解當前最強語言模型BERT:NLP是如何攻克遷移學習的?

ELMo是向NLP預訓練所邁出的重要一步。ELMoLSTM會在我們數據集的語言的一個大規模數據集上進行訓練,然後我們可以將其用作其它需要處理語言的模型的組件。

ELMo有何奧妙?

ELMo的訓練方式是預測一個詞序列的下一個詞,並以此來獲得對語言的理解——這個任務被稱為語言建模。這是很方便的,因為我們有大量文本數據,這樣的模型無需標籤也能學習。

圖解當前最強語言模型BERT:NLP是如何攻克遷移學習的?

ELMo的預訓練過程中的一步。給定「Let'sstickto」為輸入,預測下一個最有可能的詞——這是一個語言建模任務。在大型數據集上訓練時,模型會開始提取語言模式。在這個示例中,模型不太可能準確猜出下一個詞。更現實的情況是,比如在出現了「hang」這個詞之後,為「out」分配更高的概率(以拼出「hangout」),而不是「camera」。

我們可以看到從ELMo的頭部後面伸出的每個未展開的LSTM步驟的隱藏狀態。在這個預訓練完成之後,它們能用在嵌入過程中。

ELMo實際上更進了一步,訓練了一個雙向LSTM——使其語言模型不僅有對下一個詞的感知,還有對前一個詞的感知。

圖解當前最強語言模型BERT:NLP是如何攻克遷移學習的?

一個很讚的介紹ELMo的幻燈片:https://goo.gl/Fg5pF9

ELMo通過一種特定方式(連接之後加權求和)對隱藏狀態(和初始嵌入)進行分組,從而構建出語境化的嵌入。

圖解當前最強語言模型BERT:NLP是如何攻克遷移學習的?

ULM-FiT:解決NLP中的遷移學習

ULM-FiT引入了新的方法,可有效利用模型在預訓練階段學習到的很多東西——不只是嵌入,而且也不只是語境化嵌入。ULM-FiT引入了一種新語言模型和新處理過程,可針對多種任務對語言模型進行調整。NLP終於有一種做遷移學習的方法了,或許就像計算機視覺一樣。

Transformer:超越LSTM

Transformer論文和代碼的發佈以及其在機器翻譯等任務上取得的結果開始讓該領域內的一些人思考用Transformer替代LSTM。這是因為事實上Transformer在處理長期依賴方面優於LSTM。

Transformer的編碼器-解碼器結構使其能完美應用於機器翻譯。但我們如何將其用於句子分類呢?我們怎麼將其用於預訓練語言模型,然後再針對其它任務調整這個語言模型呢?(該領域將這些利用了預訓練的模型或組件的監督學習任務稱為下游任務)。

OpenAITransformer:為語言建模訓練Transformer解碼器

事實證明,我們不需要整個Transformer,就能將遷移學習和可調節的語言模型用於NLP任務。我們只需要Transformer的解碼器就夠了。解碼器是很好的選擇,因為這是語言建模的自然選擇(預測下一個詞),因為它是為得到未來token的掩碼而構建的——對逐詞生成翻譯任務而言,這是很有價值的特徵。

OpenAITransformer是由Transformer的解碼器堆棧構成的。

該模型堆疊了12個解碼器層。因為其中沒有編碼器,所以這些解碼器層不會有編碼器-解碼器注意子層(attentionsublayer),而原本的Transformer解碼器層中有這樣的注意子層。但是,OpenAITransformer中仍然有自注意層。

使用這種結構,我們可以繼續在同一語言建模任務上訓練該模型:使用大規模(無標註)數據集預測下一個詞。丟給它7000本書的文本讓它學習就行了!對這類任務而言,書籍是很棒的數據,因為書籍能讓模型學習關聯相關的信息,即使這些信息已被大量文本分隔開——當你用微博或文章等短篇幅文本進行訓練時,很難學到這類關聯屬性。

圖解當前最強語言模型BERT:NLP是如何攻克遷移學習的?

OpenAITransformer現在已經準備好基於7000本書構成的數據集來預測下一個詞了。

遷移學習到下游任務

現在OpenAITransformer已經過了預訓練,其中的層也經過了調節,可以合理地處理語言,我們可以開始將其用於下游任務了。首先我們來看看句子分類(將郵件消息分類為「垃圾郵件」或「非垃圾郵件」)。

圖解當前最強語言模型BERT:NLP是如何攻克遷移學習的?

如何使用預訓練後的OpenAITransformer來分類句子

OpenAI的論文羅列了一些輸入變換,用以處理不同類型的任務的輸入。下圖即來自該論文,展示了用於執行不同任務的模型結構和輸入變換。

圖解當前最強語言模型BERT:NLP是如何攻克遷移學習的?

是不是很巧妙?

BERT:從解碼器到編碼器

OpenAITransformer為我們提供了基於Transformer的可微調的預訓練模型。但在這種從LSTM到Transformer的過度中卻缺失了一些東西。ELMo的語言模型是雙向的,而OpenAITransformer僅訓練一個單向語言模型。我們能否構建出一種既能向前看也能向後看(即同時基於上文和下文)的基於Transformer的模型?

「瞧我的!」BERT說。

有掩碼的語言模型

BERT說:「我們將使用Transformer編碼器。」

「太瘋狂了,」Ernie說,「每個人都知道雙向調節會讓每個詞都在多層上下文中間接地看到自己。」

「我們將使用掩碼(mask)。」BERT自信地說。

圖解當前最強語言模型BERT:NLP是如何攻克遷移學習的?

BERT巧妙的語言建模任務會掩蓋輸入中15%的詞,並讓模型來預測缺失的詞。

尋找合適的任務來訓練Transformer編碼器堆棧是一個複雜的難題,BERT通過採用來自早期文獻的「有掩碼的語言模型」概念而解決了這一難題(在早期文獻中被稱為完形填空任務(Cloze))。

除了掩蔽15%的輸入,BERT還混用了一些方法來改善模型之後的調整。有時候它會隨機將一個詞替換成另一個詞,然後讓模型預測該位置的正確詞。

兩句子任務

如果你回頭看看OpenAITransformer用以處理不同任務的輸入變換,你會發現某些任務需要模型給出有關兩個句子的一些知識(比如它們是否只是彼此的複述版本?給定一個維基百科詞條以及涉及該詞條內容的問題作為輸入,我們能否回答該問題?)

要讓BERT更好地處理多個句子之間的關係,其預訓練過程還包括一項額外任務:給定兩個句子(A和B),B是否有可能是A後面的句子?

圖解當前最強語言模型BERT:NLP是如何攻克遷移學習的?

BERT預訓練的這個次級任務是一個兩句子分類任務。這幅圖中的token化過度簡化了一些,因為BERT實際上是使用WordPieces作為token,而不是使用詞——因此某些詞會被分解成更小的塊。

針對特定任務的模型

BERT論文展示了一些將BERT用於不同任務的方法。

圖解當前最強語言模型BERT:NLP是如何攻克遷移學習的?

將BERT用於特徵提取

微調方法並不是使用BERT的唯一方式。和ELMo一樣,你也可以使用預訓練後的BERT來創建語境化的詞嵌入。然後你可以將這些嵌入輸入你已有的模型——論文表明,在命名實體識別等任務上,該過程得到的結果並不比微調BERT差很多。

圖解當前最強語言模型BERT:NLP是如何攻克遷移學習的?

哪種向量最適合用作語境化嵌入?我認為這取決於具體任務。這篇論文考察了6種選擇(對比得到了96.4分的微調模型):

圖解當前最強語言模型BERT:NLP是如何攻克遷移學習的?

實際使用BERT

嘗試BERT的最好方式是動手過一遍使用CloudTPU的BERT微調,參考託管在GoogleColab上的筆記:https://goo.gl/vaZRH1。如果你之前從未用過CloudTPU,這就是你的上手時機!這些BERT代碼也適用於TPU、CPU和GPU。

接下來應該看看BERT代碼庫中的代碼:https://github.com/google-research/bert

模型構建在modeling.py之中(BertModel類),基本上與原始的Transformer編碼器完全一樣。

run_classifier.py是一個微調過程的示例。它也構建了這個監督式模型的分類層。如果你想構建自己的分類器,請查閱該文件中的create_model()方法。

其中提供了幾個可下載的預訓練模型。BERTBase和BERTLarge模型都有,涵蓋英語和漢語等語言,還有一個在維基百科上訓練的覆蓋了102種語言的多語言模型。

BERT並不將詞視為token,而是將WordPieces視為token。tokenization.py是token化算法,可將詞轉換成適用於BERT的WordPieces。

你還可以查看BERT的PyTorch實現。AllenNLP庫使用了這一實現,讓任何模型都可以使用BERT嵌入。

BERT的PyTorch實現:https://github.com/huggingface/pytorch-pretrained-BERT

AllenNLP:https://github.com/allenai/allennlp

最後附上機器之心發佈的BERT相關文章:

最強NLP預訓練模型!谷歌BERT橫掃11項NLP任務記錄

谷歌終於開源BERT代碼:3億參數量,機器之心全面解讀

資源|最強預訓練模型BERT的Pytorch實現(非官方)

推出一個半月,斯坦福SQuAD問答榜單前六名都在使用BERT

原文鏈接:https://jalammar.github.io/illustrated-bert/

本文為機器之心編譯,


分享到:


相關文章: