今天閱讀的來自谷歌大腦的同學(xué)于 2017 年發(fā)表的論文《Attention Is All You Need》,目前論文被引次數(shù)高達(dá) 6100 次。
Attention 機(jī)制是 Bengio 等同學(xué)在 2014 年提出的,并廣泛應(yīng)用于深度學(xué)習(xí)各個(gè)領(lǐng)域,如計(jì)算機(jī)視覺、NLP 等。其中,Seq2Seq 模型采用了 RNN 和 Attention 的結(jié)合成功應(yīng)用于機(jī)器翻譯領(lǐng)域,在諸多任務(wù)中都有顯著的提升。
在這篇文論文中,作者提出了 Transformer 網(wǎng)絡(luò)架構(gòu),其摒棄了傳統(tǒng)的 RNN、LSTM 架構(gòu),完全基于 Attention 機(jī)制,并在機(jī)器翻譯領(lǐng)域獲得明顯的質(zhì)量提升。
傳統(tǒng)的基于 RNN 的 Seq2Seq 模型由于難以處理長(zhǎng)序列的的句子,且因順序性也無法并行處理。而完全基于 CNN 的 Seq2Seq 模型雖然可以實(shí)現(xiàn)并行化,但是非常耗內(nèi)存。
Self-attention,也稱為 intra-attention,是一種將序列的不同位置聯(lián)系起來并計(jì)算序列表示的注意力機(jī)制。Self-attention 已成功應(yīng)用于各個(gè)任務(wù)中,包括閱讀理解、摘要生成、句子表示等任務(wù)中。
而本文介紹的 Transformer 是一個(gè)完全使用 Self-attention 的模型,即解決了計(jì)算量和并行效率的問題,又提高了實(shí)驗(yàn)的結(jié)果。
由于論文的細(xì)節(jié)部分太少而我又缺少很多必備知識(shí),而在查閱資料時(shí)發(fā)現(xiàn)了 Jay Alammar 大佬的博客,大佬采用了非常精彩的視頻和圖片介紹了 Transformer 模型和 Seq2Seq 模型,大大降低了我的學(xué)習(xí)成本。為了方便和我有類似背景(缺少相關(guān)知識(shí))的同學(xué)看這篇文章時(shí)不至于太痛苦,所以本片主要以 Jay Alammar 大佬的博文翻譯為主。
本節(jié)內(nèi)容來源于 Jay Alammar 的博客,非常感激大佬通過如此精彩的視覺方式將模型極其直觀的表達(dá)出來。
Sequence-to-sequence 模型(以下簡(jiǎn)稱 Seq2Seq)是一種深度學(xué)習(xí)模型,其論文《Sequence to Sequence Learning with Neural Networks》由谷歌的同學(xué)于 2014 年發(fā)表于 NIPS 會(huì)議,目前已有超過 9400 次的引用。Seq2Seq 的應(yīng)用廣泛,常應(yīng)用于機(jī)器翻譯,語音識(shí)別,自動(dòng)問答等領(lǐng)域。谷歌翻譯也在 2016 開始使用這個(gè)模型。接下來介紹的 Seq2Seq 是沒加 Attention 的傳統(tǒng) Seq2Seq,而我們現(xiàn)在經(jīng)常說的 Seq2Seq 是加了 Attention 的模型。
Seq2Seq 可以理解為輸入一個(gè)序列,然后經(jīng)過一個(gè)黑盒后可以得到另一個(gè)序列:
如果將 Seq2Seq 應(yīng)用于機(jī)器翻譯領(lǐng)域的話,就是輸入一種語言,然后得到另一個(gè)語言:
而這個(gè)黑盒中,其實(shí)就是 Encoder-Decoder 框架。大概可以可以理解為輸入一個(gè)序列 ,然后編碼器進(jìn)行編碼得到一個(gè)上下文信息 C,然后通過解碼器進(jìn)行逐一解碼,最后得到另一個(gè)序列 。
這邊我們需要注意幾點(diǎn):
這里的編碼器和解碼器根據(jù)不同的模型和應(yīng)用都是可以自由變換和組合的,常見的有 CNN/RNN/LSTM/GRU 等。而 Seq2Seq 使用的是 RNN 模型。
我們知道 RNN 模型需要兩個(gè)輸入,并且有兩個(gè)輸出:
所以在編碼器之間進(jìn)行傳遞的其實(shí)隱藏層的狀態(tài)。大概的工作過程為:
注意,編碼器中最后一個(gè) RNN 的隱藏狀態(tài)就是要傳給解碼器的上下文信息 Context。
對(duì)于使用 Encoder-Decoder 框架的模型來說,上下文信息 C 的質(zhì)量決定著是模型性能。而 Seq2Seq 采用的 RNN 有一個(gè)致命的缺陷:由于反向傳播會(huì)隨著網(wǎng)絡(luò)層數(shù)的加深而出現(xiàn)梯度爆炸或者梯度消失,所以無法處理長(zhǎng)序列問題。
為了解決這個(gè)問題,IUB 大學(xué)的同學(xué)和斯坦福大學(xué)的同學(xué)分別于 2014 年和 2015 年提出一種解決方案。這兩篇論文分別介紹和完善了一種叫 Attention 的技術(shù),極大地提高了機(jī)器翻譯系統(tǒng)的質(zhì)量。Attention 允許模型根據(jù)需要來關(guān)注輸入序列的某些相關(guān)部分。這種機(jī)制類似于人類的注意力,在看圖片或者閱讀時(shí),我們會(huì)特別關(guān)注某一個(gè)焦點(diǎn)。Attention 應(yīng)用廣泛,如 CV 領(lǐng)域的感受野,NLP 領(lǐng)域的關(guān)鍵 Token 定位等等。
Attention 機(jī)制主要應(yīng)用在 Seq2Seq 的解碼器中。如下圖所示,Attention 使解碼器能夠在生成英語翻譯之前將注意力集中在單詞 “etudiant”(法語中的“student”)上:
Attention 機(jī)制與傳統(tǒng)的 Seq2Seq 主要有兩個(gè)區(qū)別:
我們看一下加入后的效果:
我們來看一下解碼器中加入的 Attention 具體的操作步驟:
強(qiáng)調(diào)一下:這種 Attention 操作在解碼器每次解碼的時(shí)候都需要進(jìn)行。
現(xiàn)在我們來匯總一下所有的過程,看一下 Attention 的工作流程:
配合動(dòng)圖食用效果更佳:
我們也可以換另一種方式來表達(dá)我們的解碼過程:
左邊是隱藏層狀態(tài)的集合,右邊是對(duì)隱藏的一個(gè)加權(quán)結(jié)果。
這里要注意,這里的模型并不是盲目地將輸出中的第一個(gè)單詞與輸入中的第一個(gè)單詞對(duì)齊,事實(shí)上,它從訓(xùn)練的時(shí)候就已經(jīng)學(xué)會(huì)了如何排列語言對(duì)中的單詞。下面再給出 Attention 論文中的一個(gè)例子(模型在輸出 “European Economic Area” 時(shí),其與法語中的順序恰好的是相反的):
加了 Attention 的 Seq2Seq 模型效果得到了顯著提升,并成功應(yīng)用于諸多領(lǐng)域,但仍然存在很多問題。比如說:
Transformer 在 Seq2Seq 的基礎(chǔ)上進(jìn)行了改進(jìn),只使用 Attention 機(jī)制,舍去了 CNN/RNN/LSTM 等結(jié)構(gòu),提高了模型的并行度。
我們先概覽一下 Transformer 模型的架構(gòu),Transformer 同樣基于 Encoder-Decoder 架構(gòu):
編碼部分是堆了六層編碼器,解碼部分也堆了六個(gè)解碼器。
所有的編碼器在結(jié)構(gòu)上都是相同的,每一個(gè)都被分成兩個(gè)子層:
編碼器的輸入首先經(jīng)過一層 Self-Attention,這一層主要用來幫助編碼器在對(duì)特定的單詞進(jìn)行編碼時(shí)查看輸入句子中的其他單詞,后面我們會(huì)仔細(xì)研究 Self-Attention。
Self-Attention 層的輸出進(jìn)入給前饋神經(jīng)網(wǎng)絡(luò)(Feed Forward Neural Network,以下簡(jiǎn)稱 Feed Forward),所有前饋神經(jīng)網(wǎng)絡(luò)的結(jié)構(gòu)都相同并且相互獨(dú)立。
解碼器擁有三層,除了剛剛介紹的 Self-Attention 和 Feed Forward 外,還有一層 Encoder-Decoder Attention 層(以下簡(jiǎn)稱 Attention 層,區(qū)別于 Self-Attention),Attention 層位于 Self-Attention 和 Feed Forward 層之間,主要用來幫助解碼器將注意力集中在輸入語句的相關(guān)部分(類似于 Seq2Seq 模型中的 Attention)。
與一般 NLP 方法一樣,我們需要將每個(gè)輸入字轉(zhuǎn)換成 Embedding 向量,Transformer 采用 512 維的向量。
Embedding 只發(fā)生在最下層的編碼器中,其他編碼器接收下層的輸出作為輸入。
序列中的每個(gè) Embedding 向量都需要經(jīng)過編碼器的 Self-Attention 層和 Feed Forward 層:
這里我們需要注意:在 Self-Attention 層中,這些單詞之間存在依賴關(guān)系;但 Feed Forward 層沒有依賴,所以可以在 Feed Forward 層并行化訓(xùn)練。
谷歌論文中首次提出 Self-Attention 概念,我們來看一下它是怎么工作的。
假設(shè)我們現(xiàn)在要翻譯下面的這個(gè)這句話:
“The animal didn't cross the street because it was too tired”
這個(gè)句子中的 it 指的是什么呢?是指 street 還是 animal 呢?這對(duì)人來說比較簡(jiǎn)單,但是對(duì)算法來說就沒那么簡(jiǎn)單了。
而 Self-Attention 就可以解決這個(gè)問題,在處理 it 時(shí)會(huì)將它和 animal 聯(lián)系起來。
Self-Attention 允許當(dāng)前處理的單詞查看輸入序列中的其他位置,從而尋找到有助于編碼這個(gè)單詞的線索。
以下圖為例,展示了第五層的編碼器,當(dāng)我們?cè)诰幋a it 時(shí),Attention 機(jī)制將 The animal 和自身的 it 編碼到新的 it 上。
我們來看下 Self-Attention 是如何聰明的識(shí)別出來的。
第一步,我們對(duì)于每個(gè)單詞來說我們都一個(gè) Embedding 向量,下圖綠色部分。
此外,對(duì)于每個(gè)單詞我們還會(huì)有三個(gè)向量分別為:查詢向量(Querry)、鍵向量(Key)和值向量(Value),這些向量是單詞的 Embedding 向量分別與對(duì)應(yīng)的查詢矩陣 、鍵矩陣 和值矩陣 相乘得來的。
這邊要注意,對(duì)于 Embedding 向量來說是 512 維,而對(duì)于新向量來說是 64 維。(大小是架構(gòu)設(shè)定的。)
那么 Querry、Key 和 Value 向量到底是什么呢?
這三個(gè)概念是對(duì) Attention 的計(jì)算和思考非常有用的三個(gè)抽象概念,我們接下來會(huì)詳細(xì)敘述這些向量的作用。
第二步,我們來看下 Self-Attention 是如何計(jì)算的。
假設(shè)我們正在計(jì)算 Thinking 的 Self-Attention。我們需要將這個(gè)單詞和句子中的其他單詞得分,這個(gè)分?jǐn)?shù)決定了我們將一個(gè)單詞編碼到某個(gè)位置時(shí),需要將多少注意力放在句子的其他部分。
這個(gè)得分是通過當(dāng)前單詞的 Querry 向量和其他詞的 Key 向量做內(nèi)積得到的。
(也可以理解為當(dāng)前單詞的是由句子的所有單詞加權(quán)求和得到的,現(xiàn)在計(jì)算的是當(dāng)前單詞和其他單詞的分?jǐn)?shù),這個(gè)分?jǐn)?shù)將用于后面計(jì)算各個(gè)單詞對(duì)當(dāng)前單詞的貢獻(xiàn)權(quán)重。)
第三步,將這個(gè)分?jǐn)?shù)處以 8(Value 向量是 64 維,取平方根,主要是為了穩(wěn)定梯度)。然后將分?jǐn)?shù)通過 Softmax 標(biāo)準(zhǔn)化,使它們都為正,加起來等于1。
經(jīng)過 Softmax 后的分?jǐn)?shù)決定了序列中每個(gè)單詞在當(dāng)前位置的表達(dá)量(如,對(duì)著 Thinking 這個(gè)位置來說,= 0.88 * Thinking + 0.12 * Machines)。Softmax 分?jǐn)?shù)越高表示與當(dāng)前單詞的相關(guān)性更大。
第四步,將每個(gè)單詞的 Value 向量乘以 Softmax 分?jǐn)?shù)并相加得到一個(gè)匯總的向量,這個(gè)向量便是 Self-Attention 層的輸出向量。
以上便是 Self-Attention 的計(jì)算過程,得到的這個(gè)向量會(huì)輸送給下一層的 Feed Forward 網(wǎng)絡(luò)。
在實(shí)際的實(shí)現(xiàn)過程中,為了快速計(jì)算,我們是通過矩陣運(yùn)算來完成的。
簡(jiǎn)單的看一下 Self-Attention 的矩陣運(yùn)算:
首先是輸入矩陣與查詢矩陣、鍵矩陣和值矩陣。
然后用 softmax 計(jì)算權(quán)重,并加權(quán)求和:
谷歌論文中模型框架中畫的 Multi-Head Attention 層,Multi-Head Attention 其實(shí)就是包含了多個(gè) Self-Attention 。所以 Multi-Head Attention 有多個(gè)不同的查詢矩陣、鍵矩陣和值矩陣,為 Attention 層提供了多個(gè)表示空間。
Transformer 中每層 Multi-Head Attention 都會(huì)使用八個(gè)獨(dú)立的矩陣,所以也會(huì)得到 8 個(gè)獨(dú)立的 Z 向量:
但是 Feed Forward 層并不需要 8 個(gè)矩陣,它只需要一個(gè)矩陣(每個(gè)單詞對(duì)應(yīng)一個(gè)向量)。所以我們需要一種方法把這8個(gè)壓縮成一個(gè)矩陣。這邊還是采用矩陣相乘的方式將 8 個(gè) Z 向量拼接起來,然后乘上另一個(gè)權(quán)值矩陣 W ,得到后的矩陣可以輸送給 Feed Forward 層。
以上便是 Multi-Head Attention 的內(nèi)容,我們把它們都放在一起看一看:
我們來看一下 Multi-Head Attention 的例子,看看不同的 Attention 把 it 編碼到哪里去了:
這邊先只關(guān)注兩個(gè) Attention,可以看到一個(gè) Attention 關(guān)注了 animal,另一個(gè)專注了 tired。
但如果我們把八個(gè) Attention 都打開就很難解釋了:
我們的模型可以完成單詞的 Attention 編碼了,但是目前還只是一個(gè)詞袋結(jié)構(gòu),還需要描述一下單詞在序列中順序問題。
為了解決這個(gè)問題,Transformer 向每個(gè)輸入的 Embedding 向量添加一個(gè)位置向量,有助于確定每個(gè)單詞的絕對(duì)位置,或與序列中不同單詞的相對(duì)位置:
這種方式之所以有用,大概率是因?yàn)?,將配置信息添加?Embedding 向量中可以在 Embedding 向量被投影到Q/K/V 向量后,通過 Attention 的點(diǎn)積提供 Embedding 向量之間有效的距離信息。
舉個(gè)簡(jiǎn)單的例子,以 4 維為例:
下圖顯示的是,每一行對(duì)應(yīng)一個(gè)位置編碼向量。所以第一行就是我們要添加到第一個(gè)單詞的位置向量。每一行包含512個(gè)值——每個(gè)值的值在1到-1之間(用不同的顏色標(biāo)記)。
這張圖是一個(gè)實(shí)際的位置編碼的例子,包含 20 個(gè)單詞和 512 維的 Embedding 向量。可以看到它從中間一分為二。這是因?yàn)樽蟀氩糠值闹凳怯梢粋€(gè) Sin 函數(shù)生成的,而右半部分是由另一個(gè) Cos 函數(shù)生成的。然后將它們連接起來,形成每個(gè)位置編碼向量。這樣做有一個(gè)很大的優(yōu)勢(shì):他可以將序列擴(kuò)展到一個(gè)非常的長(zhǎng)度。使得模型可以適配比訓(xùn)練集中出現(xiàn)的句子還要長(zhǎng)的句子。
這里還要提一個(gè)編碼器的細(xì)節(jié),每個(gè)編碼器中的每個(gè)子層(Self-Attention, Feed Forward)都有一個(gè)圍繞它的虛線,然后是一層 ADD & Normalize 的操作。
這個(gè)虛線其實(shí)就是一個(gè)殘差,為了防止出現(xiàn)梯度消失問題。而 Add & Normalize 是指將上一層傳過來的數(shù)據(jù)和通過殘差結(jié)構(gòu)傳過來的數(shù)據(jù)相加,并進(jìn)行歸一化:
同樣適用于解碼器的子層:
看完編碼器后我們?cè)倏匆幌陆獯a器。
編碼器首先處理輸入序列,然后將頂部編碼器的輸出轉(zhuǎn)換成一組 Attention 矩陣 K 和 V,這兩個(gè)矩陣主要是給每個(gè)解碼器的 ”Encoder-Decoder Attention“ 層使用的,這有助于解碼器將注意力集中在輸入序列中的適當(dāng)位置:
下圖展示了翻譯過程,不斷重復(fù)此過程直到出現(xiàn)結(jié)束符號(hào)為止。像我們處理編碼器的輸入一樣,我們將輸出單詞的 Embedding 向量和位置向量合并,并輸入到解碼器中,然后通過解碼器得到最終的輸出結(jié)果。
解碼器中的 Self-Attention 層操作方式與編碼器中的略有不同。
在解碼器中,Self-Attention 層只允許注意到輸出單詞注意它前面的單詞信息。在實(shí)現(xiàn)過程中通過在將 Self-Attention 層計(jì)算的 Softmax 步驟時(shí),屏蔽當(dāng)前單詞的后面的位置來實(shí)現(xiàn)的(設(shè)置為-inf)。
解碼器中的 “Encoder-Decoder Attention” 層的工作原理與 “Multi-Head Attention” 層類似,只是它從其下網(wǎng)絡(luò)中創(chuàng)建查詢矩陣,并從編碼器堆棧的輸出中獲取鍵和值矩陣(剛剛傳過來的 K/V 矩陣)。
解碼器輸出浮點(diǎn)數(shù)向量,我們?cè)趺窗阉兂梢粋€(gè)單詞呢?
這就是最后一層 Linear 和 Softmax 層的工作了。
Linear 層是一個(gè)簡(jiǎn)單的全連接網(wǎng)絡(luò),它將解碼器產(chǎn)生的向量投影到一個(gè)更大的向量上,稱為 logits 向量。
假設(shè)我們有 10,000 個(gè)不同的英語單詞,這時(shí) logits 向量的寬度就是 10,000 個(gè)單元格,每個(gè)單元格對(duì)應(yīng)一個(gè)單詞的得分。這就解釋了模型是怎么輸出的了。
然后利用 Softmax 層將這些分?jǐn)?shù)轉(zhuǎn)換為概率。概率最大的單元格對(duì)應(yīng)的單詞作為此時(shí)的輸出。
到目前為止我們介紹玩了 Transformer 的前向傳播過程,我們?cè)賮砜匆幌滤侨绾斡?xùn)練的。
訓(xùn)練時(shí)我們需要一個(gè)標(biāo)注好的數(shù)據(jù)集。
為了形象化,我們假設(shè)詞匯表只包含 5 個(gè)單詞和一個(gè)結(jié)束符號(hào):
然后我們給每個(gè)單詞一個(gè) One-Hot 向量:
假設(shè)我們剛開始進(jìn)行訓(xùn)練,模型的參數(shù)都是隨機(jī)初始化的,所以模型的輸出和期望輸出有所偏差。
我們計(jì)算兩者的損失函數(shù)并通過反向傳播的方式來更新模型。
在一個(gè)足夠大的數(shù)據(jù)集上對(duì)模型進(jìn)行足夠長(zhǎng)的時(shí)間的訓(xùn)練之后,我們希望生成的概率分布是這樣的:
當(dāng)訓(xùn)練好的得到模型后,我們需要為某個(gè)句子進(jìn)行翻譯。有兩種方式確定輸出單詞:
以上介紹完了 Transformer。
總結(jié):Transformer 提出了 Self-Attention 方式來代替 RNN 從而防止出現(xiàn)梯度消失和無法并行化的問題,并通過 Multi-Head Attention 機(jī)制集成了 Attention 豐富了特征的表達(dá),最終在精度和速度上較 Seq2Seq 模型都有了很大的提升。
聯(lián)系客服