全文共7055字,預計學習時長14分鐘
BERT全稱是來自變換器的雙向編碼器表徵量(Bidirectional Encoder Representations from Transformers),它是Google於2018年末開發併發布的一種新型語言模型。與BERT模型相似的預訓練語言模型例如問答、命名實體識別、自然語言推理、文字分類等在許多自然語言處理任務中發揮著重要作用。
BERT是一種基於微調的多層雙向變換器編碼器。首先介紹下該變換器的架構,這一點尤為重要。
什麼是變換器(Transformer)?
2017年,谷歌發表了一篇題為《你所需要的是注意力》的論文,該論文提出一種基於注意力的結構,以處理與序列模型相關的問題,例如機器翻譯。傳統的神經機器翻譯大多使用迴圈神經網路(RNN)或卷積神經網路(CNN)作為編碼-解碼的模型庫。然而,谷歌這一基於注意力的變換器模型摒棄傳統的RNN和CNN公式。該模型高度並行執行,因此在提高翻譯效能的同時,其訓練速度也非常快。
進一步闡述變換器模型前,我們先對注意力做個介紹。
什麼是注意力(Attention)?
注意力機制可看作模糊記憶的一種形式。記憶由模型的隱藏狀態組成,模型選擇從記憶中檢索內容。深入了解注意力之前,先簡要回顧Seq2Seq模型。傳統的機器翻譯主要基於Seq2Seq模型。該模型分為編碼層和解碼層,並由RNN或RNN變體(LSTM、GRU等)組成。編碼向量是從模型的編碼部分產生的最終隱藏狀態。該向量旨在封裝所有輸入元素的資訊,以幫助解碼器進行準確的預測。其用於充當模型解碼器部分的初始隱藏狀態。
Seq2Seq模型的主要瓶頸是需要將源序列的全部內容壓縮為固定大小的向量。如果文字稍長,則很容易丟失文字的某些資訊。為解決這個問題,注意力應運而生。注意機制通過使解碼器回顧源序列隱藏狀態,然後將其加權平均值作為附加輸入提供給解碼器來緩解該問題。使用注意力,顧名思義,模型在解碼階段選擇最適合當前節點的上下文作為輸入內容。
注意力與傳統的Seq2Seq模型有兩個主要區別。
第一,編碼器向解碼器提供更多資料,並且編碼器會向解碼器提供所有節點的隱藏狀態,而不僅僅是編碼器的最後節點的隱藏狀態。
第二,解碼器不直接將所有編碼器提供的隱藏狀態作為輸入,而是採用選擇機制來選擇與當前位置最匹配的隱藏狀態。為此,它嘗試通過計算每個隱藏狀態的得分值並對得分進行softmax計算來確定哪個隱藏狀態與當前節點相關性最高,這使得隱藏狀態的更高相關性具有更大的分數值,不太相關的隱藏狀態具有較小的分數值。然後它將每個隱藏狀態與其softmax得分相乘,從而放大分數高的隱藏狀態,淹沒分數低的隱藏狀態。該評分練習在解碼器側的每個迭代時間完成。
現在,將注意機制用視覺化予以表現,研究注意流程如何進行:
1.注意解碼器RNN接收<END>令牌的嵌入和初始解碼器隱藏狀態。
2.RNN處理其輸入,產生一個輸出和一個新的隱藏狀態向量(h4),並丟棄輸入。
3.注意步驟:使用編碼器隱藏狀態和h4向量來計算該迭代時間的語境向量(C4)。
4.將h4和C4連成一個向量。
5.將這個向量傳遞給前饋神經網路(一個與模型共同訓練的網路)。
6.前饋神經網路的輸出即該迭代時間的輸出字。
7.重複下一個迭代時間的步驟
回到變換器
變換器模型使用編碼器-解碼器(encoder-decoder)架構。在谷歌發表的論文中,編碼層和解碼層都由6個編碼器堆疊而成。每個編碼器和解碼器的內部結構如下:
編碼器由兩層組成,一個自注意層和一個前饋神經網路。自我關注不僅有助於當前節點關注當前單詞,還能助其獲取上下文的語義。解碼器還包含編碼器提到的雙層網路,但在兩層中間還有一個注意層,以幫助當前節點獲得需要注意的關鍵內容。
以下是變換器架構的詳細結構:
接下來逐個分析其組成部分。
自注意(Self-Attention)
自注意是變換器將其他相關單詞的“理解”轉換為所處理的單詞的一種方式。
首先,自注意計算三個新的向量。在論文中,向量的維度是512維。將這三個向量分別稱為Query,Key和Value。這三個向量通過字嵌入向量與隨機初始化矩陣(論文中的維數為(64,512))相乘而產生的,並在反向傳播過程中不斷更新。
接下來,計算自注意的分數值,在某個位置編碼單詞時,它能決定在所輸入句子其餘部分投入的注意力。該分數值可通過Query和Key向量計算得出。然後用所得結果除以一個常數。本文中,該常數為8,這個值通常是上述矩陣第一維的平方根,即64的平方根8。然後對所有得分進行softmax計算。結果表示每個單詞與當前位置單詞的相關性。當然,當前詞的相關性肯定會很大。最後一步是將Value向量與softmax所得結果相乘並求和。結果是當前節點處的自注意值。
這種通過查詢和金鑰之間的相似度,來確定值的權重分佈的方法,被稱為縮放的點積注意。
多頭注意
本論文中更精闢的部分是增加了另一種自注意機制,稱為“多頭”注意,它不僅僅初始化一組Q,K,V矩陣。相反,初始化多個組,且變換器使用8個組,因此最終結果是8個矩陣。
前饋神經網路不能接受8個矩陣,因此需要一種方法將其減少為1個。為此,首先將8個矩陣連線在一起得到一個大矩陣,然後將這個組合矩陣與一個隨機初始化矩陣相乘得到最後的矩陣。整個流程如下圖所示。
變換器的多頭注意有三種使用方式:
1.在“編碼-解碼注意”層中,查詢來自先前的解碼器層,儲存器鍵和值來自編碼器的輸出。這使解碼器中的每個位置都參與輸入序列中的所有位置。並模擬出序列到序列模型中典型的編碼-解碼注意機制。
2.編碼器包含自注意層。在自注意層中,所有鍵、所有值和查詢都來自相同的位置,在這種情況下,它們來自於編碼器中前一層的輸出。編碼器中的每個位置都可以處理編碼器前一層中的所有位置。
3.與其相似的是,解碼器中的自注意層令解碼器中的每個位置參與到解碼器中的所有位置,直到幷包括該位置。在此需要預防解碼器中的向左資訊流,以此保持自迴歸屬性。通過掩蔽(設定為-∞)softmax中與非法連線相對應的所有值來實現縮放點積注意。這將在解碼器部分更加詳細地探討,在此僅討論掩蔽(Masking)。
位置編碼
到目前為止,還沒有辦法解釋變換器模型中輸入序列中的單詞順序。為了解決此問題,變換器在編碼器和解碼器層的輸入端增加了一個額外的向量位置編碼。其維度與嵌入維度相同。此位置編碼的值將新增到嵌入層的值中,並作為輸入傳送到下一層。位置編碼選項有很多,包括學習和修復。
殘餘連線和層規範化
在編碼器和解碼器中,在兩個子層的周圍都採用殘餘連線,然後進行層規範化。跳過連線或殘餘連線用於允許梯度直接流過網路,而不通過非線性啟用功能。非線性啟用函式本質上是非線性的,導致梯度爆炸或消失(取決於權重)。從概念上說,跳過連線形成一條“匯流排”,它在網路中流動,反過來,梯度也可以沿著它向後流動。規範化有助於解決內部協變數偏移的問題。內部協變數偏移是指在神經網路內發生的協變數偏移,即從(例如)第2層到第3層。這是因為當網路學習且權重被更新時,網路中特定層的輸出分佈會發生變化。這迫使較高層適應該漂移,這減慢了學習速度。在對神經網路中的輸入進行歸一化後,不必擔心輸入特徵的規模差別很大。要了解層規範化,將其與批規範化進行對比非常有用。一小批包含具有相同數量功能的多個示例。小批是矩陣 - 如果每個輸入是多維的,則為張量 - 其中一個軸對應批,另一個軸或多個軸對應特徵尺寸。批規範化規範批維度中的輸入要素。層規範化的關鍵特性是它可以對要素之間的輸入進行標準化。在批規範化中,統計資訊在批處理中計算,並且對於批中的每個示例都是相同的。相反,在層規範化中,統計資料是跨每個特徵計算的,並且與其他示例無關。
將殘餘連線和層規範化放在一起
解碼器
回看變換器體系結構圖,可以看到解碼器部分與編碼器部分相似,但底部有一個掩蓋的多頭注意。Mask表示遮蔽某些值的掩碼,以便在更新引數時它們不起作用。變換器模型中有兩種掩碼—填充掩碼和序列掩碼。填充掩碼用於所有縮放的點積注意,序列掩碼僅用於解碼器的自注意。
填充掩碼解決了輸入序列具有可變長度的問題。具體來說,在較短的序列後填0。但是如果輸入序列太長,則會擷取左側的內容,並直接丟棄多餘的內容。因為這些填充的位置實際上沒有意義,注意機制不應該集中在這些位置,所以需要做一些處理。具體方法是在這些位置的值上加一個非常大的負數(負無窮大),這樣這些位置的概率在softmax計算之後將接近0!填充掩碼實際上是一個張量,每個值都是一個布林值,false值指想要處理的值。
A序列掩碼旨在確保解碼器無法檢視將來的資訊。也就是說,對於序列,在time_step t,解碼輸出應該僅取決於t之前的輸出,而不取決於t之後的輸出。這針對於變換器架構,因為沒有RNN,可以按順序輸入序列。在此,一起輸入所有內容,如果沒有掩碼,多頭注意將考慮每個位置的整個解碼器輸入序列。通過生成上三角矩陣來實現這一點,上三角形的值全為零,並將該矩陣應用於每個序列。
對於解碼器的自注意,在此使用縮放的點積注意,並且新增填充掩碼和序列掩碼作為attn_mask。在其他情況下,attn_mask等於填充掩碼。
另一個細節是解碼器輸入將向右移動一個位置。這樣做的一個原因是不希望模型在訓練期間學習如何複製解碼器輸入,但還是想要了解給定編碼器序列和模型已經看到的特定解碼器序列,從而預測下一個單詞/字元。如果不移位解碼器序列,模型則簡單地學習“複製”解碼器輸入,因為位置 i 的目標字/字元將是解碼器輸入中的字/字元 i 。因此,通過將解碼器輸入移位一個位置,模型需要預測僅在解碼器序列中看到單詞/字元 1, …, i-1 的位置 i 的目標字/字元。這可以防止模型學習複製/貼上任務。用句子開頭令牌填充解碼器輸入的第一個位置,由於右移,該位置將是空的。類似地,將一個句末標記附加到解碼器輸入序列以標記該序列的結尾,並且它還附加到目標輸出語句。
輸出層
在完全執行解碼器層後,為將得到的向量對映到來自詞彙表的單詞,在結尾新增完全連線層和softmax層。
線性層是一個簡單的完全連線的神經網路,它將解碼器堆疊產生的向量投影到一個更大的向量中,稱為logits向量。假設模型知道從訓練資料集中學到的10,000個獨特的英語單詞(模型的“輸出詞彙表”) 這將使logits向量10,000個細胞變寬 - 每個單元對應於一個唯一單詞的得分。這就是對於線性層後的模型輸出的解釋。然後,softmax層將這些分數轉換為概率(所有正數,所有加起來都為1.0)。選擇具有最高概率的單元,並將與其相關聯的單詞作為該迭代時長的輸出。
回到BERT模型
BERT模型基於變換器架構。它是一種具有雙向深度的神經網路模型。BERT模型的關鍵技術創新是將變換器的雙向培訓應用於語言建模。這與先前從左到右檢視文字序列或從左到右和從右到左組合訓練的努力嘗試形成對比。BERT模型採用了一種名為掩蔽語言模型(Masked Language Modeling)的新技術(將在後文看到),它允許在從前不可能使用的模型中進行雙向訓練。在其vanilla form中,變換器包括兩個獨立的機制——讀取文字輸入的編碼器和產生任務預測的解碼器。由於BERT模型的目標是生成語言模型,因此只需要編碼器機制。
谷歌最初發布了兩個版本,如下圖所示。這裡L表示變壓器的層數,H表示輸出的維數,A表示多頭注意的數量。在這兩個版本中,前饋大小都設定為4層。
BERTBASE: L=12, H=768, A=12, Total Parameters=110M
BERTLARGE: L=24, H=1024, A=16, Total Parameters=340M
使用BERT模型有兩個階段:預訓練和微調。在預訓練期間,模型在不同的預訓練任務上訓練未標記的資料。對於微調,首先使用預訓練引數初始化BERT模型,並使用來自下游任務的標記資料對所有引數進行微調。每個下游任務都有單獨的微調模型,即使它們使用相同的預訓練引數進行初始化。BERT模型的一個顯著特點是它跨越不同任務的統一架構。預訓練架構與最終下游架構之間的差異很小。在微調期間,所有引數都經過微調。
BERT模型預訓練過程
BERT模型預訓練階段包括兩個無監督預測任務:掩蔽語言模型和下一句預測。
掩蔽語言模型(MLM)——由於BERT模型的雙向功能(雙向性)及其使用的多層自關注機制的效果,為了訓練深度雙向表示,一些百分比(論文中為15%)輸入令牌的輸入被簡單地隨機掩蓋,然後預測那些被遮蔽的令牌。對應於掩模標記的最終隱藏向量被饋送到詞彙表上的輸出softmax,如在標準學習模型LM中。與從左到右的語言模型預訓練不同,MLM目標允許表示融合的左側和右側的上下文,這使得可以預先訓練深度雙向變換器。雖然這允許獲得雙向預訓練模型,但缺點是預訓練和微調之間存在不匹配,因為在微調期間不出現[MASK]標記。為了緩解這種情況,作者並不總是用實際的[MASK]標記替換“蒙面”單詞。訓練資料生成器隨機選擇15%的令牌位置進行預測。如果選擇了第i個令牌,則將其替換為(1)[MASK]標記80%的時間(2)隨機標記10%的時間(3)未更改的第i個標記10%時間。BERT模型損失函式僅考慮掩蔽值的預測並忽略非掩蔽字的預測。因此,模型比定向模型收斂得慢,這一特徵被其增加的情境感知所抵消。
下一句預測(NSP)。為了訓練理解句子關係以及單詞之間的語義關係的模型,BERT模型還預先訓練二進位制化的下一句預測任務,該任務可以從任何文字語料庫中輕易生成。為A和B選擇一些句子,其中50%的資料B是A的下一個句子,剩餘的50%的資料B是在語料庫中隨機選擇的,然後學習相關性。新增這種預訓練的目的是許多自然語言處理任務(如QA和NLI)需要理解兩個句子之間的關係,以便預訓練模型能夠更好地適應這些任務。
為了幫助模型區分訓練中的兩個句子,輸入在進入模型之前按以下方式處理:
1.在第一個句子的開頭插入[CLS]標記,並在每個句子的末尾插入[SEP]標記。
2.在每個標記中新增表示句子A或句子B的句子嵌入。句子嵌入在概念上類似於詞彙量為2的標記嵌入。
3.向每個標記新增位置嵌入以指示其在序列中的位置。位置嵌入的概念和實現已在變換器論文中給出。
要預測第二個句子是否確實與第一個句子連線,需執行以下步驟:
1.整個輸入序列經過變換器模型。
2.使用簡單的分類層(權重和偏差的學習矩陣)將[CLS]標記的輸出轉換為2×1型的向量。
3.使用softmax計算IsNextSequence的概率。
在訓練BERT模型時,MLM和NSP是被同時訓練的,目標是最小化兩種策略的組合損失函式。
標記化—BERT模型不會將單詞視作標記。相反,它會看WordPieces。這意味著一個單詞可以分解為多個子單詞。這種標記化在處理詞彙單詞時是有益的,它可以幫助更好地表示覆雜的單詞。
BERT模型的輸入
BERT的輸入可以是單詞序列中的單個句子或句子對(例如,[問題,答案])。對於給定的單詞,其輸入表示可以由三部分嵌入求和組成。嵌入的視覺化表示如下所示:
標記嵌入表示單詞向量。第一個字是CLS標誌,可用於後續分類任務。對於非分類任務,可以忽略CLS標誌。段嵌入用於區分兩個句子,因為預訓練不僅是語言模型,而且還是具有兩個句子作為輸入的分類任務。位置嵌入編碼字順序。
用於下游自然語言處理任務的BERT模型微調
對於每個下游自然語言處理任務,只需將特定於任務的輸入和輸出插入BERT模型,並對端到端的所有引數進行微調。在輸入處,來自預訓練的句子A和句子B可類比於釋義中的句子對,蘊涵中的假設前提對,問題回答中的問題通道對等。在輸出處,標記表示被饋送到用於標記級別任務的輸出層,例如序列標記或問題回答,並且[CLS]表示被饋送到輸出層以進行分類,例如蘊涵或情緒分析。與預訓練相比,微調相對便宜。
BERT模型可用於各種語言任務,而只需在核心模型中新增一個小層:
1.通過在[CLS]標記的變換器輸出上新增分類層,類似於下一句分類,進行情感分析等分類任務。
2.在問題回答任務(例如SQUAD v1.1)中,軟體會收到有關文字序列的問題,並且需要在序列中標記答案。使用BERT模型,可以通過學習標記答案開始和結束的兩個額外向量來訓練Q&A模型。
3.在命名實體識別(NER)中,軟體接收文字序列,並且需要標記文字中出現的各種型別的實體(人員,組織,日期等)。使用BERT模型,可以通過將每個標記的輸出向量饋送到預測NER標籤的分類層來訓練NER模型。
BERT模型用於特徵提取
微調法不是使用BERT模型的唯一方法。可以使用預先訓練的BERT模型建立語境化詞嵌入。然後,可以將這些嵌入提供給現有的模型——該過程本文展示了產生結果,在命名實體識別等任務上微調BERT模型並不遠。
哪個向量最適合作為上下文嵌入呢?這要視任務而定。本文共考察了六種可選方法(與得分為96.4的微調模型相比):
我們一起分享AI學習與發展的乾貨
編譯組:胡昕彤、董宇陽
相關連結:
https://towardsdatascience.com/breaking-bert-down-430461f60efb