你所不知道的 Transformer!
作者 | 臺運鵬
這是 Transformer 系列第一篇!
參考論文:https://arxiv.org/abs/1706.03762
章節
Reasons
Self-Attention
Multi-Head Attention
Positional Encoding
Add & Norm
Feed Forward
Residual Dropout
Encoder To Decoder
Shared Weights
Effect
Reasons For Transformer
新模型的產生往往是為了舊模型的問題所設計的。那么,原始模型的問題有哪些呢?
1、無法并行運算
在transformer之前,大部分應該都是RNN,下面簡單介紹一下RNN
可以看出,在計算X2加進去吐出來的值的時候必須要先把X1得出的參數值與X2放在一起才行。換句話說,RNN的計算是必須一個接一個,并不存在并行運算。如果不能并行運算,那么時間和計算成本均會增加。
2、語義表述不清
傳統的word2vec通過將詞語轉換為坐標形式,并且根據距離之遠近決定兩個詞意思的相近程度。?但是在NLP任務中,盡管是同一個詞語,但在不同語境下代表的意思很有可能不同。例如,你今天方便的時候,來我家吃飯吧和我肚子不舒服,去廁所方便一下這兩句中方便的意思肯定不一樣。可是,word2vec處理之后坐標形式就固定了。
3、突出對待
在一個句子中,當我們需要強調某一個部分的時候,word2vec無法為我們做到這些。比如,
The cat doesn't eat the cake because it is not hungry.
The cat doesn't eat the cake because it smells bad.
第一個句子中it強調的是the cat,在第二個句子中it強調的是the cake。
4、長距離信息缺失
盡管RNN處理序列問題很拿手,但如果一個句子很長,那么我要一直把句首的信息攜帶到句尾,距離越長,信息缺失的可能性就會變大。
Self-Attention
attention的意思是我們給有意義的內容配以較高的權重,那么自己與自己做attention是什么意思?
比如這個句中的"green",self的意思就是說拿這個詞與整個句子其他的詞語分別算相似程度。如此便考慮了詞與上下文和句子整體之間的關系。當然,自己與自己肯定是聯系最緊密。我們的目的是讓機器能夠判定出某個詞語與整個句子之間的關系。
那么,如何計算self-attenion呢?
首先將詞編碼成向量,總不大可能直接將詞輸進去。其次定義三個矩陣,??這三個矩陣分別代表了Query,Key,Value,分別代表去查詢的,被查詢的以及實際的特征信息。W的意思是權重的意思,可以類比于梯度下降,權重一般都是初始化一個參數,然后通過訓練得出。最后用詞向量與矩陣分別做點積即可得到q1,q2,k1,k2,v1,v2。
用q1,q2分別與k1,k2的轉置做點積,q代表的要查的,而k是被查的。如此便可得到兩者的關系了。
注意力一共分為additive attention和這里提到的dot product attention,那么為什么偏要用后者而非前者呢?
因為內積在實際中可以用高度優化矩陣運算,所以更快,同時空間利用率也很好。在此,簡要解釋一下內積可以表示兩向量關系的原因,在坐標系中,當兩個向量垂直時,其關系最小,為0。其實就是cos為0。假如a1,a2兩個向量很接近,那么,它們之間的夾角會很小,可知cos就很大,代表聯系就越緊密。
在K的維度很小的時候,兩種注意力機制幾乎一致,但是當K的維度上升之后,發現內積效果開始變差。其實,可以聯系一下Softmax圖像,當值變得很大的時候,梯度變化量幾乎很難觀察到,又被稱為梯度消失問題,這是為什么做scale的第一個原因。
在論文中提到
兩者做點積之后還需要除以矩陣K的維度開根號,Q,K,V矩陣維度是q x d_k,p x d_k,p x d_v,softmax是沿著p維進行的,但是很多時候大方差會導致數值分布不均勻,經過softmax之后就會大的愈大,小的愈小,這里除以一個矩陣K的維度其實類似于一個歸一化,讓它的方差趨向于1,分布均勻一點,這是第二個原因,所以在原paper里面又叫做Scaled Dot-Product Attention。
那為什么除以一個矩陣K的維度開根號能使方差變為1呢?首先對于隨機分布的q,k,方差均為1,期望均為0。我們把特定的一個q_i,k_i看成X,Y。
那么q與k做點積之后的結果均值為0,方差為d_k。方差太大不穩定,所以除以矩陣K的維度開根號,參照鏈接(https://www.zhihu.com/question/339723385) 。
例如 v = 0.36v1 + 0.64v2,v1,v2是矩陣V里的。
既然都是矩陣運算,那么都是可以并行加速的。
self-attention除了可以捕獲到句子語法特征外,還可以在長序列中捕獲各個部分的依賴關系,而同樣的處理用RNN和LSTM需要進行按照次序運算,迭代幾次之后才有可能得到信息,而且距離越遠,可能捕獲到的可能性就越小。而self-attention極大程度上縮小了距離,更有利于利用特征。
Multi-head Attention
理解了自注意力,那么什么是多頭注意力呢?
類比一下CNN,當我們不斷提取特征的時候會用到一個叫卷積核的東西(filter),我們為了最大化提取有效特征,通常選擇一組卷積核來提取,因為不同的卷積核對圖片的不同區域的注意力不同。比如,我們要識別一張鳥的圖片,可能第一個卷積核更關注鳥嘴,第二個卷積核更關注鳥翅膀等等。
在Transformer中也是如此,不同的Q,K,V矩陣得出的特征關系也不相同,同樣,不一定一組Q,K,V提取到的關系能解決問題,所以保險起見,我們用多組。這里可以把一組Q,K,V矩陣類比為一個卷積核,最后再通過全連接層進行拼接降維。
Positional Encoding
為什么要進行位置編碼呢?
我上面闡述的注意力機制是不是只說了某個詞與它所處的句子之間的關系,但是在實際自然語言處理中,只知道這個詞與句子的關系而不知道它在哪個位置是不行的。
在這篇論文中,用到了正余弦函數,pos代表的是位置,i是位置編碼的維度,d_model是輸入的維度,因為位置編碼要和輸入加在一起,所以兩者維度一致。那么,為什么用正余弦呢?原論文中說對于一個已知的PE_pos,對于一個確定的k,PE_pos+k都可以被表示為PE_pos的線性組合。
那么,既然有了公式,那位置編碼是算出來的還是學出來的呢?其實算出來和學出來的效果差不多,但是考慮到算出來的可以接受更長的序列長度而不必受訓練的干擾,所以在這個模型中,位置編碼是通過公式算出來的。
Add & Norm
Add 的意思是殘差相連,思路來源于論文Deep residual learning for image recognition(https://openaccess.thecvf.com/content_cvpr_2016/html/He_Deep_Residual_Learning_CVPR_2016_paper.html),Norm指的是Layer Normalization,來源于論文Layer normalization(https://arxiv.org/abs/1607.06450)。
論文中指出
That is, the output of each sub-layer is LayerNorm(x + Sublayer(x)), where Sublayer(x) is the function implemented by the sub-layer itself意思是上一層的輸入和輸出結果相拼接,然后進行歸一化,這樣可以更加穩定??隙〞凶x者好奇為什么不直接將輸出結果歸一化,偏要把輸入結果拼接到輸出結果然后再歸一化。?
如果還有讀者不明白Backprogation,建議看BP,這里簡要說明一下,求后向傳播的過程中,設殘差相連之后輸入的層為L層,那么,肯定要求這一層對殘差相連的時候的偏導數,而這時x是作為自變量的,所以對于F(x)+ x,求偏導后x就會變為1,那么無論什么時候都會加上這個常數1,這樣會一定程度上緩解梯度消失這個問題。?
這里選取的是層歸一化(Layer Normalization),用CNN舉例,假如我們的輸入是??,分別代表樣本數量(每一個神經元對應著一個樣本),通道數,高度和寬度,那么LN就是對于單獨的每一個樣本做歸一化,計算??個值的均值和標準差然后應用到這個樣本里面。歸一化的公式如下:
Feed Forward
Feed-Forward Network究竟做了啥呢?
首先它會引入RELU進行非線性變化,也就是公式前半部分所為,而且經過這一層之后會被升維,之后把這一層的結果連接到下一層進行線性變化,同時進行降維,保證輸入輸出維度一致。
Residual Dropout
在此模型中還在輸入,輸出層和位置編碼拼接中采用了dropout,這里的比例是0.1。
Encoder To Decoder
接下來要把左側的編碼器和右側的解碼器進行相連,細心觀察圖會發現只有兩個箭頭到了右邊,這兩個箭頭代表的是K,V矩陣,Q矩陣由右側解碼器提供。
另外,解碼器會MASK掉序列的某些部分,因為如果要判斷機器是否真正理解了整段句子的意思,可以把后面遮掉,它如果猜的出來,那么說明機器理解了。具體來說,對于位置i,通常會將i+1后面的全都MASK掉,這樣機器就是從前面學到的,它沒有提前看到后面的結果。
其他結構與編碼器一致,最后再進行線性變化,最終用softmax映射成概率。
Shared Weights
我們需要把輸入和輸出轉換為向量表示,而向量表示的方法是提前學到的。此外,最后用的線性轉換以及softmax都是學出來的。和常規的序列模型一致,輸入輸出以及線性轉換用的權重矩陣是共享的,只不過在輸入輸出層用的時候乘以模型維度開根號。
Effect
一般來說,維度d肯定比序列長度n大很多,所以每一層的復雜度此模型吊打RNN。模型結果對比沒多說的,幾乎是碾壓式的。
推薦閱讀
(點擊標題可跳轉閱讀)
干貨 | 公眾號歷史文章精選
我的深度學習入門路線
我的機器學習入門路線圖
重磅!
AI有道年度技術文章電子版PDF來啦!
掃描下方二維碼,添加?AI有道小助手微信,可申請入群,并獲得2020完整技術文章合集PDF(一定要備注:入群?+ 地點 + 學校/公司。例如:入群+上海+復旦。?
長按掃碼,申請入群
(添加人數較多,請耐心等待)
感謝你的分享,點贊,在看三連??
總結
以上是生活随笔為你收集整理的你所不知道的 Transformer!的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C/C++越来越不行了?让我们看看C++
- 下一篇: 超详细的 Bert 文本分类源码解读 |