【深度學(xué)習(xí)】基礎(chǔ)知識 | 超詳細(xì)逐步圖解 Transformer
作者?|?Chilia???
整理?|?NewBeeNLP
1. 引言
讀完先修知識中的文章之后,你會發(fā)現(xiàn):RNN由于其順序結(jié)構(gòu)訓(xùn)練速度常常受到限制,既然Attention模型本身可以看到全局的信息, 那么一個自然的疑問是我們能不能去掉RNN結(jié)構(gòu),僅僅依賴于Attention模型,這樣我們可以使訓(xùn)練并行化,同時擁有全局信息?
你可能聽說過不同的著名Transformer模型,如 BERT、GPT 和 GPT2。在這篇文章中,我們將精讀谷歌的這篇 Attention is All you need[1] 論文來回顧一下僅依賴于Attention機(jī)制的Transformer架構(gòu)。
在開始之前,先讓我們看一個好玩的例子。Transformer可以根據(jù)你寫的一句開頭,寫出一段科幻小說!

「輸入:」 “As Aliens entered our planet”.
「Transformer輸出:」 “and began to colonized Earth, a certain group of extraterrestrials began to manipulate our society through their influences of a certain number of the elite to keep and iron grip over the populace.”
這真是一個黑暗的故事...但有趣的是研究模型是如何生成這個黑暗故事的。當(dāng)模型逐字生成文本時,它可以“關(guān)注”與生成的單詞相關(guān)的單詞(「attention」)。知道要關(guān)注哪些單詞的能力也是在訓(xùn)練過程中通過反向傳播學(xué)到的。

Transformer的優(yōu)勢在于,它可以不受梯度消失的影響,能夠保留任意長的長期記憶。而RNN的記憶窗口很短;LSTM和GRU雖然解決了一部分梯度消失的問題,但是它們的記憶窗口也是有限的。
Recurrent neural networks (RNN) are also capable of looking at previous inputs too. But the power of the attention mechanism is that it doesn't suffer from short term memory. RNNs have a shorter window to reference from, so when the story gets longer, RNNs can't access words generated earlier in the sequence. This is still true for Gated Recurrent Units (GRU) and Long-short Term Memory (LSTM) networks, although they do a bigger capacity to achieve longer-term memory, therefore, having a longer window to reference from. The attention mechanism, in theory, and given enough compute resources, have an 「infinite」 window to reference from, therefore being capable of using the entire context of the story while generating the text.

2.Attention Is All You Need — Step by Step Walkthrough
2.1 總體結(jié)構(gòu)
Transformer的結(jié)構(gòu)也采用了 Encoder-Decoder 架構(gòu)。但其結(jié)構(gòu)更加復(fù)雜,論文中Encoder層由6個Encoder堆疊在一起,Decoder層也一樣。

從整體來看,encoder將輸入序列做了一個復(fù)雜的、使用了高階信息的embedding;然后解碼器采用該embedding,同時還根據(jù)之前的輸出,一步一步地產(chǎn)生輸出。
每一個Encoder和Decoder的內(nèi)部結(jié)構(gòu)如下圖:

Encoder包含兩層,一個Self-attention層(「Multi-Head Attention」)和一個前饋神經(jīng)網(wǎng)絡(luò)層(「feed forward」),Self-attention層能幫助當(dāng)前節(jié)點不僅僅只關(guān)注當(dāng)前的詞,從而能獲取到上下文的語義。
Decoder也包含Encoder提到的兩層網(wǎng)絡(luò),但是在這兩層中間還有一層Attention層,幫助當(dāng)前節(jié)點獲取到當(dāng)前需要關(guān)注的重點內(nèi)容。
2.2 Encoder層詳細(xì)說明
首先,模型需要對輸入的數(shù)據(jù)進(jìn)行一個embedding操作,并輸入到Encoder層,Self-attention處理完數(shù)據(jù)后把數(shù)據(jù)送給前饋神經(jīng)網(wǎng)絡(luò),前饋神經(jīng)網(wǎng)絡(luò)的計算可以「并行」,得到的輸出會輸入到下一個Encoder。大致結(jié)構(gòu)如下:

就是embedding, 是經(jīng)過self-attention之后的輸出, 是經(jīng)過feed forward網(wǎng)絡(luò)之后的輸出,它們會被輸入到下一層encoder中去。
2.2.1 Embedding層
Transformer模型中缺少一種解釋輸入序列中單詞「順序」的方法,它跟序列模型還不一樣。為了處理這個問題,Transformer給Encoder層和Decoder層的輸入添加了一個額外的向量「Positional Encoding」,維度和embedding的維度一樣。這個位置向量的具體計算方法有很多種,論文中的計算方法如下:
其中 pos 是指當(dāng)前詞在句子中的位置, 是指向量中每個值的 index,可以看出,在偶數(shù)位置,使用正弦編碼,在奇數(shù)位置,使用余弦編碼。
所以,最終一個詞的embedding,就是它的語義信息embedding(預(yù)訓(xùn)練模型查表)+序列信息embedding (positional encoding):

2.2.2 Self-attention層
讓我們從宏觀視角看自注意力機(jī)制,精煉一下它的工作原理。
例如,下列句子是我們想要翻譯的輸入句子:
The animal didn't cross the street because 「it」 was too tired.
這個“it”在這個句子是指什么呢?它指的是street還是這個animal呢?這對于人類來說是一個簡單的問題,但是對于算法則不是。
當(dāng)模型處理這個單詞“it”的時候,自注意力機(jī)制會允許“it”與“animal”建立聯(lián)系。
隨著模型處理輸入序列的每個單詞,自注意力會「關(guān)注整個輸入序列的所有單詞」,幫助模型對本單詞「更好地進(jìn)行編碼(embedding)」。

如上圖所示,當(dāng)我們在編碼器#5(棧中最上層編碼器)中編碼“it”這個單詞的時,注意力機(jī)制的部分會去關(guān)注“The Animal”,將它的表示的一部分編入“it”的編碼中。接下來我們看一下Self-Attention詳細(xì)的處理過程。
「step1:」 首先,對于輸入序列的每個單詞,它都有三個向量編碼,分別為:Query、Key、Value。這三個向量是用embedding向量與三個矩陣( )相乘得到的結(jié)果。這三個矩陣的值在BP的過程中會一直進(jìn)行更新。
「step2:」 第二步計算Self-Attention的分?jǐn)?shù)值,該分?jǐn)?shù)值決定了當(dāng)我們在某個位置encode一個詞時,對輸入句子的其他部分的關(guān)注程度。這個分?jǐn)?shù)值的計算方法是用該詞語的Q與句子中其他詞語的Key做點乘。以下圖為例,假設(shè)我們在為這個例子中的第一個詞“Thinking”計算自注意力向量,我們需要拿輸入句子中的每個單詞對“Thinking”打分。這些分?jǐn)?shù)決定了在編碼單詞“Thinking”的過程中重視句子其它部分的程度。

「step3:」 再對每個分?jǐn)?shù)除以 (d是維度),之后做softmax。

「step4:」 把每個Value向量和softmax得到的值進(jìn)行相乘,然后對相乘的值進(jìn)行相加,得到的結(jié)果即是一個詞語的self-attention embedding值。

這樣,自注意力的計算就完成了。得到的向量就可以傳遞給前饋神經(jīng)網(wǎng)絡(luò)。
2.2.3 Multi-Headed Attention
通過增加一種叫做"多頭"注意力("multi-headed"attention)的機(jī)制,論文進(jìn)一步完善了自注意力層。
接下來我們將看到,對于“多頭”注意力機(jī)制,我們有多個Query/Key/Value權(quán)重矩陣集 (Transformer使用八個注意力頭)。

現(xiàn)在對于每一個詞語,我們有了八個向量 ! ,它們分別由八個head產(chǎn)生。但是對于下一個feed-forward層,我們應(yīng)該把每個詞語都用一個向量來表示。所以下一步,我們需要把這八個向量壓縮成一個向量。
可以直接把這些矩陣拼接在一起,然后用一個附加的權(quán)重矩陣 與它們相乘:

這幾乎就是多頭自注意力的全部。這確實有好多矩陣,我們試著把它們集中在一個圖片中,這樣可以一眼看清。

既然我們已經(jīng)摸到了注意力機(jī)制的這么多“頭”,那么讓我們重溫之前的例子,看看我們在例句中編碼“it”一詞時,不同的注意力“頭”集中在哪里:

當(dāng)我們編碼“it”一詞時,一個注意力頭集中在“animal”上,而另一個則集中在“tired”上,從某種意義上說,模型對“it”一詞的表達(dá)在某種程度上是“animal”和“tired”的代表。
2.2.4 The Residuals and Layer normalization
在繼續(xù)進(jìn)行下去之前,我們需要提到一個encoder中的細(xì)節(jié):在每個encoder中都有一個殘差連接,并且都跟隨著一個Layer Normalization(層-歸一化)步驟。

如果我們?nèi)?strong>「可視化」這些向量以及這個和自注意力相關(guān)聯(lián)的layer-norm操作,那么看起來就像下面這張圖描述一樣:

Layer-Norm也是歸一化數(shù)據(jù)的一種方式,不過 Layer-Norm 是在每一個樣本上計算均值和方差,而不是 Batch-Norm 那種在批方向計算均值和方差!

2.2.5 小結(jié)
這幾乎就是Encoder的全部。Encoder就是用來給input一個比較好的embedding,使用self-attention來使一個詞的embedding包含了上下文的信息,而不是簡單的查look-up table。Transformer使用了多層(6層)的Encoder是為了把握一些高階的信息。
2.3 Decoder層
2.3.1 簡介
從更高的角度來看,Transformer的Decoder作用和普通seq2seq一樣:從
以對話系統(tǒng)為例:
「Our Input:」 “Hi how are you”
「Transformer Output:」 “I am fine”

下面我們來詳細(xì)介紹Decoder的內(nèi)部結(jié)構(gòu)。

2.3.2 Masked Multi-Head Attention
和Encoder一樣,Decoder先經(jīng)過embedding+positional encoding之后得到了一個embedding,輸入到multi-head attention中。
和前面不同的是,Decoder的self-attention層其實是「masked」 multi-head attention。mask表示掩碼,它對某些值進(jìn)行掩蓋。這是為了防止Decoder在計算某個詞的attention權(quán)重時“看到”這個詞后面的詞語。
Since the decoder is auto-regressive and generates the sequence word by word, you need to prevent it from conditioning to future tokens. For example, when computing attention scores on the word "am", you should not have access to the word "fine", because that word is a future word that was generated after. The word "am" should only have access to itself and the words before it. This is true for all other words, where they can only attend to previous words.

「Look-head mask」 是為了使得 decoder 不能看見未來的信息。也就是對于一個序列,在 time_step 為 t 的時刻,我們的「解碼」輸出應(yīng)該只能依賴于 t 時刻之前的輸出,而不能依賴 t 之后的輸出。因此我們需要想一個辦法,把 t 之后的信息給隱藏起來。
那么具體怎么做呢?也很簡單:產(chǎn)生一個上三角矩陣,上三角的值全為 「-inf」 。把這個矩陣加在每一個序列上,就可以達(dá)到我們的目的:

加上-inf的目的是,做softmax之后-inf會變成0:

這個mask是Decoder中self-attention和Encoder中的self-attention唯一有區(qū)別的地方。
2.3.3 第二個Multi-head Attention -- 普通attention
For this layer, the encoder's outputs are keys and values, and the first multi-headed attention layer outputs are the queries. This process matches the encoder's input to the decoder's input, allowing the decoder to decide which encoder input is relevant to put a focus on.

3. Q/A
(1) Transformer為什么需要進(jìn)行Multi-head Attention?
原論文中說進(jìn)行Multi-head Attention的原因是將模型分為多個頭,形成多個子空間,可以讓模型去關(guān)注不同方面的信息,最后再將各個方面的信息綜合起來。其實直觀上也可以想到,如果自己設(shè)計這樣的一個模型,必然也不會只做一次attention,多次attention綜合的結(jié)果至少能夠起到增強模型的作用,也可以「類比CNN中同時使用多個卷積核的作用」,直觀上講,多頭的注意力有助于網(wǎng)絡(luò)捕捉到更豐富的特征/信息。
(2) Transformer相比于RNN/LSTM,有什么優(yōu)勢?
RNN系列的模型,「并行計算」能力很差,因為 T 時刻的計算依賴 T-1 時刻的隱層計算結(jié)果。 Transformer的特征抽取能力也比RNN系列的模型要好,使用了self-attention和多頭機(jī)制來讓源序列和目標(biāo)序列自身的embedding表示所蘊含的信息更加豐富。
(3)Transformer如何并行化的?
Transformer的并行化我認(rèn)為主要體現(xiàn)在self-attention模塊。對于某個序列 ,self-attention模塊可以直接計算 的點乘結(jié)果,而RNN系列的模型就必須按照順序從 計算到 .

本文參考資料
Attention is All you need: https://arxiv.org/abs/1706.03762
[2]Illustrated Guide to Transformers- Step by Step Explanation: https://towardsdatascience.com/illustrated-guide-to-transformers-step-by-step-explanation-f74876522bc0
[3]Self-Attention 與 Transformer: https://www.6aiq.com/article/1584719677724
-?END?-
往期精彩回顧 本站qq群554839127,加入微信群請掃碼:
