當前位置:
首頁 > 科技 > 谷歌、DeepMind和OpenAI都在用的Transformer是如何工作的?

谷歌、DeepMind和OpenAI都在用的Transformer是如何工作的?

乾明 編譯整理

量子位 報道 | 公眾號 QbitAI

要說當前人工智慧研究中哪個架構最火,Transformer絕對能占其一。

不論是各處霸榜的谷歌BERT、OpenAI最近的強大NLP模型GPT-2,還是DeepMind擊敗星際2頂尖職業玩家的AlphaStar,背後都有?Transformer的身影。

那麼,它是如何工作的?

最近,畢業於MIT的開發者Giuliano Giacaglia發表了一篇博客文章,通過動畫圖解的形式,解讀了?Transformer的工作原理,對於想要了解相關內容的人來說,是一篇不錯的入門文章。

Transformer的問世,是為了解決序列轉換以及神經機器翻譯的問題。

它能用來處理各種seq2seq的任務,比如語音識別、文本-語音轉換等等。

序列轉換過程,綠色是輸入,藍色是模型,紫色是輸出。

對於執行序列轉換的模型來說,必須要有某種形式的記憶。

比如說翻譯下面的這個句子:

「The Transformers」是一個日本的硬核朋克樂隊。這支樂隊成立於1968年,當時正值日本音樂史上的鼎盛時期

在這個例子中,第二句中的「樂隊」一詞,指代的是第一句中介紹的樂隊「The Transformers」。

作為人類,當你在第二句中讀到這個詞的時候,你知道它就是在指「The Transformers」樂隊。

這對機器翻譯來說非常重要,有很多情況下,句子中的一個單詞,是在代指前面句子中的單詞。

想要更好的翻譯這樣的句子,模型就需要找出單詞之間的依賴和聯繫。

用來處理這一問題的,正是循環神經網路(RNN)和卷積神經網路(CNN)。

這兩個網路各有各的特性,在開始解釋Transformer之前,先來回顧下這兩種網路架構和相應的缺點。

循環神經網路

循環神經網路中具有循環架構,可以讓信息持久存在。

輸入表示為x_t

在上圖中,我們能夠看到神經網路A的一部分,處理輸入x_t和輸出h_t。循環的存在,允許信息從一個步驟傳遞到下一個步驟。

我們可以從不同的角度來看待這一循環。一個循環神經網路,可以被看作由多個網路A組成,每個網路向後傳遞一條消息。如果把循環神經網路展開,就會是這樣子的:

這種鏈式特性表明,循環神經網路顯然與序列和列表有關。

這樣的話,如果想翻譯某些文本,就可以將這個文本中的單詞設置為輸入。循環神經網路就會將前面的單詞信息傳遞給下一個網路,下一個網路可以使用和處理這些信息。

下圖顯示了seq2seq模型使用循環神經網路的工作原理。每個單詞都是單獨處理的,通過將隱藏狀態傳遞給解碼器來生成結果句子,然後生成輸出。


長期依賴的問題

假設要做一個可以根據前面的單詞預測下一個單詞的模型。

如果用它預測句子「the clouds in the sky」的下一個單詞,就不需要太多上下文信息了。很明顯,下一個詞將是sky

在這種情況下,相關信息和需要用到它的地方之間的距離很小,循環神經網路可以學習使用過去的信息,找出這個句子的下一個單詞。

但有些情況下,我們需要更多的上下文。比如要預測「 「I grew up in France… I speak fluent …」文本中的最後一個詞是什麼。

最近的信息表明,下一個單詞可能是一種語言,但如果想縮小範圍,就需要France的上下文信息了。

當相關信息與需要信息的地方之間的差距離非常大時,循環神經網路就基本沒用了。這是因為,在循環神經網路中,信息是逐步逐步傳遞的,鏈條越長,信息沿著鏈條丟失的可能性就越大。

理論上,循環神經網路可以學習這種長期的依賴關係。但在實踐中,它們似乎並沒有學會。LSTM是一種特殊類型的循環神經網路,被用來解決這類問題。


長短期記憶(LSTM)

在安排一天的日程時,我們會先按照當前的情況安排。如果有什麼重要的事情,我們可以取消一些會議,安排這些重要的事情。

但循環神經網路並不會這樣做。無論什麼時候添加新的信息時,它都會通過應用一個函數來完全轉換現有的信息,以至於整個信息都被修改了,而不會考慮什麼是重要的,什麼不是重要的。

LSTM通過乘法和加法對信息進行小的修改。在LSTM中,信息通過一種稱為單元狀態的機制傳遞。通過這種機制,LSTM可以選擇性地記住重要的事情,或者忘記不重要的事情。

LSTM的內部構造如下圖所示:

每個單元,將x_t(句子到句子轉換的情況下是一個單詞)、前一個單元狀態和前一個單元的輸出作為輸入。它操縱這些輸入,並基於它們產生新的單元狀態和輸出。

在單元狀態下,翻譯時句子中對翻譯單詞很重要的信息,可以從一個單詞傳遞到另一個單詞。


LSTM的問題

一般來說,循環神經網路遇到的問題,LSTM上也會出現。比如在句子很長的時候,LSTM也不太管用。

背後的原因是,保持上下文信息與當前被處理單詞聯繫的可能性,會隨著距離的增加呈指數級下降。

這意味著,當句子很長時,模型經常會忘記序列中距離位置較遠的內容。

循環神經網路和 LSTM 的另一個問題是,處理句子的工作很難並行化,必須要逐單詞處理。不僅如此,還沒有長期和短期依賴的模型。

綜上所述,LSTM和循環神經網路一共存在三個問題:

順序計算抑制了並行化

沒有對長期和短期依賴關係的明確建模

位置之間的「距離」是線性的


注意力(Attention)

為了解決其中一些問題,研究人員創造了一種關注特定單詞的技術。

就我自己而言,在翻譯一個句子的時候,我會特別注意自己正在翻譯的單詞。

如果要描述自己所在的房間,我會先掃一眼,看看周圍都有啥東西。

神經網路可以通過注意力機制來實現同樣的行為,把注意力集中在給定信息的子集上。

使一個循環神經網路,可以參與到另一個循環神經網路的輸出中。

在每一步,它都將注意力集中在另一個循環神經網路中的不同位置。

對於循環神經網路來說,不僅僅是將整個句子編碼為隱藏狀態,每個單詞都會有一個對應的隱藏狀態,這個隱藏狀態一直傳遞到解碼階段。

然後,在循環神經網路的每個步驟中使用隱狀態進行解碼。下面的動圖展示了運作原理:

綠色是編碼階段,紫色是解碼階段。

它背後的想法是,一個句子中的每個單詞,都可能有相關的信息。因此,為了使解碼更加精確,需要利用注意力機制關注輸入的每一個單詞。

為了在用於序列轉換的循環神經網路中引入注意力機制,編碼和解碼主要分為兩個步驟。

如上圖所示,綠色步驟是編碼階段,紫色步驟是解碼階段。

編碼階段負責創建隱藏狀態。

在沒有引入注意力機制之前,只是將一個隱藏狀態傳遞給解碼器。現在它要將句子中每個「單詞」產生的所有隱藏狀態傳遞到解碼階段。

每個隱藏狀態都在解碼階段使用,來找出網路應該注意的地方。

例如,當把「Je suis étudiant」(我是學生)這個句子翻譯成英語時,在解碼的步驟,要看不同的單詞。

下面這個動圖,就展示了每個隱藏狀態的權重,顏色越深,權重越高。

但是,上面討論過的一些問題,使用引入注意力機制的循環神經網路也沒法解決。

比如並行處理輸入(單詞)是不可能的。

如果有大量文本需要翻譯的話,這會大幅度增加翻譯時間。

卷積神經網路(CNN)

卷積神經網路有助於解決這些問題,它能夠:

並行化(每層)

利用位置的依賴關係

位置之間的距離是呈對數的

一些用於序列轉換的流行神經網路,比如Wavenet、Bytenet,都是卷積神經網路。

Wavenet的架構。

卷積神經網路之所以能夠並行工作,是因為可以同時處理輸入的每個單詞,並且也不一定依賴於要翻譯的前面的單詞。

不僅如此,卷積神經網路的輸出單詞和輸入之間的「距離」是以 log (N)函數的順序排列的,大致如上面的動圖所示。

這比一個循環神經網路的輸出和輸入之間的距離呈指數級變化要「友好」得多。

但卷積神經網路的問題在於,它不一定能夠解決句子翻譯中的依賴問題。

這就是Transformer被創造出來的原因,它是注意力機制和卷積神經網路的結合體。

Transformer

為了解決並行化問題,Transformer嘗試將卷積神經網路與注意力模型相結合起來。

在Transformer中,使用的自注意力機制(self-attention),提高了從一個序列轉換到另一個序列的速度。

Transformer是由六個編碼器和六個解碼器組成的。

編碼器和解碼器,各自之間也都非常相似。 每個編碼器由兩層組成:自注意力和前饋神經網路。

編碼器的輸入,首先經過一個自注意力層。

這有助於編碼器在編碼特定單詞時,查看輸入句子中的其他單詞。

解碼器中也有這兩層,但在它們之間有一個注意力層,幫助解碼器專註於輸入句子的相關部分。


自注意力

接下來,就要開始研究各種向量/張量了,看它們如何在這些組件之間流動,從而將訓練模型的輸入轉化為輸出。

正如自然語言處理應用的通常情況一樣,首先使用嵌入演算法將每個輸入單詞轉換成一個向量。

每個單詞被嵌入到大小為512的向量中,用上圖中的簡單方塊來表示。

嵌入只發生在最底層的編碼器中。所有編碼器共有的抽象信息是,它們接收到一個大小為512的向量列表。

在底層的編碼器中,這是詞嵌入,但在其他編碼器中,它是下層編碼器的輸出。輸入序列中的詞都進行嵌入之後,每個單詞都會經過編碼器兩層架構中的每一層。

這就凸顯出了Transformer的一個關鍵屬性,即每個位置的單詞,在編碼器中通過它自己的路徑傳遞。

在自注意力層,這些路徑之間存在依賴關係。但是,前饋神經網路層沒有這些依賴關係,因此各種路徑可以在流經前饋神經網路層時並行執行。

接下來,以一個更短的句子為例,看看編碼器的每個子層中發生了什麼。

首先,是如何用用向量計算自注意力,然後再看看它實際上是如何使用矩陣實現的。

找出句子中單詞之間的關係,並給予正確的權重。

計算自注意力的第一步,是從編碼器的每個輸入向量中創建三個向量。

在當前的例子中,是每個單詞的嵌入。

因此,對於每個單詞,分別創建一個Query向量、一個Key向量和一個 Value向量。

這些向量是通過將嵌入乘以在訓練過程中訓練的三個矩陣來創建的。

請注意,這些新向量在維數上比嵌入向量小。

它們的維數是64,而嵌入和編碼器輸入/輸出向量的維數是512。

它們不一定要更小,這是一個讓多頭注意力的大部分計算恆定的架構選擇。

用WQ權重矩陣乘以x1得到q1,即與該單詞關聯的Query向量。

最終在輸入句子中為每個單詞創建一個Query、一個Key和一個Value的映射。

什麼是Query、Key和Value向量?它們是對計算和思考注意力有用的抽象概念。

在下面計算注意力的環節,就會知道這些向量所扮演的角色。

計算自注意力的第二步是計算分數。

假設要計算這個例子中第一個單詞「Thinking」的自注意力,需要將輸入句子中的每個單詞與這個單詞進行比較打分。

分數決定了在某個位置編碼一個單詞時,對輸入句子其他部分的關注程度。

計算分數的方法,是取要評分單詞的Query向量與Key向量的點積。

所以如果處理位置 #1中單詞的自我注意力,第一個得分是q1和k1的點積。

第二個得分是q1和 k2的點積。

第三步第四步,是將得分除以8 ,然後通過softmax傳遞結果。

Softmax將分數標準化,這樣它們都是正數,加起來等於1。

這個softmax分數,決定了每個單詞在這個位置有多重要。

顯然,在這個位置的單詞,將有最高的softmax分數,但是有時候注意與當前單詞相關的另一個單詞是很有用的。

第五步是將每個Value向量乘以softmax得分(準備求和)。

這一步是保持要關注的單詞的值不變,屏蔽掉不相關的單詞(例如,用0.001這樣的小數字與它們相乘)。

第六步是對加權Value向量求和。然後產生自注意力層的輸出(第一個單詞)。

自注意力計算到此結束。

由此產生的向量是可以發送給前饋神經網路的向量。

然而,在實際實現中,為了更快的處理,這種計算是以矩陣形式進行的。


多頭注意力(Multihead attention)

Transformer基本上就是這樣工作的。還有一些其他的細節,可以讓它們運作得更好。

例如,Transformer使用了多頭注意力的概念,使其不僅僅在一個維度上注意彼此。

背後的想法是,每當翻譯一個單詞時,可能會根據你所問的問題類型,對每個單詞給予不同的注意力。下圖顯示了這意味著什麼。

例如,當你在翻譯「I kicked the ball」這個句子中的 「kicked」時,你可能會問「Who kicked」。

根據答案的不同,這個單詞翻譯成另一種語言時可能會有所不同。或者也可以問其他問題,比如「Did what?」等等。


位置編碼

Transformer的另一個重要步驟,是在對每個單詞進行編碼時添加位置編碼,這是有必要的,因為每個單詞的位置都與翻譯結果相關。

-完-

https://medium.com/@giacaglia/transformers-141e32e69591

訂閱AI內參,獲取AI行業資訊

購買AI書籍

誠摯招聘

量子位正在招募編輯/記者,工作地點在北京中關村。期待有才氣、有熱情的同學加入我們!相關細節,請在量子位公眾號(QbitAI)對話界面,回復「招聘」兩個字。

喜歡就點「好看」吧 !


喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 量子位 的精彩文章:

「OpenAI,請開源你的模型!越公開越安全,本來也不危險。」

TAG:量子位 |