0
本文作者: 楊鯉萍 | 2019-07-29 18:13 |
雷鋒網(wǎng) AI 科技評論按:在自然語言處理任務中,循環(huán)神經(jīng)網(wǎng)絡是一種常見的方法,但近來,一種只依賴于注意力機制的特定神經(jīng)網(wǎng)絡模型已被證明它對于常見的自然語言處理任務的效果甚至優(yōu)于循環(huán)神經(jīng)網(wǎng)絡模型,這個模型被稱為變換器(Transformer)。同時,數(shù)據(jù)科學家 Maxime Allard 發(fā)表了相應的文章對變換器的原理機制作了介紹與講解,并用相應的實驗幫助大家更好的理解這種神經(jīng)網(wǎng)絡模型,雷鋒網(wǎng) AI 科技評論將其編譯如下。
論文《Attention Is All You Need》(https://arxiv.org/abs/1706.03762 )描述了變換器以及序列到序列學習的架構(gòu)。序列到序列(Seq2Seq)是一種神經(jīng)網(wǎng)絡,它將給定的元素序列(例如句子中的單詞序列)轉(zhuǎn)換為另一個序列。
Seq2Seq 模型很適用于翻譯,它可以將一種語言的單詞序列轉(zhuǎn)換為另一種語言中的單詞序列。通常 Seq2Seq 模型是基于長短期記憶(LSTM)而建立,LSTM 模塊通過序列的相關數(shù)據(jù),可以賦予序列意義,同時記住(或忘記)它判定為重要(或不重要)的部分。正因為句子依賴于序列,單詞的順序?qū)τ诶斫饩渥又陵P重要,所以 LSTM 是處理此類數(shù)據(jù)的不二選擇。
Seq2Seq 模型由編碼器和解碼器組成。編碼器獲取輸入序列并將其映射到更高維空間(n 維向量)。該抽象矢量被送入解碼器,再由解碼器將其轉(zhuǎn)換為輸出序列。輸出序列可以是另一種語言、符號、輸入的副本等。
我們可以將編碼器和解碼器理解為只會兩種語言的人工翻譯者。他們的第一語言是母語,但兩者的母語是不同的,比如一個是德語,另一個是法語;而他們的第二語言則是他們共有的一種虛構(gòu)語言。為了將德語翻譯成法語,編碼器將德語句子轉(zhuǎn)換為它所掌握的另一種語言,我們在這里稱為「虛構(gòu)語言」。同時,由于解碼器能夠讀取該虛構(gòu)語言,因此它現(xiàn)在可以把這個語言翻譯成法語。于是,這個模型(由編碼器和解碼器組成)就可以合力將德語翻譯成法語。
假設一開始,編碼器或解碼器對于虛構(gòu)語言都不是非常流利,為了很好的掌握它,我們將使用很多例子對它們(模型)進行訓練。對于 Seq2Seq 模型的編碼器和解碼器,一般情況下,其基礎配置各帶一個 LSTM 模塊。那么變換器在什么時候發(fā)揮作用呢?
我們需要一個技術細節(jié)來讓變換器更容易理解,即注意力機制。注意力機制通過查看輸入序列,然后在每個步驟確定序列中某一部分是否重要。這看似抽象,但舉個例子就很好理解了:在閱讀本文時,你會總是把注意力集中在你閱讀的單詞上,但同時你的腦海仍然保留了一些重要關鍵詞,以便聯(lián)系上下文。
所以,注意機制對于給定序列的工作方式與我們的閱讀方式類似。對于上文提到的擬人編碼器和解碼器的,我們可以想象為,編碼器不僅用虛構(gòu)語言寫下句子的翻譯,而且還寫了對句子語義理解很重要的關鍵詞,并將這些關鍵詞以及常規(guī)翻譯都提供給解碼器。通過這些關鍵詞,以及一些關鍵術語所給到的句子上下文,解碼器就可以識別出句子的重要部分,因此這些新的關鍵字就能夠幫助解碼器更容易的進行翻譯。
換而言之,對于 LSTM(編碼器)讀取的每個輸入,注意力機制會同時考慮其他幾個輸入,并通過對這些輸入賦予不同的權重來決定哪些輸入是重要的。然后,解碼器將編碼的句子和注意力機制提供的權重作為輸入。
要了解更多有關的注意力,可以參考這篇文章(https://skymind.ai/wiki/attention-mechanism-memory-network )。如果想了解更科學的方法,并且閱讀關于基于不同注意力機制的序列到序列模型方法,可以參考這篇《基于注意力的神經(jīng)機器翻譯的有效方法》的論文(https://nlp.stanford.edu/pubs/emnlp15_attn.pdf )。
《Attention Is All You Need》一文中引入了一種名為變換器的新型架構(gòu),正如標題所示,其中使用到了上文提到的注意力機制。
與 LSTM 一樣,變換器是一種在兩個部分(編碼器和解碼器)的幫助下將一個序列轉(zhuǎn)換為另一個序列的架構(gòu),但它與先前描述的「現(xiàn)有序列到序列模型」不同,因為它不包含任何循環(huán)神經(jīng)網(wǎng)絡(Recurrent Networks),如 GRU,LSTM 等。
到目前為止,循環(huán)神經(jīng)網(wǎng)絡是捕獲序列及時依賴性的最佳方法之一。然而,提交這篇論文的團隊證明,一個只有注意力機制而沒有任何循環(huán)神經(jīng)網(wǎng)絡的架構(gòu)能夠?qū)Ψg任務和其他任務的結(jié)果進行優(yōu)化。其中,在自然語言任務方面的一個改進是由引入 Bert 的團隊提出的:《BERT:用于語言理解的深度雙向變換器的預訓練》(https://arxiv.org/abs/1810.04805 )。
那么,變換器究竟是什么?我們將從下面這張圖片開始講解。
圖 1:變換器模型架構(gòu),來自 Vaswani 等人的《Attention Is All You Need》
編碼器位于左側(cè),解碼器位于右側(cè),編碼器和解碼器都由可以多次堆疊在一起的模塊組成,這展示在圖中的 Nx 部分。
我們看到模塊主要由多頭注意力機制(Multi-Head Attention)和前饋層組成。因為不能直接使用字符串,所以我們首先將輸入和輸出(目標句子)嵌入到 n 維空間中。模型中有一個很小但非常重要的部分,即對不同單詞的位置編碼。這是由于我們沒有可以存儲序列如何被輸入模型的循環(huán)網(wǎng)絡,而序列由其元素順序決定,所以我們需要以某種方式給出序列中每個單詞/部分的相對位置。這些位置被添加到每個單詞的嵌入表示(n 維向量)中。
讓我們仔細看看模型中的這些多頭注意力機制模塊:
圖 2:左圖為點積注意力機制,右圖為包含多個注意力層的并行多頭注意力機制,來自 Vaswani 等人的《Attention Is All You Need》
我們從注意力機制的左側(cè)描述開始,它不是很復雜,可以用下面的等式來描述:
其中,Q 是一個包含查詢(query,即序列中一個單詞的向量表示)的矩陣;K 是所有鍵(key,序列中所有單詞的向量表示);V 是值(value,包含所有序列中單詞的向量表示)。在編碼器和解碼器的多頭注意力機制模塊中,V 與 Q 具有相同的單詞序列。但對于反饋給編碼器和解碼器序列的注意力機制模塊,V 與 Q 具有不同的單詞序列。
為了簡化這個公式,我們可以將其表述為 V 與注意力權重 a 的乘積,其中的權重 a 由下式定義:
這意味著權重 a 由序列中的每個單詞(由 Q 表示)如何受序列中所有其他單詞(由 K 表示)的影響來定義。另外,SoftMax 函數(shù)能使權重 a 分布在 0 和 1 之間;然后我們再將這些權重應用于 V 中引入的所有單詞序列(在編碼器和解碼器中,V 與 Q 相同;但在編碼器和解碼器的輸入模塊之間,V 與 Q 則不同)。
右圖描述了如何將這種注意力機制轉(zhuǎn)化為多個可以并行使用的機制。通過 Q、K 和 V 的線性投影多次重復注意力機制,這使得系統(tǒng)可以從 Q、K 和 V 的不同表示中學習,這對模型是有益的。這些線性表示則通過將 Q、K 和 V 乘以在訓練期間所學的加權矩陣 W 來實現(xiàn)。
矩陣 Q、K 和 V 對于注意力機制模塊結(jié)構(gòu)中的每個位置是不同的,這取決于它們是在編碼器、解碼器中,還是在編碼器和解碼器之間。這是因為注意力機制要參與整個編碼器輸入序列或解碼器輸入序列的一部分,連接編碼器和解碼器的多頭注意力模塊將確保編碼器輸入序列與解碼器輸入序列的給定位置都被同時考慮在其中。
在編碼器和解碼器中的多頭注意力機制后,我們連接了一個點態(tài)前饋層。這個小的前饋網(wǎng)絡對于序列的每個位置都具有相同的參數(shù),即對來自給定序列的每個元素進行了單獨的、相同的線性變換。
訓練
如何訓練這樣的「野獸」模型呢?Seq2Seq 模型的訓練和推斷與平時的分類問題略有不同,轉(zhuǎn)換器也是如此。
我們知道,為了訓練翻譯任務的模型,我們需要兩種不同語言的句子進行雙向翻譯。一旦我們有大量的句子對,就可以對模型進行訓練。假設我們想將法語翻譯成德語,我們的編碼輸入是法語句子,而解碼器的輸入將是德語句子。但是,在這里解碼器輸入將向右移動一個位置。
其中一個原因是我們不希望這個模型在訓練期間去單純的學習對解碼器輸入的復制,而是希望模型在給定編碼器序列和特定的解碼器序列的情況下,對下一個字或者字符進行預測。
如果我們不移位解碼器序列,則模型將會學習簡單地「復制」解碼器輸入,因為位置 i 的目標字(字符)將是解碼器輸入中對應位置 i 的字(字符)。因此,通過將解碼器輸入移位一個位置,我們的模型則需要通過解碼器序列中已知位置 1,...,i-1 的字(字符)來預測位置 i 的目標字(字符)。這可以防止我們的模型學習復制、粘貼的任務。我們將句子開始的標記填充進解碼器輸入的第一個位置,否則由于右移該位置將是空的。類似地,我們將一個句子結(jié)尾標記附加到解碼器輸入序列來標記該序列的結(jié)束,并且這個標記也將附加到目標輸出句子中。在后文中,我們將看到這種方法對于推斷結(jié)果有何用處。
對于 Seq2Seq 模型和變換器,我們都做相同的處理。除了右移之外,變換器還將在第一個多頭注意力模塊的輸入端加入一個掩碼,以避免泄露潛在的「未來」序列元素。這是變換器架構(gòu)中特有的,因為這里面沒有循環(huán)神經(jīng)網(wǎng)絡可以用來事模型按照順序輸入序列。如果沒有掩碼,當我們將所有內(nèi)容一起輸入時,多頭注意力機制需要檢測整個解碼器中每一個輸入序列的位置。
將正確的移位輸入饋送到解碼器的過程也稱為教師強制(Teacher-Forcing),詳情可參考該博客內(nèi)容(https://machinelearningmastery.com/teacher-forcing-for-recurrent-neural-networks/ )。
我們想要進行損失計算的目標序列是有一個帶有序列結(jié)束標記的解碼器輸入(德語句子),而非移位后的句子。
推理
這些模型的推理和訓練不同,并且非常具有意義,因為我們希望模型在最終實現(xiàn)沒有對應德語句子的情況下翻譯法語句子。這里的訣竅是為輸出序列的每個位置重新輸入我們的模型,直到檢測到句末的標記為止。
具體步驟是:
輸入完整的編碼器序列(法語句子),并作為解碼器輸入;然后我們在第一個位置上加入一個空序列,這個空序列只有一個句子開頭標記。這將輸出一個序列,其中我們只需要第一個元素。
該元素將被填充到我們的解碼器輸入序列的第二個位置,該序列現(xiàn)在具有句子的開頭標記和其中的第一個字(字符)。
將編碼器序列和新的解碼器序列輸入到模型中,取輸出的第二個元素并將其放入解碼器輸入序列。
重復此操作,直到預測到句末的標記,這標志著翻譯結(jié)束。
我們看到,這個方法需要通過多次運行模型來翻譯該句子。
我們已經(jīng)看到了變換器的架構(gòu),并且從論文《Attention Is All You Need》
及它的作者那里知道該模型在語言任務中表現(xiàn)非常出色,現(xiàn)在我們在一個實例中來測試變換器的效果。
這里我們不用翻譯任務,而是使用德克薩斯州電力可靠性委員會(ERCOT)提供的德克薩斯州每小時電力流量的時間序列預測。每小時的數(shù)據(jù)可以在此獲得(http://www.ercot.com/gridinfo/load/load_hist/ )。如果你想深入了解架構(gòu),harvardnlp(http://nlp.seas.harvard.edu/2018/04/03/attention.html )提供了對變換器及其實現(xiàn)的詳細解釋。
既然我們可以使用基于 LSTM 的序列到序列模型來進行多步預測,那么讓我們來看看變換器做預測的能力。這里因為我們使用的不是單詞序列而是數(shù)值,所以我們首先需要對架構(gòu)進行一些更改;此外我們進行的是自動回歸實驗,而不是單詞/字符的分類。
數(shù)據(jù)
現(xiàn)有數(shù)據(jù)為我們提供了整個 ERCOT 控制區(qū)域的每小時負載。我使用了 2003 年至 2015 年的數(shù)據(jù)作為訓練集,2016 年作為測試集。因為只有負載值和負載的時間戳,所以我將時間戳擴展出了其它特性。從時間戳中,我提取了它對應的工作日并對其進行了一次熱編碼;另外,我使用年份(2003 年,2004 年,...,2015 年)和相應的小時(1,2,3,...,24)作為值本身(value),這為每天的每小時提供了 11 項特性值。出于收斂目的,我還將 ERCOT 負載除以 1000 進行了標準化操作。
為了預測給定的序列,我們需要一個過去的序列。在我們的示例中,我使用了前 24 小時的每小時數(shù)據(jù)來預測接下來的 12 小時的數(shù)據(jù),其中我們可以根據(jù)需要調(diào)整數(shù)據(jù)屬性。例如,我們可以將其更改為每日數(shù)據(jù)而不是每小時數(shù)據(jù)。
從論文中更改模型
第一步,我們需要刪除嵌入。因為我們的輸入中已經(jīng)有 11 個數(shù)值,而嵌入通常將給定的整數(shù)映射到 n 維空間;所以這里不使用嵌入,而是簡單地使用線性變換將 11 維數(shù)據(jù)轉(zhuǎn)換為 n 維空間,這類似于嵌入單詞。
然后,我們需要從變換器輸出中刪除 SoftMax 層,因為我們的輸出節(jié)點不是概率而是實際值;接著,就可以開始進行訓練了。
我使用了教師強制來進行訓練,這意味著編碼器由 24 個數(shù)據(jù)點的集合組成作為輸入,解碼器輸入是 12 個數(shù)據(jù)點的集合。其中第一個是「序列開始」值,后面的數(shù)據(jù)點是目標序列。在開始時引入「序列開始」值后,我將解碼器輸入相對于目標序列移動了一個位置。
我使用了一個只有「-1」的 11 維向量作為「序列開始」值。當然這可以改變,根據(jù)用例實際情況使用其它值是有益的;但是對于這個例子,這樣的設置非常有用,因為這可以使我們在輸入或輸出序列的任何一個維度中都沒有負值。
此示例的損失函數(shù)是均方誤差(the mean squared error)。
結(jié)果
下面的兩個圖顯示了結(jié)果。我取每天每小時值的平均值并將其與正確值進行比較。第一個圖顯示了前 24 小時的 12 小時預測;對于第二個圖,我們預測了一小時前的 24 小時數(shù)據(jù)。我們看到該模型能夠很好地捕捉到一些波動,訓練集的根均方誤差(the root mean squared error)為 859;對于驗證集,12 小時預測根均方誤差為 4,106,1 小時預測根均方誤差為 2,583。模型預測的平均絕對百分比誤差對應于第一個圖表為 8.4%,第二個圖表為 5.1%。
圖 3:一年前 24 小時的 12 小時預測
圖 4:一年前 24 小時的 1 小時預測
總結(jié)
結(jié)果表明,我們可以使用變換器進行時間序列預測。但在評估期間,結(jié)果顯示如果我們想要預測的步驟越多,錯誤就越高。上面的第一張圖(圖 3)是通過使用 24 小時預測接下來的 12 小時來實現(xiàn)的。如果我們只預測一個小時,結(jié)果會好得多,正如我們在第二個圖上看到的那樣(圖 4)。
對于變換器的參數(shù),如解碼器和編碼器層的數(shù)量等,還有很大的優(yōu)化空間。上述實驗不是一個完美的模型,它通過更好的調(diào)整和訓練,可將結(jié)果起到一定的改善作用。
使用 GPU 來加速訓練可能也會有很大幫助,本次實驗我并沒有在我的本地機器上運行,而是在 Watson Studio Local Platform 上用 GPU 來訓練了這個模型。你也可以使用 Watson 的機器學習 GPU 來加速訓練。
原文鏈接:
https://medium.com/inside-machine-learning/what-is-a-transformer-d07dd1fbec04
雷鋒網(wǎng) AI 科技評論
雷峰網(wǎng)原創(chuàng)文章,未經(jīng)授權禁止轉(zhuǎn)載。詳情見轉(zhuǎn)載須知。