attention機(jī)制是個(gè)坑俗他。
要明白attention機(jī)制,首先要明白seq2seq
要明白seq2sql阔逼,首先要明白RNN
要明白RNN兆衅,首先要明白MLP和BP算法
這是attention機(jī)制的前坑
明白attention機(jī)制后,要明白self-attention嗜浮,以及attention在諸多領(lǐng)域的應(yīng)用
明白self-attention后羡亩,要明白Transformer
明白transformer后,要明白Bert
這是attention機(jī)制的后坑
1危融,seq2seq (Sequence-to-sequence)
即一個(gè)序列生成另一個(gè)序列畏铆。最直觀的就是機(jī)器翻譯,一句英文翻譯成一句中文吉殃〈蔷樱或者應(yīng)答楷怒,問一句答一句。
模型結(jié)構(gòu):輸入數(shù)據(jù)連接一個(gè)encoder(編碼器)得到編碼輸出又稱中間狀態(tài)C然后連接到一個(gè)decoder(解碼器)最后解碼器的輸出作為模型輸出
這里的encoder瓦灶,decoder都是RNN網(wǎng)絡(luò)鸠删。可以是LSTM倚搬,或者是GRU冶共。總之這樣的網(wǎng)絡(luò)可以循環(huán)接收輸入的每一個(gè)詞w每界,然后為每一個(gè)詞都計(jì)算得到一個(gè)輸出h(w)捅僵。通常,這個(gè)h(w)可以連同下一個(gè)w一起做輸入眨层,最終的語義編碼c可以是最后一個(gè)詞的h(w)庙楚。
理解循環(huán)神經(jīng)網(wǎng)絡(luò)RNN以及seq2seq,可以這樣抽象理解:
RNN是某種外星生物趴樱,like eating itself`s shit馒闷。
現(xiàn)在RNN小E要吃一筐水果,吃第一個(gè)水果a1叁征,拉出來h(a1)(其實(shí)是RNN的隱層狀態(tài)h(x))
然后連同h(a1)和下一個(gè)水果a2有一起吃進(jìn)去纳账,拉出h(a2)(其實(shí)是RNN的隱層狀態(tài)h(x))
然后連同h(a2)和下一個(gè)水果a3有一起吃進(jìn)去,拉出h(a3)(其實(shí)是RNN的隱層狀態(tài)h(x))
按照這樣的方法一直吃到最后一個(gè)an捺疼,拉出h(an)(其實(shí)是RNN的隱層狀態(tài)h(x))
這里啰嗦幾句細(xì)節(jié)疏虫,
1,小E覺得吃a1的時(shí)候仿佛少了點(diǎn)什么啤呼,于是利用外星高科技——Random-Shit-Initializer獲取到h(a0)(其實(shí)是隨機(jī)初始化一個(gè)隱層狀態(tài))連同a1一起吃下卧秘。
2,小E利用外星高科技——Shit-Copier 保留了每個(gè)h(ai)官扣,這樣別人如果要中間產(chǎn)物翅敌,他也可以驕傲地拿出來
此時(shí),小E的朋友小D走過來惕蹄,發(fā)現(xiàn)小E把所有的水果都吃完了蚯涮,不開心。二話不說卖陵,把小E剛拉的h(an)吃了下去恋昼,妄圖知道小E到底吃了什么。
小D重復(fù)了小E的動作赶促,只不過略有差別:
小D吃下h(an),拉出來h(h(an))液肌,送入外星高科技Shit-Identifier 獲得b1(其實(shí)是RNN的每輪輸出y(x))
然后連同b1和h(h(an))一起吃下,拉出來h(b1)鸥滨,送入Shit-Identifier 獲得b2(其實(shí)是RNN的每輪輸出y(x))
然后連同b2和h(b1)一起吃下嗦哆,拉出來h(b2)谤祖,送入Shit-Identifier 獲得b3(其實(shí)是RNN的每輪輸出y(x))
直到小D實(shí)在吃不動了,最終拉出h(bm-1)老速,送入Shit-Identifier 獲得bm(其實(shí)是RNN的每輪輸出y(x))
小D驕傲地說粥喜,你分別吃了b1,b2,...bm。小E露出了贊許的目光橘券。
這里啰嗦幾句細(xì)節(jié)额湘,
1,小D覺得吃h(an)的時(shí)候仿佛少了點(diǎn)什么旁舰,于是利用外星高科技——Random-Shit-Initializer獲取到b0(其實(shí)是隨機(jī)初始化一個(gè)輸入)連同h(an)一起吃下锋华。
這里最重要的是連接小E和小D的h(an)。我們可以認(rèn)為它就是上圖中的C箭窜。
也可以發(fā)現(xiàn)毯焕,RNN星球的外星人,執(zhí)著于吃自己的隱層狀態(tài)h(x)磺樱,同時(shí)纳猫,其隱層狀態(tài)可以繼續(xù)計(jì)算得到輸出y。當(dāng)然竹捉,他們也會去吃y芜辕,當(dāng)手頭沒有輸入時(shí)他們會把前一個(gè)y當(dāng)輸入吃掉,就像小D块差。當(dāng)手頭有輸入時(shí)侵续,他們可以不吃y而吃輸入。就像小E憾儒。至于為什么這樣,可能是他們當(dāng)?shù)厝说牧?xí)慣吧乃沙,總得有點(diǎn)下shit菜不是起趾。
2,Attention機(jī)制
小E和小D是RNN星球的外星小伙伴警儒,這個(gè)大家都知道了
小E吃了一筐水果小D來了發(fā)現(xiàn)沒了很不開心训裆,這個(gè)大家都知道了
當(dāng)小D驕傲的說出小E具體吃了什么時(shí),他們發(fā)現(xiàn)蜀铲,小D說的沒有那么準(zhǔn)边琉。
兩人對視一會,發(fā)現(xiàn)問題:小D只吃了小E最后的h(an)记劝,那最后的h(an)攜帶的前面的信息就很少了变姨。要改變!要把小E所有的h(ai)都用上厌丑!而且定欧,要盡量找到對應(yīng)關(guān)系渔呵,例如預(yù)測第一個(gè)時(shí),要盡量用到第一個(gè)h(a)的信息砍鸠。
具體是怎么做的呢扩氢?
小D是這么想的,首先爷辱,讓小E把他拉的所有h(a)都給他录豺。即[h(a1),h(a2),h(a3)...h(an)],每個(gè)h(ai)都是一個(gè)向量,所以這些組成了一個(gè)矩陣K
然后饭弓,小D每拉出一個(gè)h(b)就去這個(gè)矩陣分別計(jì)算該h(b)和每個(gè)h(a)的相關(guān)度双饥,得到一系列分?jǐn)?shù),按照分?jǐn)?shù)大小來組合這些h(a)從而得到一個(gè)專屬于該h(b)的C示启。下圖中的a即是表示對應(yīng)的分?jǐn)?shù)
現(xiàn)在小D手上有一個(gè)h(b1)還有一個(gè)C兢哭,其實(shí)還有上一個(gè)輸出b1呀。小D只習(xí)慣一次吃倆夫嗓,這3個(gè)怎么辦迟螺?
他選擇堅(jiān)守自己的習(xí)慣。還是吃b1和h(b1)舍咖。但是C怎么辦矩父?
他把該h(b)和C合起來(向量拼接)送入外星高科技Shit-Identifier,計(jì)算得到b2這樣排霉,相當(dāng)于雖然吃了b和h(b)但b中包含著C的信息窍株,沒有浪費(fèi)。
還有一個(gè)問題攻柠,這里的分?jǐn)?shù)球订,通過softmax做了一個(gè)歸一化變成了加和為1的概率值
還有一個(gè)問題,怎么計(jì)算相關(guān)度瑰钮?cos相關(guān)度冒滩,點(diǎn)乘,皮爾森相關(guān)等都可以
最后一個(gè)問題浪谴,初始的隱藏狀態(tài)是什么开睡,因?yàn)闆]有用到非attention機(jī)制的h(h(an))。老規(guī)矩苟耻,隨機(jī)初始化篇恒。
所以,attention機(jī)制凶杖,像是一種配方胁艰,根據(jù)當(dāng)前不同位置來調(diào)配encoder一系列隱藏狀態(tài)h(ai)的組合比重,這顯然是很有道理的,因?yàn)榫湍梅g來說蝗茁,詞的順序往往是對應(yīng)的醋虏。
簡言之,encoder獲取狀態(tài)矩陣K哮翘,decoder根據(jù)每一輪隱藏狀態(tài)h計(jì)算注意力分?jǐn)?shù)獲得注意力向量C颈嚼,拼接h和C獲得輸出y,y和h進(jìn)入下一輪decode獲得新的h饭寺。阻课。。
3艰匙,self-Attention
上一步有個(gè)矩陣K限煞,來自encoder。而來自decoder的h類似于一個(gè)查詢(query)员凝。這個(gè)查詢分別與K中的不同向量h(a)(key)計(jì)算相關(guān)度得到分?jǐn)?shù)(score)署驻,然后利用分?jǐn)?shù)做權(quán)重與對應(yīng)的h(a)(value)加權(quán)求和得到自己想要的結(jié)果C。
這里我為什么要寫query健霹,key旺上,value呢?是為了講解self-attention糖埋。注意這里key和value都是指h(a)即encoder的狀態(tài)矩陣宣吱。
那如果這個(gè)query不來自decoder而來自encoder本身呢?即自己查自己瞳别?
有了query征候,key,value概念之后祟敛,就比較好理解self-attention了疤坝。
首先,輸入的詞匯(小E吃的水果也好馆铁,翻譯中一句話分成的一組詞也好)都是要embedding成一個(gè)固定長度的向量x才輸入模型的跑揉。即對于一句話的所有詞,組成了一個(gè)輸入矩陣X叼架。
然后畔裕,我們隨機(jī)生成3個(gè)矩陣Q,K,V對應(yīng)query衣撬,key乖订,value
對于一個(gè)輸入x,
用x點(diǎn)乘Q得到query
用x點(diǎn)乘K得到key
用x點(diǎn)乘V得到value
這樣具练,對于一句話中的所有x乍构,都可以得到對應(yīng)的query,key,value
有了這些就好辦了
每個(gè)x哥遮,都可以用自己的query去和其他key計(jì)算score岂丘,然后用該score和對應(yīng)的其他value來計(jì)算自己的注意力向量C。經(jīng)過這樣的計(jì)算眠饮,x變成了C奥帘。
上圖中的z即為C。而score到softmax之間的步驟是一些tricks仪召,不用管寨蹋。
同樣,可以多疊加幾層self-attention扔茅,用同樣的操作不同的QKV矩陣由c變成cc已旧,變成ccc
這就是self-attention。
self-attention像是一種向量轉(zhuǎn)換召娜。x變?yōu)閏运褪,維度沒變,值變了玖瘸。而同時(shí)秸讹,這種轉(zhuǎn)變又蘊(yùn)含了x與上下文x之間的關(guān)系。rnn也可以實(shí)現(xiàn)由x變?yōu)榱硪粋€(gè)向量店读,同時(shí)也考慮了上下文關(guān)系嗦枢,但是,他存在循環(huán)神經(jīng)網(wǎng)絡(luò)的弊端屯断,無法并行文虏。而self-attention組成的transformer則可以實(shí)現(xiàn)并行運(yùn)算。即殖演,他不需要等待下一個(gè)狀態(tài)h計(jì)算出來再計(jì)算C氧秘,而是直接通過QKV矩陣和當(dāng)前x計(jì)算所得。
那QKV怎么得到趴久?隨機(jī)初始丸相,訓(xùn)練所得。
4彼棍,參考
https://caicai.science/2018/10/06/attention%E6%80%BB%E8%A7%88/
https://jalammar.github.io/visualizing-neural-machine-translation-mechanics-of-seq2seq-models-with-attention/
https://zhuanlan.zhihu.com/p/37601161
https://jalammar.github.io/illustrated-transformer/