Transformer細(xì)節(jié)解讀
本系列將對(duì)Transformer的關(guān)鍵細(xì)節(jié)進(jìn)行解讀,盡可能用數(shù)學(xué)語言闡述,要讀懂本系列的讀者,只需具備基礎(chǔ)的線性代數(shù)知識(shí)即可。
self-attention
attention定義如公式(1)所示:

當(dāng)?
?時(shí),就是所謂的“self-attention”。在主流深度學(xué)習(xí)框架中,只要求?
?。
不妨設(shè)?
?,這里?
?表示詞序列?
?的長度,?
?表示詞序列?
?的長度,
?表示每個(gè)詞向量的維度,那么公式(1)中的?
?。首先將?
?展開來寫:

其中,?
?,表示單個(gè)詞向量。接下來對(duì)?
?進(jìn)行展開:

其中,?
?表示向量的內(nèi)積,用來衡量向量
?和 向量
的相似度,
?越大則表示 向量
?和 向量
?越相似。?
?表示 按行?
?依次對(duì)?
?中每行所在位置的元素進(jìn)行?
?操作,即:

?是單增函數(shù),即?
?越大,?
?越大。
最后對(duì)?
?展開:

公式(5)中任一行向量?
?表明,?
?和?
?越相似,?
?的系數(shù)越大,即?
?在結(jié)果行向量?
?貢獻(xiàn)的比例越大。換另一種角度理解,?
?建模了詞序列?
?中各個(gè)詞向量?
?和詞向量?
?的相關(guān)關(guān)系。
softmax padding mask
由于詞序列是不定長的,所以需要在后面進(jìn)行零填充固定到統(tǒng)一長度,因此才會(huì)出現(xiàn)所謂的"padding mask"。
對(duì)?
?分析(這里還沒有進(jìn)行softmax操作)。假定?
?,即零填充向量,那么?
?。由于?
?表示向量
?和 向量
的相似度。往往假定,零填充向量和向量?
?是最不相關(guān)的。因此,在進(jìn)行softmax操作前,我們需要將?
?,那么?
?。
常規(guī)的做法
假設(shè)詞序列?
?的padding mask矩陣為?
?詞序列?
?的padding mask矩陣為?
?記?
?,先將?
?取反,然后乘以?
?,其次加上?
?,最后進(jìn)行?
?操作。
快速的做法
由于后面還要做query padding mask,所以詞序列?
?的padding mask矩陣是怎么樣的,在這里沒有任何關(guān)系,不妨假定為全?
?矩陣。換句話說,只需要知道詞序列
?的padding mask矩陣?
?,直接對(duì)
?取反,然后乘以?
?,其次加上?
?,最后進(jìn)行?
?操作即可。
query padding mask
query padding mask只需:
?。但實(shí)際上,Transformer是不需要每次都做query padding mask,因?yàn)門ransformer中的各個(gè)詞向量是獨(dú)立操作的,互不干擾了,即論文中的“并行”,所以只需在輸出之前的最后一步做query padding mask即可。
關(guān)于 縮放因子
縮放因子
是為了防止?
?不至于過大或過?。凑蹈?,負(fù)值更大),那么?
?做?
?就比較平均。
MHSA
不妨設(shè)?
?,SA如公式(1)所示:

MHSA則分別先對(duì)?
?進(jìn)行線性升維操作(即全連接操作,參數(shù)不共享),輸出?
?,然后按“頭”做?
?次,最后把結(jié)果拼接起來。如公式(2)所示:

其中,?
說白了,MHSA就是分別先把?
?進(jìn)行線性升維,然后對(duì)每個(gè)“頭”并行做?
?,總共?
?個(gè)“頭”,最后把結(jié)果拼接起來。
時(shí)間復(fù)雜度分析
假定單個(gè)矩陣的運(yùn)算使用常規(guī)做法,那么純?
?的時(shí)間復(fù)雜度如公式(4)所示:

MHSA的時(shí)間復(fù)雜度如公式(5)所示:

公式(5)中的?
?表示MHSA做線性升維并行的開銷時(shí)間,?
?表示做多“頭”并行的開銷時(shí)間。
假定忽略并行開銷的時(shí)間,且?
?,那么有公式(6):

公式(6)表明MHSA總可以通過調(diào)節(jié)?
?來獲得比?
?更少的時(shí)間復(fù)雜度。通常,?
?,因此總有:?
?。
優(yōu)勢在哪里?
假定?
?,那么MHSA既能用更少的時(shí)間復(fù)雜度,又能獲得更好的性能。因?yàn)楦呔S信息總是不劣于低維信息,比如:低維空間不可分的問題,高維空間可分;低維空間很難優(yōu)化的,高維空間更容易優(yōu)化,所以神經(jīng)網(wǎng)絡(luò)的向量維度都要逐步上升的。如果?
?,MHSA的性能會(huì)低于SA,因?yàn)椤跋确趾缶邸钡淖龇ǎ€是會(huì)有損性能的。
但是仔細(xì)一想,不管是線性升維還是并行,都需要更多的內(nèi)存開銷,因此MHSA也屬于用空間復(fù)雜度換時(shí)間復(fù)雜度的例子吧。
總結(jié)來說,MHSA的優(yōu)勢:
“分治的思想,充分利用顯卡的并行性,通過空間復(fù)雜度換取時(shí)間復(fù)雜度。如果?
?,那么還能有更好的性能”
值得注意的是,并行在移動(dòng)終端和嵌入設(shè)備,表現(xiàn)得不好~
通常來說,基于Transformer的神經(jīng)網(wǎng)絡(luò)模型只在兩處做padding mask,一處是在多頭注意力中做softmax padding mask(當(dāng)然,有多個(gè)Transformer就有多個(gè)softmax padding mask),另一處是loss前的最后一步做padding mask。
為什么Transformer只在多頭注意力中做softmax padding mask?其他層呢?不是說padding mask很重要嗎?
不急,一步一步來回答。列舉一下Transformer的組件:多頭注意力層、全連接層、Dropout層、激活函數(shù)層、LN層和add層。
首先,Dropout層、激活函數(shù)層和add層對(duì)詞序列中的各個(gè)詞向量是獨(dú)立操作的,顯然成立,那么本應(yīng)被零填充的詞向量是什么,無關(guān)緊要,因?yàn)椴粫?huì)影響其他非零填充向量,所以只需在loss前的最后一步做padding mask。
其次,全連接層對(duì)詞序列中的各個(gè)詞向量也是獨(dú)立操作的,因?yàn)槿B接層會(huì)給每個(gè)詞向量都獨(dú)立分配一個(gè)向量權(quán)重和偏置參數(shù),也是易得(有興趣的讀者,自己可以推導(dǎo)一下),那么本應(yīng)被零填充的詞向量是什么,無關(guān)緊要,因?yàn)椴粫?huì)影響其他非零填充向量的參數(shù)訓(xùn)練,所以也只需在loss前的最后一步做padding mask。
最后,就只剩下LN層了。大部分深度學(xué)習(xí)框架都是沿著詞向量維度做標(biāo)準(zhǔn)化,然后參數(shù)也是沿著詞向量維度。換句話說,所有詞向量共享一個(gè)?
?向量參數(shù)和一個(gè)?
?向量參數(shù)。那么本應(yīng)零填充卻沒有零填充,會(huì)不會(huì)影響共享向量參數(shù)的更新呢?
LN層的獨(dú)立
答案是不一定會(huì)。要看場景,比如:A、B、C共用一臺(tái)電腦,C每次使用電腦,都恢復(fù)電腦原樣,那么在A和B看來,電腦只被A和B共用,因?yàn)镃不會(huì)改變電腦。
對(duì)應(yīng)到神經(jīng)網(wǎng)絡(luò)中,“C每次使用電腦,都恢復(fù)電腦原樣”對(duì)應(yīng)只在loss前的最后一步做padding mask,“C不會(huì)改變電腦”對(duì)應(yīng)零填充向量不改變共享參數(shù)的更新。
那么,只在loss前的最后一步做padding mask,零填充向量是否會(huì)改變共享參數(shù)的更新,即是否參與共享參數(shù)的梯度計(jì)算呢?答案是不會(huì)。這里筆者就直接把最后的結(jié)果寫出來,推導(dǎo)還是比較繁瑣的,具體可以參考BN的反向傳播推導(dǎo):

其中,?
表示詞序列,
?表示?
?mask向量,所在位置為0,那么?
?該位置為零填充。由公式(1)表示,只需在loss前的最后一步做padding mask,那么零填充不會(huì)參與共享參數(shù)梯度的計(jì)算。當(dāng)然,公式(1)不是嚴(yán)謹(jǐn)?shù)耐茖?dǎo),只是大概表達(dá)了零填充向量不參與共享參數(shù)的梯度計(jì)算。
結(jié)論
共享,不等價(jià)于一定不能相互獨(dú)立。要看場景。就好比,對(duì)所有進(jìn)程,CPU是共享的,但當(dāng)某進(jìn)程使用時(shí),就是獨(dú)占CPU的,所以感覺就是,每個(gè)進(jìn)程獨(dú)立使用一個(gè)CPU。
