03.05 關於Transformer,面試官們都怎麼問

寫在前面

前些時間,趕完論文,開始對 Transformer、GPT、Bert 系列論文來進行仔仔細細的研讀,然後順手把站內的相關問題整理了一下,但是發現站內鮮有回答仔細的~所以自己就在網上針對每個問題收集了一些資料,並做了整理,有些問題還寫了一些自己的看法,可能會有紕漏,甚至還有錯誤,還請大家賜教

模型總覽:


1.Transformer 的結構是什麼樣的?

Transformer 本身還是一個典型的 encoder-decoder 模型,如果從模型層面來看,Transformer 實際上就像一個 seq2seq with attention 的模型,下面大概說明一下 Transformer 的結構以及各個模塊的組成。

1.1 Encoder 端 & Decoder 端總覽


  • Encoder 端由 N(原論文中「N=6」)個相同的大模塊堆疊而成,其中每個大模塊又由「兩個子模塊」構成,這兩個子模塊分別為多頭 self-attention 模塊,以及一個前饋神經網絡模塊;
    • 「需要注意的是,Encoder 端每個大模塊接收的輸入是不一樣的,第一個大模塊(最底下的那個)接收的輸入是輸入序列的 embedding(embedding 可以通過 word2vec 預訓練得來),其餘大模塊接收的是其前一個大模塊的輸出,最後一個模塊的輸出作為整個 Encoder 端的輸出。」

  • Decoder 端同樣由 N(原論文中「N=6」)個相同的大模塊堆疊而成,其中每個大模塊則由「三個子模塊」構成,這三個子模塊分別為多頭 self-attention 模塊,「多頭 Encoder-Decoder attention 交互模塊」,以及一個前饋神經網絡模塊;
    • 同樣需要注意的是,Decoder端每個大模塊接收的輸入也是不一樣的,其中第一個大模塊(最底下的那個)訓練時和測試時的接收的輸入是不一樣的,並且每次訓練時接收的輸入也可能是不一樣的(也就是模型總覽圖示中的"shifted right",後續會解釋),其餘大模塊接收的是同樣是其前一個大模塊的輸出,最後一個模塊的輸出作為整個Decoder端的輸出
    • 對於第一個大模塊,簡而言之,其訓練及測試時接收的輸入為:
      • 訓練的時候每次的輸入為上次的輸入加上輸入序列向後移一位的 ground truth(例如每向後移一位就是一個新的單詞,那麼則加上其對應的 embedding),特別地,當 decoder 的 time step 為 1 時(也就是第一次接收輸入),其輸入為一個特殊的 token,可能是目標序列開始的 token(如),也可能是源序列結尾的 token(如),也可能是其它視任務而定的輸入等等,不同源碼中可能有微小的差異,其目標則是預測下一個位置的單詞(token)是什麼,對應到 time step 為 1 時,則是預測目標序列的第一個單詞(token)是什麼,以此類推;
        • 這裡需要注意的是,在實際實現中可能不會這樣每次動態的輸入,而是一次性把目標序列的embedding通通輸入第一個大模塊中,然後在多頭attention模塊對序列進行mask即可
      • 而在測試的時候,是先生成第一個位置的輸出,然後有了這個之後,第二次預測時,再將其加入輸入序列,以此類推直至預測結束。

1.2 Encoder 端各個子模塊

「1.2.1 多頭 self-attention 模塊」

在介紹 self-attention 模塊之前,先介紹 self-attention 模塊, attention 可以被描述為「將 query 和 key-value 鍵值對的一組集合映射到輸出」,其中 query,keys,values 和輸出都是向量,其中 query 和 keys 的維度均為,values 的維度為(論文中),輸出被計算為 values 的加權和,其中分配給每個 value 的權重由 query 與對應 key 的相似性函數計算得來。這種 attention 的形式被稱為“Scaled Dot-Product Attention”,對應到公式的形式為:

而多頭 self-attention 模塊,則是將通過參數矩陣映射後(給分別接一個全連接層),然後再做 self-attention,將這個過程重複(原論文中)次,最後再將所有的結果拼接起來,再送入一個全連接層即可.

其中

「1.2.2 前饋神經網絡模塊」

前饋神經網絡模塊(即圖示中的 Feed Forward)由兩個線性變換組成,中間有一個 ReLU 激活函數,對應到公式的形式為:

論文中前饋神經網絡模塊輸入和輸出的維度均為,其內層的維度.

1.3 Decoder 端各個子模塊

「1.3.1 多頭 self-attention 模塊」

Decoder 端多頭 self-attention 模塊與 Encoder 端的一致,但是「需要注意的是 Decoder 端的多頭 self-attention 需要做 mask,因為它在預測時,是“看不到未來的序列的”,所以要將當前預測的單詞(token)及其之後的單詞(token)全部 mask 掉。」

「1.3.2 多頭 Encoder-Decoder attention 交互模塊」

多頭 Encoder-Decoder attention 交互模塊的形式與多頭 self-attention 模塊一致,唯一不同的是其矩陣的來源,其矩陣來源於下面子模塊的輸出(對應到圖中即為 masked 多頭 self-attention 模塊經過 Add & Norm 後的輸出),而矩陣則來源於整個 Encoder 端的輸出,仔細想想其實可以發現,這裡的交互模塊就跟 seq2seq with attention 中的機制一樣,目的就在於讓 Decoder 端的單詞(token)給予 Encoder 端對應的單詞(token)“更多的關注(attention weight)”

「1.3.3 前饋神經網絡模塊」

該部分與 Encoder 端的一致

1.4 其他模塊

「1.4.1 Add & Norm 模塊」

Add & Norm 模塊接在 Encoder 端和 Decoder 端每個子模塊的後面,其中 Add 表示殘差連接,Norm 表示 LayerNorm,殘差連接來源於論文Deep Residual Learning for Image Recognition[1],LayerNorm 來源於論文Layer Normalization[2],因此 Encoder 端和 Decoder 端每個子模塊實際的輸出為:LayerNorm ,其中Sublayer 為子模塊的輸出。

「1.4.2 Positional Encoding」

Positional Encoding 添加到 Encoder 端和 Decoder 端最底部的輸入 embedding。Positional Encoding 具有與 embedding 相同的維度

,因此可以對兩者進行求和。


具體做法是使用不同頻率的正弦和餘弦函數,公式如下:

其中為位置,為維度,之所以選擇這個函數,是因為任意位置可以表示為的線性函數,這個主要是三角函數的特性:

需要注意的是,Transformer 中的 Positional Encoding 不是通過網絡學習得來的,而是直接通過上述公式計算而來的,論文中也實驗了利用網絡學習 Positional Encoding,發現結果與上述基本一致,但是論文中選擇了正弦和餘弦函數版本,「因為三角公式不受序列長度的限制,也就是可以對 比所遇到序列的更長的序列 進行表示。」

2.Transformer Decoder 端的輸入具體是什麼?

見上述 Encoder 端 & Decoder 端總覽中,對 Decoder 端的輸入有詳細的分析

3.Transformer 中一直強調的 self-attention 是什麼?self-attention 的計算過程?為什麼它能發揮如此大的作用?self-attention 為什麼要使用 Q、K、V,僅僅使用 Q、V/K、V 或者 V 為什麼不行?

3.1 self-attention是什麼?

「self-attention」,也叫 「intra-attention」,是一種通過自身和自身相關聯的 attention 機制,從而得到一個更好的 representation 來表達自身,self-attention 可以看成一般 attention 的一種特殊情況。在 self-attention 中,,序列中的每個單詞(token)和該序列中其餘單詞(token)進行 attention 計算。self-attention 的特點在於「無視詞(token)之間的距離直接計算依賴關係,從而能夠學習到序列的內部結構」,實現起來也比較簡單,值得注意的是,在後續一些論文中,self-attention 可以當成一個層和 RNN,CNN 等配合使用,並且成功應用到其他 NLP 任務。

3.2 關於 self-attention 的計算過程?

問題 1 中有詳細的解答

3.3 關於 self-attention 為什麼它能發揮如此大的作用

在上述 self-attention 的介紹中實際上也有所提及,self-attention 是一種自身和自身相關聯的 attention 機制,這樣能夠得到一個更好的 representation 來表達自身,在多數情況下,自然會對下游任務有一定的促進作用,但是 Transformer 效果顯著及其強大的特徵抽取能力是否完全歸功於其 self-attention 模塊,還是存在一定爭議的,參見論文:How Much Attention Do You Need?A Granular Analysis of Neural Machine Translation Architectures

[3],如下例子可以大概探知 self-attention 的效果:

關於Transformer,面試官們都怎麼問圖 1 可視化 self-attention 實例
關於Transformer,面試官們都怎麼問圖 2 可視化 self-attention 實例

從兩張圖(圖 1、圖 2)可以看出,self-attention 可以捕獲同一個句子中單詞之間的一些句法特徵(比如圖 1 展示的有一定距離的短語結構)或者語義特徵(比如圖 1 展示的 its 的指代對象 Law)。

很明顯,引入 Self Attention 後會更容易捕獲句子中長距離的相互依賴的特徵,因為如果是 RNN 或者 LSTM,需要依次序序列計算,對於遠距離的相互依賴的特徵,要經過若干時間步步驟的信息累積才能將兩者聯繫起來,而距離越遠,有效捕獲的可能性越小。

但是 Self Attention 在計算過程中會直接將句子中任意兩個單詞的聯繫通過一個計算步驟直接聯繫起來,所以遠距離依賴特徵之間的距離被極大縮短,有利於有效地利用這些特徵。除此外,Self Attention 對於增加計算的並行性也有直接幫助作用。這是為何 Self Attention 逐漸被廣泛使用的主要原因。

3.4 關於 self-attention 為什麼要使用 Q、K、V,僅僅使用 Q、V/K、V 或者 V 為什麼不行?

這個問題我覺得並不重要,self-attention 使用 Q、K、V,這樣三個參數獨立,模型的表達能力和靈活性顯然會比只用 Q、V 或者只用 V 要好些,當然主流 attention 的做法還有很多種,比如說 seq2seq with attention 也就只有 hidden state 來做相似性的計算,處理不同的任務,attention 的做法有細微的不同,但是主體思想還是一致的,不知道有沒有論文對這個問題有過細究,有空去查查~

「其實還有個小細節,因為 self-attention 的範圍是包括自身的(masked self-attention 也是一樣),因此至少是要採用 Q、V 或者 K、V 的形式,而這樣“詢問式”的 attention 方式,個人感覺 Q、K、V 顯然合理一些。」

4.Transformer 為什麼需要進行 Multi-head Attention?這樣做有什麼好處?Multi-head Attention 的計算過程?各方論文的觀點是什麼?

4.1 Why Multi-head Attention

原論文中說到進行 Multi-head Attention 的原因是將模型分為多個頭,形成多個子空間,可以讓模型去關注不同方面的信息,最後再將各個方面的信息綜合起來。其實直觀上也可以想到,如果自己設計這樣的一個模型,必然也不會只做一次 attention,多次 attention 綜合的結果至少能夠起到增強模型的作用,也可以類比 CNN 中同時使用「多個卷積核」的作用,直觀上講,多頭的注意力「有助於網絡捕捉到更豐富的特徵/信息」。

4.2 關於 Multi-head Attention 的計算過程

在 1 中也有詳細的介紹,但是需要注意的是,論文中並沒有對 Multi-head Attention 有很強的理論說明,因此後續有不少論文對 Multi-head Attention 機制都有一定的討論,一些相關工作的論文如下(還沒看,先攢著)

4.3 Multi-head Attention 機制相關的論文:

A Structured Self-attentive Sentence Embedding[4]

Analyzing Multi-Head Self-Attention: Specialized Heads Do the Heavy Lifting, the Rest Can Be Pruned[5]

Are Sixteen Heads Really Better than One?[6]

What Does BERT Look At? An Analysis of BERT's Attention[7]

A Multiscale Visualization of Attention in the Transformer Model[8]

Improving Deep Transformer with Depth-Scaled Initialization and Merged Attention[9]

5.Transformer 相比於 RNN/LSTM,有什麼優勢?為什麼?

5.1 RNN 系列的模型,並行計算能力很差

RNN 系列的模型時刻隱層狀態的計算,依賴兩個輸入,一個是時刻的句子輸入單詞,另一個是時刻的隱層狀態的輸出,這是最能體現 RNN 本質特徵的一點,RNN 的歷史信息是通過這個信息傳輸渠道往後傳輸的。而 RNN 並行計算的問題就出在這裡,因為時刻的計算依賴時刻的隱層計算結果,而時刻的計算依賴時刻的隱層計算結果,如此下去就形成了所謂的序列依賴關係。

5.2 Transformer 的特徵抽取能力比 RNN 系列的模型要好

上述結論是通過一些主流的實驗來說明的,並不是嚴格的理論證明,具體實驗對比可以參見:

放棄幻想,全面擁抱 Transformer:自然語言處理三大特徵抽取器(CNN/RNN/TF)比較[10]

但是值得注意的是,並不是說 Transformer 就能夠完全替代 RNN 系列的模型了,任何模型都有其適用範圍,同樣的,RNN 系列模型在很多任務上還是首選,熟悉各種模型的內部原理,知其然且知其所以然,才能遇到新任務時,快速分析這時候該用什麼樣的模型,該怎麼做好。

6.Transformer 是如何訓練的?測試階段如何進行測試呢?

6.1 訓練

Transformer 訓練過程與 seq2seq 類似,首先 Encoder 端得到輸入的 encoding 表示,並將其輸入到 Decoder 端做交互式 attention,之後在 Decoder 端接收其相應的輸入(見 1 中有詳細分析),經過多頭 self-attention 模塊之後,結合 Encoder 端的輸出,再經過 FFN,得到 Decoder 端的輸出之後,最後經過一個線性全連接層,就可以通過 softmax 來預測下一個單詞(token),然後根據 softmax 多分類的損失函數,將 loss 反向傳播即可,所以從整體上來說,Transformer 訓練過程就相當於一個有監督的多分類問題。

  • 需要注意的是,「Encoder 端可以並行計算,一次性將輸入序列全部 encoding 出來,但 Decoder 端不是一次性把所有單詞(token)預測出來的,而是像 seq2seq 一樣一個接著一個預測出來的。」

6.2 測試

而對於測試階段,其與訓練階段唯一不同的是 Decoder 端最底層的輸入,詳細分析見問題 1。

7.Transformer 中的 Add & Norm 模塊,具體是怎麼做的?

見 1 其他模塊的敘述,對 Add & Norm 模塊有詳細的分析

8.為什麼說 Transformer 可以代替 seq2seq?

這裡用代替這個詞略顯不妥當,seq2seq 雖已老,但始終還是有其用武之地,seq2seq 最大的問題在於「將 Encoder 端的所有信息壓縮到一個固定長度的向量中」,並將其作為 Decoder 端首個隱藏狀態的輸入,來預測 Decoder 端第一個單詞(token)的隱藏狀態。在輸入序列比較長的時候,這樣做顯然會損失 Encoder 端的很多信息,而且這樣一股腦的把該固定向量送入 Decoder 端,Decoder 端不能夠關注到其想要關注的信息。

上述兩點都是 seq2seq 模型的缺點,後續論文對這兩點有所改進,如著名的Neural Machine Translation by Jointly Learning to Align and Translate[11]

,雖然確確實實對 seq2seq 模型有了實質性的改進,但是由於主體模型仍然為 RNN(LSTM)系列的模型,因此模型的並行能力還是受限,而 transformer 不但對 seq2seq 模型這兩點缺點有了實質性的改進(多頭交互式 attention 模塊),而且還引入了 self-attention 模塊,讓源序列和目標序列首先“自關聯”起來,這樣的話,源序列和目標序列自身的 embedding 表示所蘊含的信息更加豐富,而且後續的 FFN 層也增強了模型的表達能力(ACL 2018 會議上有論文對 Self-Attention 和 FFN 等模塊都有實驗分析,見論文:How Much Attention Do You Need?A Granular Analysis of Neural Machine Translation Architectures[12]),並且 Transformer 並行計算的能力是遠遠超過 seq2seq 系列的模型,因此我認為這是 transformer 優於 seq2seq 模型的地方。

9.Transformer 中句子的 encoder 表示是什麼?如何加入詞序信息的?

Transformer Encoder 端得到的是整個輸入序列的 encoding 表示,其中最重要的是經過了 self-attention 模塊,讓輸入序列的表達更加豐富,而加入詞序信息是使用不同頻率的正弦和餘弦函數,具體見 1 中敘述。

10.Transformer 如何並行化的?

Transformer 的並行化我認為主要體現在 self-attention 模塊,在 Encoder 端 Transformer 可以並行處理整個序列,並得到整個輸入序列經過 Encoder 端的輸出,在 self-attention 模塊,對於某個序列,self-attention 模塊可以直接計算的點乘結果,而 RNN 系列的模型就必須按照順序從計算到。

11.self-attention 公式中的歸一化有什麼作用?

首先說明做歸一化的原因,隨著的增大,點積後的結果也隨之增大,這樣會將 softmax 函數推入梯度非常小的區域,使得收斂困難(可能出現梯度消失的情況)

為了說明點積變大的原因,假設和的分量是具有均值 0 和方差 1 的獨立隨機變量,那麼它們的點積均值為 0,方差為,因此為了抵消這種影響,我們將點積縮放,對於更詳細的分析,參見(有空再來總結,哈哈~):transformer 中的 attention 為什麼 scaled?[13]

寫在後面

17 年提出的 Transformer 模型,在當時確實引起了很大的轟動,但是到現在事後看來,Transformer 模型也確實能力很強,但是我覺得並不像論文題目說的那樣《attention is all you need》,反而我覺得論文最大的貢獻在於它第一次做到了在自然語言處理任務中把網絡的深度堆疊上去還能取得很好的效果,而機器翻譯恰好也是一個目前數據量非常豐富且問題本身難度不大的一個任務了,這樣充分發揮了 Transformer 的優勢。另外,self-attention 其實並不是 Transformer 的全部,實際上從深度 CNN 網絡中借鑑而來的 FFN 可能更加重要。所以,理智看待 Transformer,面對不同的任務,選擇最合適自己任務的模型就好了~

[14][15][16][17][18][19][20][21][22][23][24]


關於Transformer,面試官們都怎麼問



分享到:


相關文章: