
使用這些基本 REST API 最佳實踐構建出色的 API
里面主要有兩部分組成:Encoder 和 Decoder
當我輸入一個文本的時候,該文本數據會先經過一個叫Encoders的模塊,對該文本進行編碼,然后將編碼后的數據再傳入一個叫Decoders的模塊進行解碼,解碼后就得到了翻譯后的文本,對應的我們稱Encoders為編碼器,Decoders為解碼器。
細心的同學可能已經發現了,上圖中的Decoders后邊加了個s,那就代表有多個編碼器了唄,沒錯,這個編碼模塊里邊,有很多小的編碼器,一般情況下,Encoders里邊有6個小編碼器,同樣的,Decoders里邊有6個小解碼器。
我們看到,在編碼部分,每一個的小編碼器的輸入是前一個小編碼器的輸出,而每一個小解碼器的輸入不光是它的前一個解碼器的輸出,還包括了整個編碼部分的輸出。
我們放大一個encoder,發現里邊的結構是一個自注意力機制加上一個前饋神經網絡。
1、首先,self-attention的輸入就是詞向量,即整個模型的最初的輸入是詞向量的形式。那自注意力機制呢,顧名思義就是自己和自己計算一遍注意力,即對每一個輸入的詞向量,我們需要構建self-attention的輸入。在這里,transformer首先將詞向量乘上三個矩陣,得到三個新的向量,之所以乘上三個矩陣參數而不是直接用原本的詞向量是因為這樣增加更多的參數,提高模型效果。對于輸入X1(機器),乘上三個矩陣后分別得到Q1,K1,V1,同樣的,對于輸入X2(學習),也乘上三個不同的矩陣得到Q2,K2,V2。
2、那接下來就要計算注意力得分了,這個得分是通過計算Q與各個單詞的K向量的點積得到的。我們以X1為例,分別將Q1和K1、K2進行點積運算,假設分別得到得分112和96。
3、將得分分別除以一個特定數值8(K向量的維度的平方根,通常K向量的維度是64)這能讓梯度更加穩定,則得到結果如下:
4、將上述結果進行softmax運算得到,softmax主要將分數標準化,使他們都是正數并且加起來等于1。
5、將V向量乘上softmax的結果,這個思想主要是為了保持我們想要關注的單詞的值不變,而掩蓋掉那些不相關的單詞(例如將他們乘上很小的數字)
6、將帶權重的各個V向量加起來,至此,產生在這個位置上(第一個單詞)的self-attention層的輸出,其余位置的self-attention輸出也是同樣的計算方式。
將上述的過程總結為一個公式就可以用下圖表示:
還沒有,論文為了進一步細化自注意力機制層,增加了“多頭注意力機制”的概念,這從兩個方面提高了自注意力層的性能。
第一個方面,他擴展了模型關注不同位置的能力,這對翻譯一下句子特別有用,因為我們想知道“it”是指代的哪個單詞。
第二個方面,他給了自注意力層多個“表示子空間”。對于多頭自注意力機制,我們不止有一組Q/K/V權重矩陣,而是有多組(論文中使用8組),所以每個編碼器/解碼器使用8個“頭”(可以理解為8個互不干擾自的注意力機制運算),每一組的Q/K/V都不相同。然后,得到8個不同的權重矩陣Z,每個權重矩陣被用來將輸入向量投射到不同的表示子空間。
經過多頭注意力機制后,就會得到多個權重矩陣Z,我們將多個Z進行拼接就得到了self-attention層的輸出:
上述我們經過了self-attention層,我們得到了self-attention的輸出,self-attention的輸出即是前饋神經網絡層的輸入,然后前饋神經網絡的輸入只需要一個矩陣就可以了,不需要八個矩陣,所以我們需要把這8個矩陣壓縮成一個,我們怎么做呢?只需要把這些矩陣拼接起來然后用一個額外的權重矩陣與之相乘即可。
最終的Z就作為前饋神經網絡的輸入。
接下來就進入了小編碼器里邊的前饋神經網模塊了,關于前饋神經網絡,網上已經有很多資料,在這里就不做過多講解了,只需要知道,前饋神經網絡的輸入是self-attention的輸出,即上圖的Z,是一個矩陣,矩陣的維度是(序列長度×D詞向量),之后前饋神經網絡的輸出也是同樣的維度。
以上就是一個小編碼器的內部構造了,一個大的編碼部分就是將這個過程重復了6次,最終得到整個編碼部分的輸出。
然后再transformer中使用了6個encoder,為了解決梯度消失的問題,在Encoders和Decoder中都是用了殘差神經網絡的結構,即每一個前饋神經網絡的輸入不光包含上述self-attention的輸出Z,還包含最原始的輸入。
上述說到的encoder是對輸入(機器學習)進行編碼,使用的是自注意力機制+前饋神經網絡的結構,同樣的,在decoder中使用的也是同樣的結構。也是首先對輸出(machine learning)計算自注意力得分,不同的地方在于,進行過自注意力機制后,將self-attention的輸出再與Decoders模塊的輸出計算一遍注意力機制得分,之后,再進入前饋神經網絡模塊。
以上,就講完了Transformer編碼和解碼兩大模塊,那么我們回歸最初的問題,將“機器學習”翻譯成“machine learing”,解碼器輸出本來是一個浮點型的向量,怎么轉化成“machine learing”這兩個詞呢?
是個工作是最后的線性層接上一個softmax,其中線性層是一個簡單的全連接神經網絡,它將解碼器產生的向量投影到一個更高維度的向量(logits)上,假設我們模型的詞匯表是10000個詞,那么logits就有10000個維度,每個維度對應一個惟一的詞的得分。之后的softmax層將這些分數轉換為概率。選擇概率最大的維度,并對應地生成與之關聯的單詞作為此時間步的輸出就是最終的輸出啦!!
以上就是Transformer的框架了,但是還有最后一個問題,我們都是到RNN中的每個輸入是時序的,是又先后順序的,但是Transformer整個框架下來并沒有考慮順序信息,這就需要提到另一個概念了:“位置編碼”。
Transformer中確實沒有考慮順序信息,那怎么辦呢,我們可以在輸入中做手腳,把輸入變得有位置信息不就行了,那怎么把詞向量輸入變成攜帶位置信息的輸入呢?
我們可以給每個詞向量加上一個有順序特征的向量,發現sin和cos函數能夠很好的表達這種特征,所以通常位置向量用以下公式來表示:
最后祭出這張經典的圖,最初看這張圖的時候可能難以理解,希望大家在深入理解Transformer后再看這張圖能夠有更深刻的認識。
Transformer就介紹到這里了,后來的很多經典的模型比如BERT、GPT-2都是基于Transformer的思想。我們有機會再詳細介紹這兩個刷新很多記錄的經典模型。
文章轉自微信公眾號@算法進階