Transformer 是 Google 團(tuán)隊(duì)在 17 年 6 月提出的 NLP 經(jīng)典之作,
由 Ashish Vaswani 等人在 2017 年發(fā)表的論文 Attention Is All You Need 中提出。
Transformer 在機(jī)器翻譯任務(wù)上的表現(xiàn)超過(guò)了 RNN,CNN,只用 encoder-decoder 和 attention 機(jī)制就能達(dá)到很好的效果,最大的優(yōu)點(diǎn)是可以高效地并行化。

Transformer 是一種基于 encoder-decoder 結(jié)構(gòu)的模型,

在 Encoder 中,
- Input 經(jīng)過(guò) embedding 后,要做 positional encodings,
- 然后是 Multi-head attention,
- 再經(jīng)過(guò) position-wise Feed Forward,
- 每個(gè)子層之間有殘差連接。
在 Decoder 中,
- 如上圖所示,也有 positional encodings,Multi-head attention 和 FFN,子層之間也要做殘差連接,
- 但比 encoder 多了一個(gè) Masked Multi-head attention,
- 最后要經(jīng)過(guò) Linear 和 softmax 輸出概率。
下面我們具體看一下其中這幾個(gè)概念,這里主要參考 Jay Alammar,他在 The Illustrated Transformer 中給出了很形象的講解。
1. 整體結(jié)構(gòu)
例如我們要進(jìn)行機(jī)器翻譯任務(wù),輸入一種語(yǔ)言,經(jīng)過(guò) Transformer,會(huì)輸出另一種語(yǔ)言。
Transformer 的 encoder 由 6 個(gè)編碼器疊加組成,
decoder 也由 6 個(gè)解碼器組成,
在結(jié)構(gòu)上都是相同的,但它們不共享權(quán)重。
每一個(gè) encoder 都分為兩個(gè)子層:
- 先流經(jīng) self-attention 層,這一層可以幫助編碼器在編碼某個(gè)特定單詞時(shí),也會(huì)查看其他單詞
- self-attention 層的輸出再傳遞給一個(gè)前饋神經(jīng)網(wǎng)絡(luò)層,在每個(gè)位置的前饋網(wǎng)絡(luò)都是完全相同的,
每一個(gè) decoder 也具有這兩個(gè)層,但還有一個(gè)注意力層,用來(lái)幫助解碼器關(guān)注輸入句子的相關(guān)部分

2. Encoder
- Input 經(jīng)過(guò) embedding 后,要做 positional encodings,
- 然后是 Multi-head attention,
- 再經(jīng)過(guò) position-wise Feed Forward,
- 每個(gè)子層之間有殘差連接。
首先使用嵌入算法將輸入的 word 轉(zhuǎn)換為 vector,
最下面的 encoder ,它的輸入就是 embedding 向量,
在每個(gè) encoder 內(nèi)部,
輸入向量經(jīng)過(guò) self-attention,再經(jīng)過(guò) feed-forward 層,
每個(gè) encoder 的輸出向量是它正上方 encoder 的輸入,
向量的大小是一個(gè)超參數(shù),通常設(shè)置為訓(xùn)練集中最長(zhǎng)句子的長(zhǎng)度。

在這里,我們開(kāi)始看到 Transformer 的一個(gè)關(guān)鍵性質(zhì),
即每個(gè)位置的單詞在 encoder 中都有自己的路徑,
self-attention 層中的這些路徑之間存在依賴關(guān)系,
然而在 feed-forward 層不具有那些依賴關(guān)系,
這樣各種路徑在流過(guò) feed-forward 層時(shí)可以并行執(zhí)行。
2.1 positional encodings
Positional Encoding 是一種考慮輸入序列中單詞順序的方法。
encoder 為每個(gè)輸入 embedding 添加了一個(gè)向量,這些向量符合一種特定模式,可以確定每個(gè)單詞的位置,或者序列中不同單詞之間的距離。
例如,input embedding 的維度為4,那么實(shí)際的positional encodings如下所示:

在下圖中,是20個(gè)單詞的 positional encoding,每行代表一個(gè)單詞的位置編碼,即第一行是加在輸入序列中第一個(gè)詞嵌入的,每行包含 512 個(gè)值, 每個(gè)值介于 -1 和 1 之間,用顏色表示出來(lái)。

可以看到在中心位置分成了兩半,因?yàn)樽蟀氩糠值闹涤梢粋€(gè)正弦函數(shù)生成,右半部分由余弦函數(shù)生成,然后將它們連接起來(lái)形成了每個(gè)位置的編碼向量。
當(dāng)然這并不是位置編碼的唯一方法,只是這個(gè)方法能夠擴(kuò)展到看不見(jiàn)的序列長(zhǎng)度處,例如當(dāng)我們要翻譯一個(gè)句子,這個(gè)句子的長(zhǎng)度比我們訓(xùn)練集中的任何一個(gè)句子都長(zhǎng)時(shí)。
2.2 Multi-head attention
2.2.1 先看什么是 Self-Attention
例如我們要翻譯:”The animal didn't cross the street because it was too tired” 這句話
這句話中的“it”是指什么?它指的是 street 還是 animal?
這對(duì)人類來(lái)說(shuō)是一個(gè)簡(jiǎn)單的問(wèn)題,但對(duì)算法來(lái)說(shuō)并不簡(jiǎn)單。
而 Self-Attention 讓算法知道這里的 it 指的是 animal
2.2.2 self-attention 的作用
當(dāng)模型在處理每個(gè)單詞時(shí),self-attention 可以幫助模型查看 input 序列中的其他位置,尋找相關(guān)的線索,來(lái)達(dá)到更好的編碼效果。它的作用就是將對(duì)其他相關(guān)單詞的“understanding”融入我們當(dāng)前正在處理的單詞中。

例如上圖中,在第5層時(shí),我們就知道 it 大概指的是 animal 了。
2.2.3 self-attention 具體原理
第一步,為編碼器的每個(gè)輸入單詞創(chuàng)建三個(gè)向量,
即 Query vector, Key vector, Value vector
這些向量通過(guò) embedding 和三個(gè)矩陣相乘得到,
請(qǐng)注意,這些新向量的尺寸小于嵌入向量。它們的維數(shù)為64,而嵌入和編碼器輸入/輸出向量的維數(shù)為512.它們不一定要小,這是一種架構(gòu)選擇,可以使多頭注意力計(jì)算(大多數(shù))不變。
將x1乘以WQ得到Query向量 q1,同理得到Key 向量 和, Value 向量
這三個(gè)向量對(duì) attention 的計(jì)算有很重要的作用

第二步,是計(jì)算一個(gè)得分
假設(shè)我們要計(jì)算一個(gè)例子中第一個(gè)單詞 “Thinking” 的 self-attention,就需要根據(jù)這個(gè)單詞,對(duì)輸入句子的每個(gè)單詞進(jìn)行評(píng)分,這個(gè)分?jǐn)?shù)決定了對(duì)其他單詞放置多少關(guān)注度。
分?jǐn)?shù)的計(jì)算方法是,
例如我們正在考慮 Thinking 這個(gè)詞,就用它的 q1 去乘以每個(gè)位置的 ki
第三步和第四步,是將得分加以處理再傳遞給 softmax
將得分除以 8(因?yàn)檎撐闹惺褂玫?key 向量的維數(shù)是 64,8 是它的平方根)
這樣可以有更穩(wěn)定的梯度,
然后傳遞給 softmax,Softmax 就將分?jǐn)?shù)標(biāo)準(zhǔn)化,這樣加起來(lái)保證為 1。
這個(gè) softmax 分?jǐn)?shù)決定了每個(gè)單詞在該位置bbei表達(dá)的程度。
很明顯,這個(gè)位置上的單詞將具有最高的softmax分?jǐn)?shù),但有時(shí)候注意與當(dāng)前單詞相關(guān)的另一個(gè)單詞是有用的。
第五步,用這個(gè)得分乘以每個(gè) value 向量
目的讓我們想要關(guān)注單詞的值保持不變,并通過(guò)乘以 0.001 這樣小的數(shù)字,來(lái)淹沒(méi)不相關(guān)的單詞
第六步,加權(quán)求和這些 value 向量

這就是第一個(gè)單詞的 self-attention 的輸出
得到的向量接下來(lái)要輸入到前饋神經(jīng)網(wǎng)絡(luò),在實(shí)際實(shí)現(xiàn)中用矩陣乘法的形式完成
2.2.4 multi-headed 機(jī)制
論文中還增加一種稱為 multi-headed 注意力機(jī)制,可以提升注意力層的性能
它使得模型可以關(guān)注不同位置
雖然在上面的例子中,z1 包含了一點(diǎn)其他位置的編碼,但當(dāng)前位置的單詞還是占主要作用, 當(dāng)我們想知道“The animal didn’t cross the street because it was too tired” 中 it 的含義時(shí),這時(shí)就需要關(guān)注到其他位置
這個(gè)機(jī)制為注意層提供了多個(gè)“表示子空間”。下面我們將具體介紹,
1. 經(jīng)過(guò) multi-headed , 我們會(huì)得到和 heads 數(shù)目一樣多的 Query / Key / Value 權(quán)重矩陣組
論文中用了8個(gè),那么每個(gè)encoder/decoder我們都會(huì)得到 8 個(gè)集合。
這些集合都是隨機(jī)初始化的,經(jīng)過(guò)訓(xùn)練之后,每個(gè)集合會(huì)將input embeddings 投影到不同的表示子空間中。
2. 簡(jiǎn)單來(lái)說(shuō),就是定義 8 組權(quán)重矩陣,每個(gè)單詞會(huì)做 8 次上面的 self-attention 的計(jì)算
這樣每個(gè)單詞會(huì)得到 8 個(gè)不同的加權(quán)求和 z

3. 但在 feed-forward 處只能接收一個(gè)矩陣,所以需要將這八個(gè)壓縮成一個(gè)矩陣
方法就是先將8個(gè)z矩陣連接起來(lái),然后乘一個(gè)額外的權(quán)重矩陣WO

下圖顯示了在例句中,it 的不同的注意力 heads 所關(guān)注的位置,一個(gè)注意力的焦點(diǎn)主要集中在“animal”上,而另一個(gè)注意力集中在“tired”,換句話說(shuō),it 是 “animal”和“tired”的一種表現(xiàn)形式。
當(dāng)然如果選了8個(gè)層,將所有注意力 heads 都添加到圖片中,就有點(diǎn)難以解釋了。

2.3 Residuals
這里有一個(gè)細(xì)節(jié),
即在每個(gè) encoders 和 decoders 里面的 self-attention, ffnn,encoders-decoders attention 層,都有 residual 連接,還有一步 layer-normalization

3. Decoder
下面我們看一下 Decoder 部分
- 如上圖所示,也有 positional encodings,Multi-head attention 和 FFN,子層之間也要做殘差連接,
- 但比 encoder 多了一個(gè) Masked Multi-head attention,
- 最后要經(jīng)過(guò) Linear 和 softmax 輸出概率。
1. 輸入序列經(jīng)過(guò)編碼器部分,然后將最上面的 encoder 的輸出變換成一組 attention 向量 K和V
這些向量會(huì)用于每個(gè) decoder 的 encoder-decoder attention 層,有助于解碼器聚焦在輸入序列中的合適位置

重復(fù)上面的過(guò)程,直到 decoder 完成了輸出,每個(gè)時(shí)間步的輸出都在下一個(gè)時(shí)間步時(shí)喂入給最底部的 decoder,同樣,在這些 decoder 的輸入中也加入了位置編碼,來(lái)表示每個(gè)字的位置。
2. 解碼器中的 self attention 層與編碼器中的略有不同
在解碼器中,在 self attention 的 softmax 步驟之前,將未來(lái)的位置設(shè)置為 -inf 來(lái)屏蔽這些位置,這樣做是為了 self attention 層只能關(guān)注輸出序列中靠前的一些位置。
Encoder-Decoder Attention 層的工作方式與 multiheaded self-attention 類似,只是它用下面的層創(chuàng)建其 Queries 矩陣,從編碼器棧的輸出中獲取 Keys 和 Values 矩陣。
3. 解碼器最后輸出的是一個(gè)向量,如何把它變成一個(gè)單詞,這就要靠它后面的線性層和 softmax 層
線性層就是一個(gè)很簡(jiǎn)單的全連接神經(jīng)網(wǎng)絡(luò),將解碼器輸出的向量映射成一個(gè)更長(zhǎng)的向量。
例如我們有 10,000 個(gè)無(wú)重復(fù)的單詞,那么最后輸出的向量就有一萬(wàn)維。
每個(gè)位置上的值代表了相應(yīng)單詞的分?jǐn)?shù)。

softmax 層將這個(gè)分?jǐn)?shù)轉(zhuǎn)換為了概率。
我們選擇概率最大的所對(duì)應(yīng)的單詞,就是當(dāng)前時(shí)間步的輸出。
學(xué)習(xí)資源:
https://arxiv.org/pdf/1706.03762.pdf
https://jalammar.github.io/illustrated-transformer/
https://ai.googleblog.com/2017/08/transformer-novel-neural-network.html