back to index

【機器學習 2022】各式各樣神奇的自注意力機制 (Self-attention) 變型


link |
00:00.000
好,現場的同學、線上的同學大家好,那我們就開始上課吧!
link |
00:09.000
今天要講的是各式各樣的Self-Attention的技術。
link |
00:15.000
假設你已經看過跟Self-Attention相關的上課錄影,你已經知道Self-Attention是什麼,
link |
00:25.000
然後我們來告訴你其實Self-Attention有各式各樣的變形。
link |
00:31.000
在這個上課錄影的結尾已經告訴你說,其實Self-Attention並不是只有我們上課說的那種樣子。
link |
00:40.000
我們上課有說Self-Attention就是產生Q、K、B三種vector,
link |
00:45.000
然後這個Q跟K之間會兩兩算這個大發達,然後對value做weighted sum,然後做Self-Attention。
link |
00:54.000
假設你對這整個系列的機制已經非常的清楚,但是Self-Attention不只這樣子。
link |
01:01.000
在Self-Attention之前的影片裡面,我們就停在這個頁面告訴你說,
link |
01:07.000
Self-Attention其實有各式各樣的變化,他們往往都用什麼former、什麼former、什麼former作為結尾,
link |
01:18.000
但那是另外一個很長的故事了,今天我們就要來講這個故事。
link |
01:25.000
先很簡短的複習一下什麼是Self-Attention,還有它的難點、它的痛點在哪裡呢?
link |
01:34.000
我們知道Self-Attention的存在是為了要處理如果你的input是一個sequence的狀態,
link |
01:41.000
假設你要處理的input是一個sequence,這個sequence的長度我們用N來表示。
link |
01:48.000
這個sequence可能是各種不同的資料型態,它可能是一個句子,句子裡面的每一個token或詞彙當作是一個單位。
link |
02:00.000
或者是你的input可能是一段語音訊號,語音訊號裡面的一個frame當作一個單位。
link |
02:06.000
甚至最近常常有人把Self-Attention用在影像處理上,你的輸入是一張圖片,圖片裡面的每一個pixel當作一個單位。
link |
02:15.000
那Self-Attention它要做的事情就是處理一個input的sequence,那現在假設sequence的長度是N。
link |
02:23.000
那input一個sequence以後呢,我們會產生這個N個key的vector跟N個query的vector。
link |
02:32.000
那這個N個key的vector跟這個N個query的vector會兩兩之間做搭發的。
link |
02:39.000
那有N個key有N個query那叫做N平方次搭發的。
link |
02:44.000
把N平方次搭發的結果集合起來,你就得到一個N乘以N的矩陣,那這個矩陣呢叫做Attention的matrix。
link |
02:54.000
那我們根據這個Attention的matrix對value vector,那這個value vector我就沒有畫在這個圖片上了。
link |
03:01.000
我們得到這個Attention的matrix以後呢,對value vector做歸題上,那這個都是過去已經跟大家講過的內容。
link |
03:09.000
那我們在之前的錄影裡面也已經跟大家講過說,Self-Attention的痛點就是這個N乘以N的矩陣,它的計算量可能會非常的驚人。
link |
03:20.000
尤其是你的input sequence非常長的時候,這個N乘以N的Attention的matrix它的計算量會非常的大,
link |
03:28.000
會大到你沒有辦法承受。
link |
03:31.000
所以就有一系列的方法想辦法加速Attention這個機制的計算。
link |
03:37.000
但是在開始之前呢,這邊要提醒大家,其實Self-Attention往往只是一個你的巨大network的其中一個module。
link |
03:47.000
舉例來說,假設你要用的是Transformer,上課錄影照理說你已經聽過Transformer了。
link |
03:54.000
假設我們要用的是Transformer,Transformer裡面不是只有Self-Attention,除了Self-Attention以外還有其他的module。
link |
04:04.000
所以今天呢,雖然我們說Self-Attention它的運算量跟N平方是成正比的,
link |
04:12.000
跟sequence的長度,input sequence的長度的平方是成正比的。
link |
04:17.000
但是假設這個Self-Attention它的運算沒有dominate整個network的運算的話,
link |
04:24.000
那你加快Self-Attention的運算,那可能幫助不一定會很大。
link |
04:29.000
就有很多同學會,他用了這個新的Self-Attention的技術,
link |
04:32.000
在Transformer裡面發現計算的加速還蠻有限的。
link |
04:37.000
那因為很有可能整個network裡面,V-forward的部分,
link |
04:41.000
他所需要耗費的運算量也許根本比Self-Attention大。
link |
04:45.000
那你加快Self-Attention也許幫助就非常有限。
link |
04:49.000
那什麼時候Self-Attention會dominate這整個network呢?
link |
04:54.000
什麼時候這整個network最主要的運算會來自於Self-Attention呢?
link |
04:59.000
當input的sequence,也就是這個N的長度非常長的時候,
link |
05:04.000
整個Transformer裡面最主要的運算就會來自於Self-Attention。
link |
05:09.000
所以今天sequence很長的時候,加快Self-Attention才有幫助。
link |
05:15.000
所以這就是為什麼等一下你會看到的這些Self-Attention的變形,
link |
05:20.000
加快Self-Attention的方式往往最早都是用在影像處理上面。
link |
05:27.000
因為當很多人想要把Self-Attention用在影像處理上面的時候,
link |
05:31.000
他們就發現有非常大的障礙。
link |
05:34.000
怎麼說呢?假設你要處理的是256x256的一張image,
link |
05:39.000
那256x256的image也不是太大的image。
link |
05:42.000
那假設你今天硬是要用Self-Attention處理的話,
link |
05:45.000
會變成什麼狀況呢?
link |
05:47.000
如果你要用Self-Attention處理一張圖片,
link |
05:49.000
那你可能會把圖片裡面的每一個pixel當作一個單位。
link |
05:54.000
這個時候你input sequence的長度,
link |
05:56.000
就把這個圖片裡面的pixel全部拉直,變成256x256。
link |
06:01.000
那所以你的大N是256x256。
link |
06:04.000
如果今天Self-Attention它的運算量是正比於256x256的平方,
link |
06:10.000
不是只有256平方喔,是256x256再平方,
link |
06:14.000
所以其實是256的四次方。
link |
06:16.000
那這個運算量就會非常驚人了。
link |
06:19.000
所以這就是為什麼你會發現說,
link |
06:21.000
我們等一下看到的種種Self-Attention的變形,
link |
06:24.000
往往最早都是用在影像處理上。
link |
06:28.000
所以總之這邊要先跟大家強調的是,
link |
06:30.000
當input sequence非常長的時候,
link |
06:32.000
以下看到的那些招數才有可能會發揮真正的效用。
link |
06:38.000
好,那有什麼樣Self-Attention的變形呢?
link |
06:42.000
有什麼樣的方法可以加快Self-Attention這個機制的運算呢?
link |
06:47.000
那我們剛才說Self-Attention這個機制的運算,
link |
06:50.000
它最大的bottleneck來自於我們需要計算一個N乘以N的矩陣。
link |
06:57.000
所以人們就從這個地方下手,
link |
07:00.000
有沒有辦法加快這個N乘以N的矩陣的運算呢?
link |
07:04.000
那第一個想法是,
link |
07:06.000
也許我們並不需要把N乘以N的這個Attention Matrix裡面的每一個數值都計算出來。
link |
07:14.000
也許有一些位置,有一些位置的Attention的value應該是多少,
link |
07:20.000
我們不需要算,我們根據人類對這個問題的理解,
link |
07:25.000
可以直接知道Attention的value應該是多少。
link |
07:29.000
這樣講也許很抽象,我們先舉第一個例子。
link |
07:34.000
這個例子是這樣子的,
link |
07:36.000
有時候我們在做Attention的時候,
link |
07:39.000
有些問題不一定需要看整個sequence,
link |
07:44.000
也許有一些問題在做Attention的時候,
link |
07:47.000
在每一個位置上你只需要看左右的鄰居就可以得到正確的答案,
link |
07:54.000
就可以理解一個Token,一個位置它存有什麼樣的資訊。
link |
07:59.000
所以今天假設我們在做Self-Attention的時候,
link |
08:02.000
其實只有左右的鄰居的資訊是需要知道的,
link |
08:06.000
那也許你可以把更長的距離的Self-Attention的Attention的weight就直接設為0。
link |
08:15.000
講得更具體一點,
link |
08:17.000
你的Attention Matrix可以直接畫成這個樣子。
link |
08:21.000
在這個圖上,灰色的部分代表我們直接把Attention的weight設為0,
link |
08:28.000
就不算了,不需要去計算灰色的位置的Attention weight,
link |
08:31.000
它直接設為0。
link |
08:33.000
然後你只需要去計算有圖顏色的,不是灰色的,
link |
08:38.000
藍色這個部分的Attention的數值,
link |
08:42.000
這樣就可以加速運算,
link |
08:44.000
因為灰色的部分你都不算用Attention了,
link |
08:46.000
都不需要做任何計算,
link |
08:48.000
只算藍色的部分,那就可以加快這個矩陣產生的速度。
link |
08:53.000
那像這樣子的方法叫做Local Attention,
link |
08:57.000
或者叫Truncated Attention。
link |
09:00.000
但像這種Local Attention或Truncated Attention,
link |
09:03.000
它顯然有一個問題,
link |
09:05.000
就是每次你在做Attention的時候,
link |
09:07.000
你只看得到某一個小範圍之內的資訊。
link |
09:11.000
那這樣子做的話,那Attention跟CNN就沒什麼差別了,對不對?
link |
09:17.000
我們上課的時候其實已經跟大家講過CNN跟Attention的關係。
link |
09:22.000
我們有說,如果今天Attention都是Attend在一個很小的範圍內,
link |
09:27.000
那其實它就是CNN。
link |
09:30.000
所以如果我們今天用Local Attention,
link |
09:33.000
那就等於是做CNN,那你就直接用CNN就好啦。
link |
09:36.000
所以Local Attention它是一個可以加快Self-Attention運算的方法,
link |
09:41.000
但它不一定可以給你非常好的結果。
link |
09:44.000
那除了Local Attention以外,還有各式各樣的變形。
link |
09:50.000
比如說有人說,你既然覺得Local Attention不好,
link |
09:53.000
只看鄰居不好,那我們就看比較遠一點的鄰居。
link |
09:59.000
比如說在每一個位置,我們不是看下一個位置的資訊,
link |
10:03.000
上一個位置的資訊,而是先跳兩個,
link |
10:06.000
和三個位置之後的資訊,三個位置之前的資訊。
link |
10:11.000
那這樣就可以看到比較大的範圍內的資訊。
link |
10:15.000
那如果把它畫成Attention Matrix的話,
link |
10:18.000
你的Attention Matrix就長這個樣子。
link |
10:21.000
那這種方法叫做Stripe Attention。
link |
10:25.000
當你用Stripe Attention的時候,在這個圖上灰色的部分,
link |
10:30.000
就是直接填零,就不計算。
link |
10:33.000
我們只計算有圖青色的部分,有顏色的部分。
link |
10:38.000
那有人可能會問說,那為什麼是空兩格,
link |
10:42.000
看三步之外發生什麼事情,空兩格,
link |
10:45.000
看三步之前發生什麼事情呢?
link |
10:48.000
你可以不要這樣做,你可以只空一個,
link |
10:51.000
然後你也可以空三格,這個完全是你自己決定的。
link |
10:56.000
那你可以根據你現在要處理的問題,
link |
10:58.000
決定說你的Stripe Attention應該要長什麼樣子。
link |
11:05.000
那還有其他的方法,有一個方法叫做Global Attention。
link |
11:12.000
那不管是剛才看過的Local Attention,
link |
11:15.000
還是Stripe Attention,都是以某一個位置作為中心,
link |
11:19.000
看這個位置左右兩邊發生什麼樣的事情。
link |
11:24.000
那如果我們今天想要知道一整個Sequence發生什麼事,
link |
11:29.000
那也許你可以用Global Attention。
link |
11:32.000
那Global Attention是什麼意思呢?
link |
11:35.000
在做Global Attention的時候,
link |
11:37.000
你會在你原來的Sequence裡面,
link |
11:39.000
加上一個特殊的Token。
link |
11:42.000
那如果你今天是做NLP的問題,
link |
11:45.000
你的input是一串文字的話,
link |
11:47.000
那就是加入一個特殊的符號,
link |
11:51.000
這個特殊的符號代表這個位置,
link |
11:54.000
要做Global Attention。
link |
11:57.000
那Global Attention它會做兩件事。
link |
12:00.000
第一個事情是Global Attention,
link |
12:03.000
它會Attain到Sequence裡面的每一個Token。
link |
12:08.000
它會從Sequence裡面的每一個Token都去收集資訊。
link |
12:13.000
也就是說這種特別的Token,
link |
12:17.000
它要做的事情就是先來收集一下整個句子的資訊,
link |
12:22.000
來了解一下這整個句子裡面,
link |
12:24.000
整個input的Sequence裡面發生了什麼樣的事情。
link |
12:28.000
所有人都會去看這個特別的Token,
link |
12:31.000
看看這個特別的Token裡面有發生什麼樣的事情,
link |
12:35.000
存有什麼樣的資訊。
link |
12:36.000
所以這些特別的Token,
link |
12:38.000
它們會Attain到所有的Token,
link |
12:40.000
另外它們會被所有的TokenAttain。
link |
12:44.000
然後具體的操作其實有兩種做法,
link |
12:48.000
怎麼做這個Global Attention呢?
link |
12:51.000
有兩種做法。
link |
12:52.000
第一種做法是,
link |
12:53.000
你在你原來的Sequence裡面就直接Assign一些人,
link |
12:59.000
直接Assign一些Token,
link |
13:01.000
作為Special Token。
link |
13:03.000
舉例來說,你可以說,
link |
13:05.000
如果是在處理文字的時候,
link |
13:07.000
大家都知道說Vert的每一個句子的開頭,
link |
13:10.000
不是有一個CLS的Token嗎?
link |
13:14.000
你告訴他什麼也沒有關係,
link |
13:15.000
其實在一般用Transformer來處理文字的時候,
link |
13:20.000
你會放一個代表開頭的Token,
link |
13:23.000
也許我們就直接把那個開頭的Token當作Special Token,
link |
13:28.000
或者是每一個句子都有句號,
link |
13:32.000
一個句子幾個數字都有句號,
link |
13:34.000
也許我們可以把句號當作Special Token。
link |
13:38.000
所以這種Special Token怎麼來?
link |
13:39.000
第一個做法就是,
link |
13:40.000
你從原來就有的Input Sequence裡面,
link |
13:44.000
原來就有的Token裡面,
link |
13:46.000
選一些當作Global的,
link |
13:50.000
當作這種特別的Token。
link |
13:52.000
那有另外一種做法是,
link |
13:54.000
你就外加額外的Token,
link |
13:57.000
今天不管Input的Sequence是什麼,
link |
13:59.000
Input的句子是什麼,
link |
14:00.000
你都直接硬是插兩個符號,
link |
14:03.000
這兩個符號代表特別的Token,
link |
14:06.000
這兩個特別的Token,
link |
14:07.000
他們會Attain到所有其他的Token,
link |
14:10.000
所有其他的Token也都會Attain到這兩個Token。
link |
14:14.000
那如果要把它的Attention Matrix畫出來的話,
link |
14:18.000
看起來就像是這個樣子。
link |
14:22.000
我們假設這一個句子裡面,
link |
14:25.000
這一個Input的Sequence裡面,
link |
14:27.000
頭兩個位置就是Special的Token,
link |
14:33.000
叫做Global Attention的Special的Token。
link |
14:36.000
那你發現說,
link |
14:38.000
在這一個Attention的Matrix裡面,
link |
14:42.000
我們假設這個Row,
link |
14:45.000
每一個Row代表一個Query,
link |
14:48.000
每一個Column代表一個Key,
link |
14:52.000
那我發現前兩個Row,
link |
14:54.000
前兩個Row全部都是有值的,
link |
14:58.000
全部都是要計算Attention的,
link |
15:00.000
代表說前兩個Token,
link |
15:02.000
他們是Special Token,
link |
15:04.000
前兩個位置他們代表Special Token,
link |
15:06.000
他們的Query要去Attain到所有其他人的Key。
link |
15:12.000
那今天你看這前兩個Column,
link |
15:16.000
也是有顏色的,
link |
15:18.000
這是什麼意思呢?
link |
15:19.000
代表說除了Special Token以外的那些Token,
link |
15:23.000
他們在做Attention的時候,
link |
15:25.000
他們的Query都會Attain到第一個位置跟第二個位置。
link |
15:30.000
所以每一個Row,
link |
15:32.000
每一個不是Special Token的位置,
link |
15:35.000
他們都Attain到Special Token,
link |
15:38.000
現在這個例子裡面是句子前面的前兩個Token。
link |
15:43.000
這個Global Token要Attain到所有人,
link |
15:46.000
也被所有人Attain以外,
link |
15:48.000
其他的Token彼此之間就沒有往來了。
link |
15:52.000
所以我發現說,
link |
15:53.000
在這個Attention的Matrix裡面,
link |
15:55.000
只有頭兩個Row跟頭兩個Column是有顏色的,
link |
15:59.000
其他位置直接塗灰色,
link |
16:01.000
其他位置的Attention直接塗綠色,
link |
16:03.000
所以代表其他位置,
link |
16:05.000
其他的Token不是Special Token,
link |
16:07.000
彼此之間互相就不做任何Attention,
link |
16:10.000
互相就不管彼此發生了什麼事。
link |
16:13.000
如果打一個比方的話,
link |
16:15.000
Special Token就是Token中的里長伯。
link |
16:18.000
你知道在一個里裡面,
link |
16:19.000
你可能不知道你的鄰居是誰,
link |
16:21.000
你的鄰居也不知道你是誰,
link |
16:23.000
你們互相是沒有往來的,
link |
16:25.000
但是每個人都認識里長伯,
link |
16:27.000
里長伯也認識每一個人。
link |
16:30.000
所以今天要傳遞什麼資訊,
link |
16:31.000
你可以透過里長伯來傳遞,
link |
16:33.000
這個就是Special Token的作用。
link |
16:36.000
這個是Global Attention,
link |
16:39.000
講到這邊,
link |
16:40.000
大家會問的一個問題是,
link |
16:41.000
我們講了各式各樣,
link |
16:43.000
憑藉著人的Knowledge,
link |
16:46.000
決定的這一種Self-Attention的Matrix,
link |
16:49.000
有Local的Attention,
link |
16:51.000
有Stride的Attention,
link |
16:53.000
有Global的Attention,
link |
16:55.000
那哪一種最好呢?
link |
16:57.000
應該要用哪一種才是對的呢?
link |
17:00.000
這邊的答案就是,
link |
17:02.000
小孩子才做選擇,
link |
17:04.000
你知道嗎?
link |
17:05.000
真正好的結果就是,
link |
17:06.000
全部都用。
link |
17:08.000
你記得嗎?
link |
17:09.000
一個Self-Attention裡面,
link |
17:10.000
它是有Multiple Head的,
link |
17:12.000
對不對?
link |
17:13.000
我們可以設定多個不同的Head,
link |
17:15.000
你就讓每一個Head,
link |
17:17.000
做不同的事,
link |
17:18.000
有的Head是Local Attention,
link |
17:20.000
有的Head是Stride Attention,
link |
17:22.000
有的Head是Global Attention,
link |
17:25.000
就這樣,
link |
17:26.000
你就不需要做選擇了。
link |
17:27.000
所以一些比較知名的,
link |
17:30.000
這個Self-Attention的變形,
link |
17:33.000
就是這麼做的,
link |
17:34.000
比如說Long-Former,
link |
17:36.000
Long-Former就是把Local Attention,
link |
17:38.000
加Stride Attention,
link |
17:40.000
加Global Attention,
link |
17:42.000
還有另外一個知名的,
link |
17:44.000
這個Self-Attention的變形,
link |
17:46.000
叫做Big Bird,
link |
17:47.000
這邊我看了很久,
link |
17:49.000
都不知道它跟Big Bird,
link |
17:51.000
有什麼樣的關係,
link |
17:52.000
我覺得它就是純粹湊梗,
link |
17:54.000
你知道嗎?
link |
17:55.000
它的模型命名為Big Bird,
link |
17:57.000
它連小模型的名字都懶得想了,
link |
17:59.000
直接就把它叫做Big Bird,
link |
18:01.000
那Big Bird其實就是Long-Former,
link |
18:04.000
加Random Attention,
link |
18:06.000
就是原來Long-Former裡面的東西,
link |
18:07.000
它都有,
link |
18:08.000
它有Local Attention,
link |
18:09.000
有Global Attention,
link |
18:10.000
但是它自己新加了一個很特別的東西,
link |
18:13.000
叫做Random Attention,
link |
18:16.000
就是它會隨機選一些位置,
link |
18:19.000
隨機選一些Token,
link |
18:21.000
讓它們彼此之間,
link |
18:23.000
也是有Attention的,
link |
18:25.000
至於這個Random Attention,
link |
18:27.000
有什麼樣的妙用,
link |
18:28.000
這個就留給大家自己去研究,
link |
18:31.000
可以看一下Big Bird這篇Paper,
link |
18:33.000
它會有更詳細的說明,
link |
18:35.000
甚至有理論的推導,
link |
18:36.000
告訴你說,
link |
18:37.000
為什麼要有這個Random的Attention,
link |
18:40.000
剛才我們是用人工的力量,
link |
18:44.000
直接告訴你說,
link |
18:45.000
哪一些位置就不需要算Self-Attention,
link |
18:50.000
哪些位置直接不理,
link |
18:52.000
但是這樣真的是最好的方法嗎?
link |
18:55.000
也許不見得,
link |
18:56.000
也許人類設計的這些Attention,
link |
18:59.000
人類自己決定,
link |
19:01.000
哪一些地方不需要算Attention,
link |
19:03.000
並不能得到最好的結果。
link |
19:06.000
我們能不能夠不要用人的力量,
link |
19:10.000
而是用Data-Driven的方法呢?
link |
19:13.000
舉例來說,
link |
19:14.000
今天在一個Self-Attention的Matrix裡面,
link |
19:18.000
可能某些位置,
link |
19:19.000
它的Value,Attention的Weight就是特別大,
link |
19:24.000
某一些位置,
link |
19:25.000
它的Attention的Value就是特別小。
link |
19:29.000
這個時候,
link |
19:30.000
其實你可以把Attention的Value特別小的位置,
link |
19:34.000
直接無理。
link |
19:35.000
把Attention的Value特別小的位置,
link |
19:38.000
本來就很接近0,
link |
19:39.000
你直接把它當作0,
link |
19:40.000
不去計算,
link |
19:41.000
也許對你這樣子有變成0跟沒有變成0,
link |
19:46.000
也許結果是不會差距太大的。
link |
19:49.000
如果我們用這樣子的方法,
link |
19:51.000
來加快Attention的運算,
link |
19:53.000
那也許我們簡化以後的Attention,
link |
19:57.000
跟原來完整的Attention,
link |
19:59.000
就不會有太大的差距。
link |
20:02.000
所以我們其實可以想看看,
link |
20:05.000
有沒有辦法直接估計,
link |
20:07.000
在一個Attention的Matrix裡面,
link |
20:10.000
哪一些位置有可能會有比較大的值。
link |
20:14.000
我們只計算那些,
link |
20:16.000
有可能會有比較大的值的位置。
link |
20:19.000
如果有些位置,
link |
20:20.000
我們猜它可能本來Attention的Value就會很小,
link |
20:23.000
那我們直接就不進行任何的計算,
link |
20:27.000
我們就直接把它當作是0。
link |
20:30.000
再來的問題是,
link |
20:32.000
怎麼快速的估算出,
link |
20:34.000
哪些位置可能有大的AttentionValue,
link |
20:37.000
進行詳細的計算,
link |
20:39.000
哪些位置可能有小的AttentionValue,
link |
20:42.000
直接就可以無視呢?
link |
20:45.000
這邊的方法,
link |
20:47.000
在Reformer跟Routing Transformer,
link |
20:50.000
這兩篇Paper裡面,
link |
20:51.000
他們都用了非常類似的方法,
link |
20:54.000
他們用了Clustering這個技術,
link |
20:56.000
就是你先把你的Query跟Key拿出來,
link |
20:59.000
然後你就做Clustering,
link |
21:02.000
你就根據這個Query跟Key,
link |
21:04.000
它們相近的程度做Clustering,
link |
21:08.000
比較近的就分類在一起,
link |
21:10.000
比較遠的就屬於不同的Cluster,
link |
21:13.000
在今天這個例子裡面,
link |
21:15.000
總共分成四個Cluster,
link |
21:17.000
這邊有紅色的Vector,
link |
21:19.000
邊框是紅色的Vector,
link |
21:20.000
代表它們屬於Cluster1,
link |
21:22.000
邊框是紫色的,
link |
21:24.000
代表屬於Cluster2,
link |
21:26.000
邊框是綠色的,
link |
21:28.000
代表屬於Cluster3,
link |
21:30.000
邊框是黃色的,
link |
21:31.000
代表屬於Cluster4,
link |
21:33.000
我們把Query跟Key做Clustering,
link |
21:36.000
在這個例子裡面分成四個Cluster,
link |
21:39.000
這個Cluster的目的,
link |
21:41.000
是要讓相近的Vector,
link |
21:44.000
就屬於同一個Cluster,
link |
21:47.000
不相近的Vector,
link |
21:48.000
就屬於不同的Cluster,
link |
21:51.000
講到這邊有同學可能會問說,
link |
21:53.000
Clustering這件事情,
link |
21:55.000
會不會也耗費很大的運算量呢?
link |
21:57.000
如果今天Clustering這件事情,
link |
21:59.000
它的Complexity,
link |
22:01.000
也跟Sequence的平方有關的話,
link |
22:04.000
那做Clustering,
link |
22:06.000
也許根本沒有辦法加速Search Attention的運算,
link |
22:10.000
但是實際上呢,
link |
22:12.000
Clustering有很多可以加速的方法,
link |
22:15.000
所以這邊在做Clustering的時候,
link |
22:17.000
你會採取一個,
link |
22:19.000
可能是估測不是非常準確,
link |
22:21.000
但非常快速的方法,
link |
22:23.000
來把這一些Query跟Key的Vector進行分群,
link |
22:27.000
那在Reformer還有Routing Transformer裡面,
link |
22:30.000
就採取了不同的Clustering的方法,
link |
22:32.000
來快速的把相近的Query跟Key,
link |
22:35.000
歸在同一群裡面,
link |
22:37.000
那把Query跟Key歸在同一群裡面以後,
link |
22:40.000
接下來呢?
link |
22:42.000
接下來呢,
link |
22:44.000
如果一個Query跟一個Key,
link |
22:46.000
它們落在同樣的Cluster裡面,
link |
22:48.000
我們才去計算Attention的位置,
link |
22:51.000
所以舉例來說,
link |
22:53.000
這個紅色的Query跟這三個Key,
link |
22:56.000
它們是在同一個Cluster裡面,
link |
22:59.000
那我們就計算一下,
link |
23:01.000
它的Attention的位置,
link |
23:03.000
紅色的這個Query跟其他的這五個Key,
link |
23:07.000
它們不在同一個Cluster裡面,
link |
23:10.000
那就代表說它們其實很不像,
link |
23:12.000
它們的距離其實是偏遠的,
link |
23:14.000
直接把它們的Attention設為零,
link |
23:17.000
所以同理,
link |
23:19.000
黃色的這個Vector,
link |
23:21.000
它跟另外這兩個Key在同一個Cluster裡面,
link |
23:23.000
所以只有這兩個位置需要計算Attention,
link |
23:25.000
其他地方直接不零,
link |
23:27.000
所以呢,
link |
23:29.000
這整個Attention的Matrix裡面,
link |
23:31.000
很多位置你就不需要去計算,
link |
23:33.000
直接算零,
link |
23:35.000
只有屬於同一個Cluster的Query跟Key,
link |
23:37.000
我們才計算它的Attention位,
link |
23:39.000
那這樣就可以加快這個Attention的Matrix的計算。
link |
23:43.000
好,那這個是Clustering的方法。
link |
23:47.000
好,那到目前為止啊,
link |
23:50.000
我們怎麼決定哪一些位置要計算Cluster,
link |
23:55.000
哪些位置不要計算Cluster,
link |
23:57.000
都是憑著人類對這個問題的理解,
link |
24:00.000
不管是前面我們講的Local Attention, Global Attention,
link |
24:04.000
還是到Clustering,
link |
24:05.000
Clustering是假設說比較近的Vector,
link |
24:07.000
我們才去計算它的Attention,
link |
24:11.000
所以到目前為止,
link |
24:12.000
要不要計算Attention,
link |
24:14.000
往往還是基於人類對這個問題的理解。
link |
24:18.000
那有沒有辦法把要不要計算Attention這件事情,
link |
24:22.000
用Learn的直接把它學出來呢?
link |
24:26.000
是有可能的。
link |
24:28.000
有一個方法叫做Synhome Sorting Network,
link |
24:32.000
它要做的事情就是,
link |
24:34.000
哪些地方要不要計算Attention,
link |
24:37.000
我們直接用Learn的來決定這件事情。
link |
24:41.000
所以呢,我們要計算Attention的時候,
link |
24:44.000
你要先產生一個Matrix,
link |
24:46.000
這個Matrix裡面呢,
link |
24:47.000
有一些位置是1,有一些位置是0,
link |
24:50.000
那這邊呢,塗深色的代表1,塗淺色的代表0,
link |
24:54.000
只有塗深色的地方需要去計算Attention,
link |
24:59.000
淺色的地方就當作Attention是0,
link |
25:02.000
我們就不計算Attention,
link |
25:04.000
所以哪一個Key要跟哪一個Query計算Attention,
link |
25:07.000
我們用這一個Matrix來決定。
link |
25:09.000
而這個Matrix怎麼來呢?
link |
25:11.000
到目前為止,
link |
25:13.000
在這門課講到目前為止,
link |
25:15.000
哪一些地方要計算Attention都是人決定的,
link |
25:18.000
但是在Synhome Sorting Network裡面,
link |
25:21.000
他決定直接Learn一個Network,
link |
25:24.000
Learn另外一個Network,
link |
25:25.000
來決定哪些地方需要計算Attention。
link |
25:28.000
怎麼做呢?
link |
25:29.000
這個是你的Input Sequence,
link |
25:31.000
然後呢,你把Input Sequence的每一個Position,
link |
25:35.000
通過一個Network產生一個Vector,
link |
25:39.000
這個Vector的長度要跟你的Sequence一樣,
link |
25:42.000
所以Input Sequence的每一個Vector,
link |
25:45.000
通過一個Network,
link |
25:46.000
那就產生另外一排Vector,
link |
25:49.000
那這些Vector全部拼起來以後,
link |
25:51.000
它的大小也要是N乘以N,
link |
25:54.000
跟你的Attention的Matrix一樣。
link |
25:56.000
那我們現在的目標,
link |
25:58.000
就是要把這個東西,
link |
26:00.000
變成這個東西。
link |
26:02.000
那你可能會想說,
link |
26:03.000
可是這個決定要不要計算Attention的Matrix,
link |
26:06.000
裡面它的值是Binary的,
link |
26:08.000
只有1跟0而已啊。
link |
26:11.000
那可是Network的Output,
link |
26:12.000
它是Continuous的,
link |
26:14.000
不是只有1跟0而已啊。
link |
26:16.000
那這就是這篇Network的一個重點,
link |
26:18.000
它有一個很特別的技術,
link |
26:20.000
來解決這個問題。
link |
26:22.000
你可以用某一個方法,
link |
26:23.000
把這個本來不是Binary的Matrix,
link |
26:26.000
變成Binary的Matrix,
link |
26:29.000
而且這一個過程,
link |
26:32.000
是可以微分的,
link |
26:34.000
所以最後你在Train這個NN的時候,
link |
26:36.000
它是跟你的整個Network一起Train出來的,
link |
26:40.000
你被Propagation的時候,
link |
26:41.000
是可以走過這個,
link |
26:42.000
從Continuous的Matrix,
link |
26:44.000
變成Binary的Matrix,
link |
26:46.000
變成Binary的Matrix的這個過程,
link |
26:48.000
這一關是可以微分的。
link |
26:50.000
所以這個NN,
link |
26:51.000
會跟Network的其他部分,
link |
26:52.000
一起被學出來。
link |
26:54.000
當然以上是一個比較簡化的講法啦,
link |
26:57.000
所以實際上,
link |
26:58.000
Syntax Sorting Network是怎麼運作的,
link |
27:00.000
那就請大家自己參考文獻。
link |
27:02.000
總之,
link |
27:03.000
怎麼產生這個Matrix,
link |
27:05.000
怎麼決定哪些位置,
link |
27:07.000
要被計算Attention,
link |
27:09.000
你可以任另外一個Network,
link |
27:11.000
來讓Machine自己去學,
link |
27:14.000
讓Network自己去學,
link |
27:16.000
什麼位置要不要計算Attention。
link |
27:18.000
這個是Syntax Sorting Network。
link |
27:22.000
講到這邊,
link |
27:23.000
大家有沒有問題想要問的呢?
link |
27:29.000
欸,你誰說?
link |
27:30.000
我想請問一下,
link |
27:31.000
這個Pattern認出來要怎麼,
link |
27:33.000
它會不會和原本Tension的很像,
link |
27:35.000
就是該大的地方大,
link |
27:36.000
該小的地方都很,
link |
27:38.000
這一次就是要怎麼定點說,
link |
27:40.000
它們兩個朝同一個方向前進,
link |
27:43.000
如果在這個Syntax Sorting Network。
link |
27:46.000
欸,可是你們,
link |
27:47.000
我其實我知道你的問題,
link |
27:49.000
但是你想喔,
link |
27:50.000
我們現在是先產生這個東西,
link |
27:52.000
然後呢,
link |
27:53.000
產生一個Binary的Mask,
link |
27:55.000
然後決定說只有這些位置,
link |
27:57.000
要算Attention,
link |
27:58.000
但為什麼,
link |
27:59.000
我們不直接Output Attention的Matrix呢?
link |
28:05.000
嗯,就被破梗了,
link |
28:06.000
所以這個Syntax Sorting Network的同一批作者,
link |
28:09.000
下一篇叫做Synthesizer,
link |
28:11.000
他們就決定說,
link |
28:12.000
欸,為什麼要做兩步呢?
link |
28:14.000
直接Output Attention的Weight就好啦,
link |
28:16.000
結束了這樣子。
link |
28:18.000
這樣有沒有回答到你的問題?
link |
28:23.000
嗯,好,好,
link |
28:25.000
好,這個是,
link |
28:26.000
本來Synthesizer是在這個投影片的最後一頁,
link |
28:29.000
才會講到嘛,
link |
28:30.000
我這邊就是破梗,
link |
28:31.000
對,你,
link |
28:32.000
好,
link |
28:33.000
欸,這樣大家還有問題要問嗎?
link |
28:36.000
欸,你說?
link |
28:37.000
這樣的話不是對於感覺有點喪失了Attention的那個計算很快速的性質,
link |
28:42.000
就是它變成每一個Input它就要去算個恩恩,
link |
28:46.000
然後過一個恩恩,
link |
28:47.000
然後再產生一個響亮,
link |
28:49.000
然後就變成平行。
link |
28:50.000
好,這也是一個很好的問題,
link |
28:52.000
我猜你的問題就是說,
link |
28:54.000
欸,我們今天用恩恩來產生這個Matrix,
link |
28:59.000
它真的會比原來用Key跟Value算出這個Attention Matrix還要快嗎?
link |
29:06.000
你仔細想想,
link |
29:07.000
假設我們每一個Input我們都要產生一個Vector,
link |
29:13.000
其實你的運算量跟原來的Attention Matrix其實差不多的,
link |
29:17.000
你根本沒有真的加速。
link |
29:18.000
好,這是個好問題,
link |
29:20.000
這邊有一個沒有提到的細節啦,
link |
29:23.000
在Synthome Sorting Network裡面,
link |
29:25.000
它真正做的事情是什麼呢?
link |
29:27.000
它真正做的事情是,
link |
29:29.000
好幾個Input的Vector會共用同一個Vector,
link |
29:36.000
也就是說假設你Input一個很長的Sequence,
link |
29:38.000
比如說100個Vector,
link |
29:40.000
我們把它切成10段,
link |
29:41.000
每段10個Vector,
link |
29:43.000
10個Vector一起通過Network以後產生一個Vector,
link |
29:46.000
那10個Vector要共用同一個Vector,
link |
29:50.000
也就是那10個Vector最後會共用同一個Column,
link |
29:55.000
它們會有同樣被Mask起來的地方,
link |
29:59.000
同樣要算Attention的地方,
link |
30:00.000
同樣不要算Attention的地方。
link |
30:04.000
好,這樣我們回答到你的問題。
link |
30:06.000
所以說產生出來的這個NN的Matrix,
link |
30:09.000
它裡面其實只有10種Vector,
link |
30:12.000
假設Input是100個,
link |
30:14.000
它裡面就只有10種Vector。
link |
30:15.000
對,就假設你這邊本來要算100x100的Matrix,
link |
30:19.000
就你Attention其實是100x100的Attention,
link |
30:22.000
但是在Synthome Sorting Network裡面,
link |
30:24.000
你用NN產生的這個東西,
link |
30:26.000
它是解析度比較低的,
link |
30:28.000
它其實只有10x10,
link |
30:29.000
那你再把它放大成100x100。
link |
30:34.000
好,這個大家都聽得很仔細,
link |
30:37.000
有沒有發現這個上課沒有要講的細節。
link |
30:41.000
到目前為止都想要產生一個NxN的Matrix,
link |
30:43.000
只是我們說NxN的Matrix裡面,
link |
30:45.000
有一些位置我們直接設定,
link |
30:48.000
但是我們真的需要一個NxN的Attention Matrix嗎?
link |
30:56.000
在林峰的這篇Paper裡面,
link |
30:58.000
他告訴我們說,
link |
31:00.000
看起來也許不需要喔。
link |
31:03.000
為什麼?
link |
31:04.000
因為林峰的這篇Paper裡面,
link |
31:06.000
他有做了一個實驗是,
link |
31:08.000
如果你真的把這個Attention的Matrix拿出來看,
link |
31:12.000
你會發現裡面有很多Redundant的Color,
link |
31:17.000
那在這個例子裡面,
link |
31:18.000
我是特別畫很多Color的Value都是一樣的,
link |
31:21.000
告訴你說,
link |
31:22.000
很多Color其實都是重複的。
link |
31:25.000
那在林峰的那篇Paper裡面,
link |
31:27.000
他做的事情是,
link |
31:28.000
他去計算這個Attention Matrix的Rank,
link |
31:31.000
那他告訴你說,
link |
31:32.000
這些Attention的Matrix其實都是LowRank的Matrix,
link |
31:37.000
也就是說,
link |
31:38.000
這個Attention的Matrix很多Color都是Dependent的,
link |
31:42.000
很多Color可能是其他Color做Duplicate,
link |
31:45.000
或是其他Color的Linear Combination。
link |
31:48.000
從這個角度說起來,
link |
31:50.000
也許我們根本不需要一個N乘以N的Matrix,
link |
31:53.000
因為這個N乘以N的Matrix裡面,
link |
31:55.000
很多資訊都是重複的。
link |
31:58.000
那我們能不能夠把某一些重複的Color就把它拿掉,
link |
32:03.000
產生一個比較小的Attention Matrix,
link |
32:06.000
我們只計算這個比較小的Attention Matrix,
link |
32:09.000
那我們就可以加快Attention這件事情的運算速度。
link |
32:13.000
那這個就是Link Format這篇Paper要做的事情。
link |
32:17.000
那實際上你要怎麼做呢?
link |
32:20.000
實際上你的做法是這樣的,
link |
32:22.000
本來有N個Key,
link |
32:25.000
我們從這N個Key裡面,
link |
32:28.000
只挑大K的出來,
link |
32:30.000
當作Key的代表。
link |
32:33.000
所有的Key,
link |
32:34.000
每一個都拿來跟Query計算的Attention太多了,
link |
32:37.000
很多Key,
link |
32:38.000
他們都是很像的,
link |
32:39.000
都做重複的事情,
link |
32:41.000
他們只是種源,
link |
32:42.000
也許我們只需要選最具代表性的K跟Key出來就好了。
link |
32:46.000
那至於怎麼選,
link |
32:47.000
我們會在下一頁投影片提到。
link |
32:49.000
反正你現在就知道說,
link |
32:51.000
K跟N的Key,
link |
32:52.000
不要全部都用,
link |
32:53.000
只挑有代表性的Key出來就好了。
link |
32:57.000
那只挑有代表性的Key出來以後,
link |
32:59.000
你就不需要算一個完整的N乘以N的Attention Matrix了,
link |
33:04.000
你就可以把這個Attention的Matrix變瘦,
link |
33:07.000
我們只算一個N乘以K的Attention Matrix。
link |
33:12.000
那產生這個Attention Matrix以後,
link |
33:15.000
接下來你要怎麼用這個Attention Matrix,
link |
33:18.000
產生Self-Attention Layer的Output呢?
link |
33:21.000
你的做法是這個樣子的。
link |
33:22.000
你有N個Value,
link |
33:24.000
你一樣要挑出K個具代表性的Value。
link |
33:30.000
所以這邊有K個Key,
link |
33:32.000
每一個Key其實都有一個對應的Value Vector,
link |
33:36.000
你有K個Key Vector,
link |
33:37.000
但你有K個Value Vector。
link |
33:40.000
然後接下來呢,
link |
33:41.000
你把K個Key對第一個Query Vector算出來的Attention Weight,
link |
33:47.000
對這K個Vector做Weighted Sum,
link |
33:50.000
得到第一個位置的Output。
link |
33:52.000
同比,
link |
33:53.000
把這四個Value再跟K個Vector,
link |
33:58.000
這邊的K等於4啦,
link |
34:00.000
把這K個Value跟這四個Vector再做Weighted Sum,
link |
34:04.000
得到第二個位置的Output。
link |
34:06.000
以此類推,
link |
34:07.000
你就可以得到整個Self-Attention Module的Output。
link |
34:11.000
講到這邊,
link |
34:13.000
大家可能會想到一個問題,
link |
34:16.000
為什麼我們只選有代表性的Key?
link |
34:20.000
為什麼我們不選有代表性的Query呢?
link |
34:26.000
我們可以把Key的數目從N變到K,
link |
34:30.000
我們為什麼不能把Query的數目也變成另外一個數值,
link |
34:35.000
比如說也是大K好了?
link |
34:37.000
那這樣子我們的Attention Matrix不是變得更小,
link |
34:40.000
這樣計算起來不是會更快嗎?
link |
34:44.000
不知道大家有沒有想過這樣子的問題。
link |
34:49.000
你確實也可以把Query的數目變少,
link |
34:53.000
你確實也可以只選有代表性的Query,
link |
34:58.000
但是你想想看,
link |
35:00.000
假如你只選有代表性的Query,
link |
35:02.000
你會遇到什麼問題?
link |
35:04.000
你會遇到你的Output Sequence的Length就縮短了對不對?
link |
35:08.000
因為你Output Sequence的Length跟你的Query的Length是一樣的。
link |
35:12.000
如果你的Query變成原來的一半,
link |
35:14.000
那你Output Sequence就變成原來的一半。
link |
35:16.000
那變成原來的一半會不會有影響呢?
link |
35:19.000
那就是Case by Case。
link |
35:21.000
有些任務是讀一整個Sequence,
link |
35:24.000
然後只產生一個Class,
link |
35:27.000
那就是大家在作業裡面做的Speaker Classification,
link |
35:31.000
那就是Input一整段句子,
link |
35:33.000
你只需要輸出一個Label。
link |
35:35.000
像這樣子的任務就無妨,
link |
35:37.000
你真的可以把你的Query變少,
link |
35:39.000
你真的可以選有代表性的Query出來就好了。
link |
35:42.000
但是假設你今天的任務是Input Sequence裡面的每一個位置,
link |
35:47.000
你都需要Output一個Label,
link |
35:49.000
像我們在作業2裡面做的Phoning的Classification,
link |
35:53.000
就是每一個Friend你都要給他一個Phoning的Label。
link |
35:56.000
假設你今天Output的長度變短了,
link |
35:58.000
那你的Label的數目不就有錯了嗎?
link |
36:01.000
那這樣會有問題。
link |
36:02.000
所以假設你今天你需要每一個位置都下一個Label,
link |
36:06.000
每一個位置都做一遍Classification給他一個Label,
link |
36:09.000
那你其實沒有辦法把Query變少,
link |
36:12.000
你沒有辦法只選有代表性的Query出來。
link |
36:18.000
好,那接下來要講的就是,
link |
36:20.000
怎麼選出有代表性的Key呢?
link |
36:24.000
我們說要選有代表性的Key嘛,
link |
36:26.000
怎麼選呢?那就有不同的做法。
link |
36:28.000
有一篇Paper叫做Compress Attention,
link |
36:30.000
他做的事情是說,你Input很多的很長的一個Key的Sequence,
link |
36:37.000
那我們用CNN來掃過它。
link |
36:40.000
那你用CNN來掃過一個Sequence以後,
link |
36:43.000
這個Sequence的長度就變短了,
link |
36:45.000
那這個短的Sequence就當作是有代表性的Key。
link |
36:50.000
所以我們可以用CNN來把一個長的Sequence變成短的Sequence,
link |
36:54.000
那把短的Sequence當作有代表性的Key。
link |
36:57.000
那另外一個是Link Form的這篇Paper裡面的做法,
link |
37:01.000
他說Input的這些Key集合起來,
link |
37:06.000
可以看作是一個D乘以N的矩陣。
link |
37:10.000
那把這個D乘以N的矩陣去乘一個N乘以K的矩陣,
link |
37:16.000
把D乘以N的矩陣乘上N乘以K的矩陣,
link |
37:19.000
會得到一個D乘以K的矩陣。
link |
37:22.000
那這個D乘以K的矩陣,
link |
37:24.000
它的每一個Column,它的K個Column,
link |
37:27.000
就是K個有代表性的Key。
link |
37:31.000
那如果你熟悉線性代數的話,
link |
37:33.000
你會知道說,把這個D乘以N的矩陣乘上這個N乘以K的矩陣,
link |
37:37.000
得到D乘以K的矩陣,
link |
37:39.000
你實際上做的事情是什麼?
link |
37:41.000
你實際上做的事情是,這邊這K個Vector,
link |
37:44.000
都是這N個Vector的Linear Combination。
link |
37:48.000
你把這N個Vector做不同的Linear Combination,
link |
37:51.000
做K種不同的Linear Combination,
link |
37:54.000
就得到這K個Vector。
link |
37:57.000
所以可以說,如果你從Link Forward的時候,
link |
37:59.000
所謂K個有代表性的Vector,
link |
38:01.000
就是把原來大N個Vector裡面,
link |
38:04.000
把這些大N個Vector,
link |
38:06.000
做不同方式的Linear Combination,
link |
38:08.000
那就產生K個有代表性的Key,
link |
38:12.000
然後你就可以減少你的運算量。
link |
38:15.000
這個就是Link Forward在做的事情。
link |
38:20.000
好,那接下來,我們再回頭想一下,
link |
38:25.000
其實Attention的整個Process,
link |
38:28.000
它其實說穿了,就是一連串矩陣的相乘。
link |
38:32.000
那這個矩陣相乘的過程中,
link |
38:35.000
有沒有可以減少運算量的部分呢?
link |
38:38.000
那我們來複習一下,
link |
38:40.000
Attention這一個Mechanism,
link |
38:42.000
跟矩陣相乘的關係。
link |
38:44.000
而假設Input,我們當作一個Matrix叫做I。
link |
38:49.000
我們會把I這個大I這個Matrix,
link |
38:51.000
乘上一個Linear Transform,
link |
38:53.000
得到另外一個Matrix叫做Q。
link |
38:57.000
Q的大小是D乘以N。
link |
39:00.000
Q是一個D乘以N的Matrix,
link |
39:02.000
N是Sequence的長度,
link |
39:04.000
D是你的Query Vector的Dimension。
link |
39:07.000
那同樣的道理,I乘以另外一個Transform,
link |
39:11.000
叫WK,會得到我們的Key。
link |
39:13.000
所有的Key集合起來,
link |
39:15.000
一樣是一個D乘以N的Matrix。
link |
39:17.000
把I乘上另外一個Transform,
link |
39:19.000
得到大V,
link |
39:20.000
這個大V這個矩陣呢,
link |
39:22.000
它是一個Dπ乘以N的矩陣。
link |
39:25.000
那把所有的Value Vector集合起來,
link |
39:27.000
它是一個Dπ乘以N的矩陣。
link |
39:30.000
那這個Q跟K啊,
link |
39:31.000
它們的Dimension必須要一樣啦,
link |
39:33.000
這樣它們才能夠做大發達嘛,
link |
39:34.000
Dimension不一樣不能做大發達。
link |
39:36.000
但是V的Dimension,
link |
39:37.000
不一定要跟Q跟K一樣。
link |
39:39.000
所以你一般在實作的時候,
link |
39:41.000
你會直接就把它們Dimension設成一樣,
link |
39:43.000
但是不一樣也沒有關係。
link |
39:46.000
所以我這邊呢,
link |
39:47.000
特別說Value的Vector是Dπ,
link |
39:50.000
Q跟K,
link |
39:51.000
Query跟Key的這個Dimension都是D,
link |
39:54.000
但Value的Vector是Dπ。
link |
39:56.000
Dπ也可以等於D,
link |
39:57.000
但沒有必要,
link |
39:58.000
一定要等於D。
link |
39:59.000
好,那接下來呢,
link |
40:01.000
接下來呢,
link |
40:02.000
你會把Key乘以一個Transpose,
link |
40:04.000
跟Q相乘,
link |
40:05.000
得到一個Attention的Matrix,
link |
40:08.000
叫做A。
link |
40:09.000
然後接下來呢,
link |
40:11.000
你會做Softmax,
link |
40:12.000
得到A',
link |
40:13.000
接下來你把A'乘上V,
link |
40:16.000
得到Output O。
link |
40:18.000
所以整個Attention的Mechanism,
link |
40:20.000
就是Input一個Sequence表示成I,
link |
40:23.000
Output另外一個Sequence表示成O,
link |
40:26.000
中間你會經過這一連串的運算。
link |
40:29.000
那有沒有辦法加速這個運算呢?
link |
40:32.000
其實是有辦法的。
link |
40:34.000
我們先做一個簡化,
link |
40:36.000
我們先假設我們沒有做Softmax這件事情。
link |
40:40.000
那如果拿掉Softmax,
link |
40:41.000
那你覺得不舒服的話,
link |
40:43.000
不要擔心,
link |
40:44.000
等一下會把它加回去。
link |
40:45.000
我們先假設沒有Softmax。
link |
40:48.000
那這一個A',
link |
40:50.000
這邊這個A',
link |
40:51.000
它就是K的Transpose乘上Q。
link |
40:54.000
所以其實做Attention這件事情,
link |
40:57.000
我們真正做的事情,
link |
40:59.000
就是把V跟K的Transpose跟Q,
link |
41:02.000
三個取得相乘,
link |
41:04.000
我們就得到Self-Attention Module的Output,
link |
41:07.000
也就是這邊的O。
link |
41:09.000
那這個Q是一個D乘以N的矩陣,
link |
41:13.000
這個K的Transpose是一個N乘以D的矩陣,
link |
41:16.000
本來K是D乘以N,
link |
41:17.000
Transpose以後就變成N乘以D。
link |
41:19.000
然後我們先把Q跟K的Transpose進行相乘以後,
link |
41:24.000
再乘上V這個矩陣,
link |
41:26.000
V這個矩陣的大角是D'乘以N,
link |
41:29.000
三個乘完以後,
link |
41:30.000
我們得到O,它就是一個D'乘以N的矩陣,
link |
41:34.000
這是Self-Attention做的事情。
link |
41:36.000
我們先把K的Transpose跟Q乘起來,
link |
41:39.000
再乘V,最後得到O。
link |
41:42.000
那這整個過程其實是可以加速的。
link |
41:47.000
怎麼加速呢?
link |
41:48.000
先把V跟K的Transpose相乘,
link |
41:52.000
再乘上Q。
link |
41:54.000
這兩件事情,
link |
41:55.000
你可能覺得它們是一樣的,
link |
41:58.000
它們確實乘出來的結果O會是一樣的,
link |
42:02.000
但是中間需要的運算量不是一樣的。
link |
42:07.000
同樣是V乘以K的Transpose乘以Q,
link |
42:11.000
先把K的Transpose乘Q再乘V,
link |
42:13.000
跟先把V乘以K的Transpose再乘Q,
link |
42:16.000
雖然得到的結果是一樣的,
link |
42:18.000
但是所需的運算量不是一樣的。
link |
42:23.000
這件事情,
link |
42:24.000
如果你有修過我的線性代數的話,
link |
42:26.000
我們在線性代數這門課有跟大家講過,
link |
42:29.000
你把A跟C跟P三個矩陣相乘,
link |
42:32.000
你不管是先把C跟P相乘,
link |
42:34.000
變成CP就是一個Couple,
link |
42:37.000
再乘A,
link |
42:38.000
還是先把AC相乘再乘P,
link |
42:40.000
它們的結果是一樣的,
link |
42:43.000
但是運算量是不一樣的。
link |
42:46.000
如果你沒有修過我的線性代數也沒有關係,
link |
42:49.000
我們直接跟大家說明,
link |
42:52.000
用V乘以K乘以Q的例子跟大家說明。
link |
42:55.000
如果我們先把K的乘透乘Q,
link |
42:58.000
我們需要做多少次的矩陣乘法呢?
link |
43:02.000
需要做N乘以D乘以N次。
link |
43:05.000
那如果你是太久以前修線性代數,
link |
43:08.000
一下子想不起來矩陣乘法怎麼做的話,
link |
43:10.000
你就記得這個原則是這樣。
link |
43:12.000
這邊把N乘以D的矩陣乘上D乘以N的矩陣,
link |
43:16.000
需要做多少次乘法呢?
link |
43:18.000
就是N乘以D乘以N,
link |
43:20.000
就是第一個矩陣的RAW的數目乘上第一個矩陣的COLUMN的數目乘上第二個矩陣的COLUMN的數目。
link |
43:31.000
把這三個東西乘起來,
link |
43:33.000
就是把兩個矩陣相乘的時候需要做的乘法次數。
link |
43:38.000
所以把K的乘透乘Q需要做幾次乘法?
link |
43:41.000
需要做N乘以D乘以N次的乘法。
link |
43:45.000
把這兩個乘起來以後,
link |
43:47.000
你得到一個N乘以N的矩陣,
link |
43:50.000
就是我們的Attention Matrix。
link |
43:52.000
把Attention Matrix再乘上V,
link |
43:54.000
V是一個D'乘以N的矩陣,
link |
43:56.000
需要幾次乘法呢?
link |
43:58.000
用剛才那個原則,
link |
44:00.000
兩個矩陣相乘的時候乘法的次數,
link |
44:02.000
就是第一個矩陣的RAW的數目乘COLUMN的數目再乘第二個矩陣的COLUMN的數目。
link |
44:08.000
所以今天這個例子裡面,
link |
44:10.000
V乘以A的時候乘法的次數是D'乘以N乘以N。
link |
44:15.000
那我們把所有的乘法的次數加起來,
link |
44:18.000
N乘以D乘以N,D'乘以N乘以N,
link |
44:21.000
全部加起來是D加D'乘以N平方。
link |
44:25.000
所以你要做,
link |
44:26.000
你的這個乘法的次數跟N平方是乘正比的。
link |
44:32.000
那如果我們今天交換一下乘法的順序會變成怎樣呢?
link |
44:36.000
矩陣相乘的順序會變成怎樣呢?
link |
44:38.000
我們把V先乘上K的乘透。
link |
44:42.000
把V乘上K的乘透需要的乘法的次數是D'乘以N乘以D。
link |
44:48.000
那把這個V乘以K的乘透以後,
link |
44:51.000
它會變成什麼東西呢?
link |
44:53.000
它變成一個D'乘以D的矩陣。
link |
44:56.000
我們一時看不出來它代表什麼東西,
link |
44:59.000
不像是Q跟K相乘,
link |
45:00.000
非常直覺是一個attention的matrix。
link |
45:03.000
V乘以K的乘透,
link |
45:04.000
一時之間我們看不出來是什麼東西,
link |
45:07.000
不過沒關係,
link |
45:08.000
反正它就是一個D'乘以D的矩陣。
link |
45:11.000
把D'乘以D的矩陣再乘上Q,
link |
45:14.000
Q是D乘以N的矩陣,
link |
45:15.000
需要多少的乘法呢?
link |
45:18.000
需要D'乘以D乘以N次的乘法。
link |
45:21.000
所以合起來,
link |
45:22.000
當你把V乘以K的時候,
link |
45:24.000
你需要D'乘以N乘以D。
link |
45:26.000
那你再把V乘以K的結果再乘以Q,
link |
45:29.000
你需要D'乘以D乘以N次的乘法。
link |
45:32.000
合起來,
link |
45:33.000
這是兩倍的D'乘以D乘以N次的乘法。
link |
45:37.000
所以你發現說當我們改變矩陣相乘的順序的時候,
link |
45:41.000
其實我們需要的乘法的次數是有很大的差距的。
link |
45:46.000
如果Q跟K先相乘,
link |
45:48.000
這個時候我們得到這個O的乘法次數是D加D'乘以N平方。
link |
45:55.000
V跟K先相乘,
link |
45:57.000
是兩倍的D'乘以D乘以N。
link |
46:00.000
而如果把Q跟V先相乘,
link |
46:03.000
我們需要的乘法的次數是遠大於V跟K先相乘的。
link |
46:10.000
因為N往往比D還要大很多,
link |
46:13.000
不要忘了這個N是sequence的長度,
link |
46:17.000
它可以是一個非常大的數字,
link |
46:19.000
所以D加D'的N平方可能會遠大於兩倍的D'乘以D乘以N。
link |
46:26.000
所以其實我們只要改變矩陣相乘的順序,
link |
46:32.000
我們的結果可能就會有很大的不同。
link |
46:37.000
講到這邊,
link |
46:39.000
如果你沒有那麼喜歡看到數學的notation的話,
link |
46:44.000
講到這邊你可以當作你已經知道我要講的東西是什麼了,
link |
46:48.000
我們只是改變一下矩陣相乘的順序。
link |
46:51.000
但是假設你對這個結果還是有困惑,
link |
46:55.000
因為你覺得拿掉softmax讓你覺得有點不爽的話,
link |
46:59.000
接下來告訴你放回softmax是怎麼樣運作的。
link |
47:04.000
以下數學符號比較多,
link |
47:06.000
如果你不想聽的話,
link |
47:07.000
你也可以把這一段跳過。
link |
47:10.000
原來的self-attention是怎麼被計算的?
link |
47:15.000
原來self-attention是說,
link |
47:17.000
如果要計算input sequence是A1到A4,
link |
47:23.000
如果你要計算第一個位置的輸出B1的話,
link |
47:26.000
你會把第一個位置的query Q1,
link |
47:30.000
跟所有位置的key算個attention,
link |
47:34.000
得到這邊的alpha prime,
link |
47:36.000
再把alpha prime跟每一個位置的value vector,
link |
47:40.000
所有位置上就得到B1。
link |
47:43.000
所以B1是summation over i等於1到n,
link |
47:48.000
然後把alpha 1i prime,就是Q1跟每一個key的attention的value,
link |
47:58.000
這是有經過softmax normalize以後的value,
link |
48:01.000
然後把這些value對V1做weighted sum得到B1。
link |
48:08.000
那這一項alpha,
link |
48:10.000
如果你想要把它的計算過程算出來的話,
link |
48:13.000
其實是這個樣子的,
link |
48:14.000
看起來有點複雜,
link |
48:16.000
它是分子的地方是Q1跟Ki做大quota,
link |
48:23.000
然後再去exponential。
link |
48:25.000
分母的地方呢?
link |
48:26.000
分母的地方是summation over整個sequence,
link |
48:29.000
把Q1對整個sequence裡面所有的key,
link |
48:32.000
都做大quota,成exponential,
link |
48:35.000
相加以後放在分母,
link |
48:37.000
分子的地方是Q1跟某一項key,
link |
48:39.000
做大quota,去exponential,
link |
48:41.000
然後再對Vi做weighted sum。
link |
48:44.000
這些是原來的self-attention的計算過程。
link |
48:49.000
接下來就是要告訴你,
link |
48:51.000
實際上這個計算過程是可以被簡化的。
link |
48:56.000
首先exponential Q跟K的大quota,
link |
49:01.000
可以拆解成phiQ跟phiK的大quota。
link |
49:06.000
什麼是phiQ,什麼是phiK呢?
link |
49:08.000
你就想成說,
link |
49:09.000
你有一個transform叫做phi,
link |
49:11.000
把Q這個vector輸進去,
link |
49:13.000
他會給你另外一個vector叫做phiQ。
link |
49:17.000
那你把Q跟K都輸入這個phi,
link |
49:19.000
得到phiQ跟phiK兩個vector,
link |
49:21.000
把這兩個vector做大quota,
link |
49:23.000
會等於Q跟K先做大quota,
link |
49:26.000
再做exponential。
link |
49:28.000
那有人可能會問說,
link |
49:29.000
這個phi是什麼呢?
link |
49:32.000
我們先不要在意這個細節,
link |
49:34.000
反正有這麼一個神奇的phi,
link |
49:36.000
就是可以讓exponential Q跟K的大quota,
link |
49:39.000
等於phiQ跟phiK的大quota。
link |
49:43.000
好了,有了這個,
link |
49:44.000
知道這些事情以後呢,
link |
49:46.000
你就可以把這邊所有的exponential,
link |
49:48.000
exponential Q1Ki的大quota,
link |
49:51.000
換成phiQ1到phiKi,
link |
49:53.000
exponential Q1Kj的大quota,
link |
49:55.000
換成phiQ1到phiKj。
link |
50:00.000
那接下來呢,
link |
50:01.000
我們就來稍微做一下整理,
link |
50:04.000
我們先來看這邊分母這項。
link |
50:07.000
這邊有一個summation over i等於1到n,
link |
50:11.000
但是分母這項其實是沒有出現i的,
link |
50:14.000
分母這項沒有出現i,
link |
50:16.000
所以可以把它拿到summation i等於1到n的外面。
link |
50:20.000
所以呢,我們這個式子變成這個樣子,
link |
50:22.000
分母的地方是summation j等於1到n,
link |
50:25.000
phiQ1到phiKj的總和,
link |
50:29.000
分子的地方是summation i等於1到n,
link |
50:32.000
那summation i等於1到n的時候,
link |
50:35.000
我們會對phi做weighted sum,
link |
50:37.000
那這個weight是什麼?
link |
50:39.000
這個weight是phiQ1跟phiKi的大quota。
link |
50:45.000
好,那我們先來看分母的地方,
link |
50:47.000
分子的地方比較tricky啊,
link |
50:49.000
我們先來看分母的地方。
link |
50:51.000
分母的地方其實很單純,
link |
50:52.000
我們這邊summation j等於1到n,
link |
50:55.000
phiQ1到phiKj,
link |
50:57.000
你會發現phiQ1其實跟j沒有關係,
link |
51:00.000
所以phiQ1是可以提出來的。
link |
51:03.000
所以分母的地方,
link |
51:05.000
實際上是你把phiQ1跟phiKj
link |
51:09.000
summation j等於1到n,
link |
51:11.000
把這n個phiKj加起來以後,
link |
51:14.000
一次去跟phiQ1做大quota。
link |
51:17.000
或者是,如果你要圖像化的表示的話,
link |
51:20.000
就是把phiKj,
link |
51:22.000
summation j等於1到n的phiKj啊,
link |
51:26.000
統統加起來,變成一個vector。
link |
51:29.000
然後去跟phiQ1做大quota,
link |
51:33.000
就等於這一項分母的地方。
link |
51:37.000
好,分母的地方是很簡單的,
link |
51:40.000
再來是分子的地方。
link |
51:43.000
分子的地方我們來計算一下,
link |
51:46.000
分子的地方我們特別把它拿出來,
link |
51:48.000
就是在這個藍色的框框裡面,
link |
51:50.000
它是vi的weighted sum,
link |
51:52.000
那weight就是phiQi跟phiKi的大quota。
link |
51:57.000
所以如果你把它展開的話,
link |
51:59.000
希望展開讓你比較好理解一點,
link |
52:01.000
展開的話,就是phiQ1.phiK1乘以v1,
link |
52:05.000
但phiQ1.phiK1這個是一個scalar哦,
link |
52:08.000
綜合號裡面是一個數值,
link |
52:10.000
這個weight是一個數值,乘上v1,
link |
52:13.000
加上phiQ1.phiK2乘上v2,
link |
52:16.000
一次類推,一直加到vN。
link |
52:21.000
那接下來呢,
link |
52:23.000
phiQ1這個項量,
link |
52:27.000
我們把它裡面每一個component展開的話,
link |
52:32.000
呈現出來用notation來表示的話,
link |
52:35.000
我們把phiQ1表示成Q上標1下標1,
link |
52:39.000
第二個component就是Q上標1下標2,
link |
52:42.000
同理phiK1是K上標1下標1,
link |
52:45.000
K上標1下標2。
link |
52:48.000
所以呢,我們phiQ1到phiK1,
link |
52:53.000
你把它展開以後,
link |
52:55.000
phiQ1到phiK1,
link |
52:57.000
它是Q1.1乘K1.1,
link |
53:00.000
加上Q1.2乘以K1.2,
link |
53:02.000
Q1.1乘以K1.1,
link |
53:04.000
加Q1.2乘以K1.2,
link |
53:06.000
一路加起來,
link |
53:08.000
看這邊有幾個element,
link |
53:10.000
看這邊有幾個element,
link |
53:11.000
把它加起來,再乘以v1。
link |
53:13.000
第二項也是一樣,
link |
53:15.000
接下來把它展開,
link |
53:18.000
這邊都不是什麼複雜的數學,
link |
53:19.000
只是很繁瑣而已,
link |
53:20.000
把v1乘上這裡面的每一項,
link |
53:23.000
把v2乘上這裡面的每一項。
link |
53:26.000
接下來是關鍵的一步,
link |
53:29.000
我們把乘上Q1.1的項集合起來,
link |
53:34.000
把乘上Q1.2的項集合起來,
link |
53:38.000
所以我們就會得到這樣的式子,
link |
53:41.000
所以上面這件事情,
link |
53:45.000
這個v1的分子的地方,
link |
53:47.000
可以寫成Q1.1乘上,
link |
53:50.000
這邊有個括號,
link |
53:51.000
裡面是v1,v2,
link |
53:53.000
一直到vn的weight,
link |
53:55.000
他們的weight是多少?
link |
53:56.000
他們的weight是K1.1,
link |
53:58.000
K2.1,K3.1,
link |
54:00.000
以此類推。
link |
54:01.000
所以這個分子的地方,
link |
54:04.000
你可以寫成Q1.1乘上
link |
54:06.000
v1到vn的linear combination,
link |
54:09.000
加上Q1.2乘上v1到vn的
link |
54:12.000
另外一組linear combination。
link |
54:17.000
好,我們現在假設
link |
54:18.000
你可以接受這件事情以後,
link |
54:20.000
那這整件事情實際上可以看作是
link |
54:24.000
一個矩陣跟一個向量的相乘,
link |
54:27.000
我們把括號裡面的東西
link |
54:29.000
當作是一個向量,
link |
54:31.000
括號裡面的東西
link |
54:33.000
就是v1到vn的weighted sum,
link |
54:36.000
那你把v1到vn用另外一組weight
link |
54:39.000
做weighted sum,
link |
54:40.000
你得到另外一個向量。
link |
54:42.000
這邊會有幾個向量呢?
link |
54:44.000
有人可能會很直覺的說
link |
54:46.000
是不是大N個向量,
link |
54:49.000
N是sequence的長度,
link |
54:51.000
但其實不是,
link |
54:53.000
他是看5Q1的dimension的。
link |
54:57.000
括號前面不是Q1.1,Q1.2嗎?
link |
55:00.000
那到底會有幾個括號?
link |
55:03.000
其實就是看5Q1的dimension有多少。
link |
55:07.000
所以假設5Q1的dimension是大N的話,
link |
55:11.000
這邊就是有大N個括號,
link |
55:14.000
所以這邊就是有大N個vector。
link |
55:18.000
那這每一個vector都乘上一個weight,
link |
55:21.000
這個weight是Q1.1,Q1.2,
link |
55:24.000
一直到Q1.N,
link |
55:26.000
如果5Q1有N個dimension的話。
link |
55:29.000
所以你可以把上面這個式子
link |
55:33.000
看成是一個矩陣,
link |
55:35.000
這個矩陣的每一個vector,
link |
55:37.000
括號裡面的每一個vector,
link |
55:39.000
他們是第一個value vector的linear combination,
link |
55:42.000
然後乘上5Q1。
link |
55:45.000
如果你覺得這個聽起來很複雜,
link |
55:50.000
不知道在講些什麼呢?
link |
55:51.000
那我們用圖像化的方式
link |
55:53.000
來表示一下我剛才做的事情。
link |
55:55.000
所以實際上分子的地方做的事情是什麼呢?
link |
55:58.000
實際上分子的地方做的事情是
link |
56:00.000
你先把你所有的value vector拿出來,
link |
56:04.000
你有大N個value vector,
link |
56:07.000
value vector的數目
link |
56:09.000
跟input sequence的長度是一樣的。
link |
56:13.000
然後你把你的大N個key都拿出來,
link |
56:20.000
然後把他們通過find這個function
link |
56:22.000
一樣得到大N個向量。
link |
56:26.000
接下來我們把這些向量的
link |
56:30.000
第一個element都拿出來,
link |
56:33.000
把這些向量的第一個element都拿出來,
link |
56:36.000
對value vector,
link |
56:38.000
對大N個value vector做weighted sum,
link |
56:41.000
就得到這一個矩陣裡面的第一個vector。
link |
56:45.000
然後把這些5K的第二個element拿出來,
link |
56:52.000
這邊有N個vector,
link |
56:54.000
所以他們的第二個element總共有N個數值。
link |
56:56.000
把這第二個element拿出來,
link |
56:59.000
對V1到VN做weighted sum,
link |
57:01.000
你就得到這邊的第二個vector一次類推。
link |
57:04.000
那如果5K的dimension是大N的話,
link |
57:08.000
這邊就會有大N個vector。
link |
57:11.000
那再把這大N個vector排起來,
link |
57:15.000
當作是一個matrix乘上5Q1,
link |
57:18.000
你就得到V1的分子增加。
link |
57:21.000
那再把分母算出來,
link |
57:24.000
你就得到V1的值是多少了。
link |
57:27.000
那講到這邊,你可能覺得這聽起來
link |
57:30.000
就只是比較複雜的數學運算跟notation而已,
link |
57:34.000
跟原來的計算好像沒有什麼不同。
link |
57:38.000
但他真正的關鍵點在於,
link |
57:40.000
你看看喔,
link |
57:42.000
我們在計算第一個位置的output的時候,
link |
57:45.000
跟第一個位置有關的只有query的vector而已。
link |
57:50.000
而這個藍色的向量所組成的矩陣,
link |
57:54.000
還有放在分母的地方的這個黃色的向量,
link |
57:57.000
他們其實跟位置,
link |
58:00.000
其實跟V1的這個1是沒有任何關係的。
link |
58:04.000
所以假設你在計算V1的時候,
link |
58:07.000
你已經把這些藍色的vector,
link |
58:10.000
還有把這個黃色的vector求出來,
link |
58:12.000
接下來你就不需要再重算了。
link |
58:15.000
當你把V1算出來以後,
link |
58:18.000
接下來你要算V2,
link |
58:20.000
你只需要把這些藍色的vector複製過來,
link |
58:23.000
把黃色的vector複製過來,
link |
58:25.000
再乘上findQ2,你就計算出V2了。
link |
58:29.000
所以這個藍色的vector跟黃色的vector,
link |
58:32.000
只需要計算一次就好。
link |
58:35.000
接下來不同的位置,
link |
58:37.000
就是乘上不同的findQ,
link |
58:40.000
你就得到不同的V,
link |
58:42.000
得到不同位置的輸出。
link |
58:45.000
假設你剛才講的東西,
link |
58:50.000
你沒有聽得很懂的話,
link |
58:52.000
接下來就是要告訴你說,
link |
58:54.000
其實self-attention,
link |
58:56.000
可以用另外一個方法來看待。
link |
58:59.000
而這個計算的方法,
link |
59:01.000
跟原來的self-attention,
link |
59:03.000
計算出來的結果是一模一樣的,
link |
59:06.000
只是他的運算量是比較少的。
link |
59:10.000
如果剛才講的東西你沒有聽懂的話,
link |
59:12.000
直接告訴你這件事怎麼操作。
link |
59:15.000
他操作起來是這個樣子的,
link |
59:17.000
我們input是一個sequence A1到A4,
link |
59:21.000
每一個input的位置都產生K跟V,
link |
59:25.000
先產生K跟V。
link |
59:27.000
我們先讓K跟V來做一些互動,
link |
59:31.000
做什麼樣的互動呢?
link |
59:33.000
你先把K都通過一個transform,
link |
59:37.000
變成5K1,5K2,一直到5K4。
link |
59:42.000
然後你把這些5K的第一個位置,
link |
59:48.000
第一個dimension的element拿出來,
link |
59:52.000
對V1到V4做weighted sum,
link |
59:56.000
得到一個項量。
link |
59:57.000
你把5K1到5K4的第二個位置的,
link |
01:00:01.000
第二個dimension的element拿出來,
link |
01:00:04.000
然後把這邊每一個綠色的位置,
link |
01:00:07.000
每一個綠色的這個位置的數值,
link |
01:00:10.000
去跟V1、V2、V3、V4做weighted sum,
link |
01:00:14.000
得到另外一個vector。
link |
01:00:16.000
反覆這個動作,你就看說,
link |
01:00:18.000
你這個5K有多少的dimension,
link |
01:00:20.000
假設M的dimension,
link |
01:00:22.000
那你就產生M的vector,
link |
01:00:24.000
那每一個dimension都會產生一個vector出來,
link |
01:00:27.000
每一個dimension都會產生一個vector出來,
link |
01:00:30.000
有M的dimension就產生M的vector。
link |
01:00:34.000
好,那這件事情只需要做一次,
link |
01:00:39.000
在process整個sequence的時候,
link |
01:00:41.000
只需要做一次,接下來就一勞永逸。
link |
01:00:45.000
怎麼一勞永逸呢?
link |
01:00:46.000
假設你要產生第一個位置的輸出,
link |
01:00:49.000
怎麼辦?
link |
01:00:50.000
先把Q1產生出來,
link |
01:00:52.000
Q1要通過一個transform變成5Q1,
link |
01:00:56.000
接下來把5Q1的第一個dimension
link |
01:01:00.000
乘上第一個vector,
link |
01:01:02.000
第二個dimension乘上第二個vector,
link |
01:01:05.000
但這邊要確保說,
link |
01:01:07.000
Q跟K他們通過這個transform,
link |
01:01:09.000
5以後他們的dimension是一模一樣的,
link |
01:01:11.000
都是M,
link |
01:01:12.000
那你才能把Q的每一個element
link |
01:01:14.000
乘上這邊的每一個vector,
link |
01:01:17.000
所以Q有M個value在他的vector裡面,
link |
01:01:21.000
把這M個value乘上這M個vector
link |
01:01:24.000
做weighted sum,
link |
01:01:26.000
你就得到B1就結束了。
link |
01:01:29.000
其實精確的來說,
link |
01:01:31.000
是得到B1的分子這一項啦,
link |
01:01:33.000
那分母這一項其實也是非常類似的概念,
link |
01:01:36.000
我們就不幫大家剖析,
link |
01:01:38.000
總之你把5Q1跟這M個vector
link |
01:01:41.000
做weighted sum,
link |
01:01:42.000
然後你就可以把B1的分子這一項算出來,
link |
01:01:46.000
那分母這一項算的方法也是類似,
link |
01:01:49.000
而且更簡單,
link |
01:01:50.000
這樣你就求出B1了。
link |
01:01:53.000
接下來要求B2的話,
link |
01:01:55.000
怎麼做呢?
link |
01:01:56.000
這M個vector你不要重算了,
link |
01:01:59.000
他們是全部的位置都共用的,
link |
01:02:02.000
他們就放在那邊,
link |
01:02:03.000
你就不要再去動它了,
link |
01:02:05.000
當你要算第二個位置的時候,
link |
01:02:07.000
怎麼做呢?
link |
01:02:08.000
你把Q2過一個transform得到5Q2,
link |
01:02:13.000
然後把5Q2的每一個dimension的value
link |
01:02:18.000
拿去對這M個vector做weighted sum,
link |
01:02:21.000
5Q2的第一個dimension乘上第一個vector,
link |
01:02:24.000
第二個dimension乘上第二個vector,
link |
01:02:26.000
有M個dimension正好乘M個vector,
link |
01:02:29.000
加起來你就得到B2了。
link |
01:02:31.000
其實精確的說是B2的分子那一項,
link |
01:02:34.000
那分母那一項的計算是更簡單的。
link |
01:02:37.000
所以用這個方法,
link |
01:02:38.000
你就先把M個vector算出來以後,
link |
01:02:41.000
接下來就是一勞永逸,
link |
01:02:43.000
每一個位置都可以很快的被計算出來。
link |
01:02:47.000
如果你想要理解一下這個東西有什麼意思的話,
link |
01:02:52.000
也許可以這樣理解。
link |
01:02:53.000
之前做self-attention非常的直觀,
link |
01:02:56.000
你可以說我們就是要找哪一個位置跟哪一個位置有關聯,
link |
01:03:00.000
算出一個attention,
link |
01:03:01.000
然後從那個位置抽資訊出來。
link |
01:03:03.000
如果你要理解這種新的做法,
link |
01:03:05.000
這邊要強調一下這個做法跟一般的self-attention
link |
01:03:08.000
其實是一模一樣的,
link |
01:03:09.000
算出來的結果其實是一模一樣的,
link |
01:03:11.000
你只要選適當的fine,
link |
01:03:13.000
算出來的結果會是一樣的。
link |
01:03:15.000
那怎麼理解這個新的計算方法呢?
link |
01:03:18.000
也許可以這樣理解,
link |
01:03:19.000
每一個位置都產生V,
link |
01:03:22.000
有V1到V4,
link |
01:03:23.000
然後我們把它做weighted sum,
link |
01:03:25.000
是要找尋重要的template,
link |
01:03:30.000
這整個sequence裡面總共有M個重要的template,
link |
01:03:35.000
然後接下來每一個位置的輸出,
link |
01:03:38.000
就是拿這些template做linear combination,
link |
01:03:41.000
那產生這個fineQ是要去這M個template裡面
link |
01:03:45.000
選擇適當的template,
link |
01:03:47.000
那這個template是整個sequence每一個位置都共用的,
link |
01:03:51.000
這M個template產生出來以後,
link |
01:03:53.000
它就放在那邊就不需要動它了,
link |
01:03:55.000
每一個位置選擇不同的template組合起來作為輸出。
link |
01:04:00.000
那如果你需要一個物理上的解釋的話,
link |
01:04:02.000
也許這是一個可以理解這種新的self-attention運算方法的概念。
link |
01:04:09.000
好,那接下來最後一個問題就是,
link |
01:04:14.000
那exponential Q.K怎麼拆解成fineQ.fineK呢?
link |
01:04:20.000
不同的paper就有不同的做法了,
link |
01:04:24.000
所以不管是efficient attention,
link |
01:04:26.000
linear transformer,
link |
01:04:28.000
random feature attention,
link |
01:04:29.000
還是performer,
link |
01:04:30.000
他們做的都是我剛才前幾個投影片跟你講的簡化,
link |
01:04:34.000
那不一樣的地方在哪裡呢?
link |
01:04:36.000
不一樣的地方就是怎麼把exponential Q.K拆成fineQ.fineK。
link |
01:04:42.000
那至於這個fine應該長什麼樣子,
link |
01:04:45.000
那就留給大家去細讀這些文獻。
link |
01:04:47.000
好,那接下來我們就可以再進一步思考,
link |
01:04:52.000
如果要產生self-attention,
link |
01:04:55.000
要做self-attention,
link |
01:04:57.000
一定要用Q跟K做inner product來產生attention嗎?
link |
01:05:02.000
不一定,
link |
01:05:03.000
你可以參考一個做法叫做synthesizer,
link |
01:05:07.000
synthesizer做法是這個樣子的,
link |
01:05:09.000
你要做self-attention,
link |
01:05:10.000
你的目標是input一個sequence,
link |
01:05:12.000
output另外一個sequence,
link |
01:05:14.000
那我們先把input的sequence每一個位置產生一個value vector,
link |
01:05:18.000
接下來跟一般的self-attention一樣,
link |
01:05:21.000
我們把這些value vector做weighted上,
link |
01:05:25.000
我們可以產生每一個位置的輸出,
link |
01:05:28.000
而這些value一樣是本來有一個attention的matrix,
link |
01:05:32.000
這個matrix做完softmax以後,
link |
01:05:34.000
可以得到normalized以後的value,
link |
01:05:36.000
normalized的value做weighted上,
link |
01:05:38.000
可以得到open,
link |
01:05:39.000
那跟一般的self-attention不一樣的地方是,
link |
01:05:42.000
在synthesizer裡面,
link |
01:05:44.000
這個matrix不是Q跟K產生的,
link |
01:05:48.000
在synthesizer裡面不需要Q跟K,
link |
01:05:52.000
那這個matrix怎麼來呢?
link |
01:05:54.000
其實在synthesizer裡面有兩個不同的版本,
link |
01:05:56.000
有一個版本跟那個synthome sorting level很像,
link |
01:05:59.000
他就是拿A1到A4去產生這個matrix,
link |
01:06:03.000
但是在synthesizer裡面,
link |
01:06:05.000
還有另外一個更神奇的版本就是,
link |
01:06:08.000
把這個matrix當作network的一部分,
link |
01:06:12.000
這個matrix裡面有n乘以n個數值對不對,
link |
01:06:17.000
這n乘以n個數值就是network裡面的n乘以n個參數,
link |
01:06:23.000
我們知道network裡面如果neuron有weight有bias嘛,
link |
01:06:26.000
現在多加了attention weight,
link |
01:06:29.000
attention weight是network的參數,
link |
01:06:31.000
這樣你在做self-attention的時候,
link |
01:06:34.000
你連計算attention weight這個步驟都免了,
link |
01:06:37.000
沒有計算attention weight這件事了,
link |
01:06:39.000
他本來就已經在network裡面了,
link |
01:06:42.000
他就是network的參數,
link |
01:06:45.000
那有可能會問說,
link |
01:06:46.000
如果attention weight是network的參數,
link |
01:06:48.000
那不是input不同的sequence,
link |
01:06:50.000
那個attention的weight都是一樣的嗎?
link |
01:06:53.000
對,
link |
01:06:54.000
那performance會變差嗎?
link |
01:06:55.000
不會,
link |
01:06:56.000
就這樣子,
link |
01:06:57.000
好,
link |
01:06:58.000
所以這個synthesizer讓我們重新思考,
link |
01:07:01.000
到底attention的價值是什麼,
link |
01:07:03.000
過去我們會覺得input不同的sequence,
link |
01:07:05.000
attention的matrix應該不一樣,
link |
01:07:07.000
但是當我們把attention的matrix
link |
01:07:10.000
作為network的參數一部分的時候,
link |
01:07:12.000
因為network的參數不會隨著input不一樣的不一樣嘛,
link |
01:07:15.000
這代表attention的matrix,
link |
01:07:17.000
不管input是什麼永遠都是一樣的,
link |
01:07:19.000
那這樣performance其實是不會掉太多的,
link |
01:07:22.000
這重新讓我們思考attention的價值到底是什麼,
link |
01:07:26.000
好,
link |
01:07:27.000
那再來再更進一步思考,
link |
01:07:29.000
處理sequence一定要用attention嗎?
link |
01:07:33.000
所以人們開始思考,
link |
01:07:34.000
能不能夠把attention丟掉,
link |
01:07:37.000
有沒有attention-free的方法,
link |
01:07:40.000
過去人們已經丟掉了recurrent,
link |
01:07:43.000
接下來人們要丟掉attention,
link |
01:07:46.000
所以有一系列的文章,
link |
01:07:48.000
這邊我們就不細談,
link |
01:07:49.000
一系列的文章他們直接用NLP,
link |
01:07:53.000
就是一般的Fully Connected Network,
link |
01:07:55.000
來處理一個sequence,
link |
01:07:57.000
那這邊就留給大家自己研究,
link |
01:07:59.000
這就又是另外一個故事了,
link |
01:08:01.000
留給大家自己研究。
link |
01:08:02.000
好,
link |
01:08:03.000
這一張圖啊,
link |
01:08:04.000
這個就是今天的最後一頁投影片了,
link |
01:08:07.000
這一張圖是Long Range Arena,
link |
01:08:10.000
就是我們說這個self-attention有一個Benchmark的Compass,
link |
01:08:14.000
叫做Long Range Arena,
link |
01:08:17.000
那在這個Compass裡面,
link |
01:08:19.000
你可以去計算一個self-attention的方法,
link |
01:08:21.000
它的好壞,
link |
01:08:22.000
那裡面用LRS score,
link |
01:08:24.000
細節我們就不講,
link |
01:08:25.000
反正這個分數越高,
link |
01:08:26.000
代表這個self-attention的方法表現越好,
link |
01:08:30.000
橫軸代表的是速度,
link |
01:08:33.000
就是每一秒鐘可以處理多少個sequence,
link |
01:08:37.000
所以越往右代表速度越快,
link |
01:08:40.000
那你可以看到這邊,
link |
01:08:41.000
有一系列的方法,
link |
01:08:43.000
那每一個方法呢,
link |
01:08:44.000
他都用個圈圈來表示,
link |
01:08:45.000
那圈圈的大小啊,
link |
01:08:47.000
代表這個方法需要用到的memory越大,
link |
01:08:50.000
代表用的memory越多,
link |
01:08:53.000
最原始的self-attention,
link |
01:08:55.000
就是這個藍色的圈圈,
link |
01:08:57.000
就是Transformer,
link |
01:08:59.000
那其實今天這個圖上的每一個圈圈,
link |
01:09:02.000
這一堂課裡面,
link |
01:09:03.000
我們通通都已經講到了,
link |
01:09:06.000
我們就從左上角開始看起,
link |
01:09:08.000
Big Bird,
link |
01:09:09.000
講過了對不對,
link |
01:09:10.000
Big Bird,
link |
01:09:11.000
就是把,
link |
01:09:12.000
就是小孩子才做選擇,
link |
01:09:14.000
然後把各種不同人設計的attention放在一起,
link |
01:09:17.000
就是Big Bird,
link |
01:09:19.000
那他的performance,
link |
01:09:21.000
比原來的Transformer好一點,
link |
01:09:22.000
那速度其實有點沒有快很多,
link |
01:09:24.000
快一點點而已,
link |
01:09:26.000
好,
link |
01:09:27.000
有Synthesizer,
link |
01:09:28.000
Synthesizer就是我剛才說的,
link |
01:09:30.000
非常神奇,
link |
01:09:31.000
全新的想法,
link |
01:09:32.000
Attention Matrix,
link |
01:09:33.000
不需要用QK產生,
link |
01:09:34.000
直接當network的參數,
link |
01:09:36.000
他的performance,
link |
01:09:37.000
其實掉了一點速度,
link |
01:09:39.000
快了一點,
link |
01:09:41.000
好,
link |
01:09:42.000
然後接下來呢,
link |
01:09:43.000
比如說Reformer,
link |
01:09:44.000
Reformer就是做clustering的方法,
link |
01:09:46.000
看起來其實他performance不一定很好喔,
link |
01:09:48.000
好,
link |
01:09:49.000
有Local Attention,
link |
01:09:50.000
Local Attention就是一個速度很快,
link |
01:09:52.000
但是performance有點慘的方法,
link |
01:09:55.000
好,
link |
01:09:56.000
那Syntome,
link |
01:09:57.000
Syntome有講喔,
link |
01:09:58.000
Syntome就是很神奇,
link |
01:10:00.000
他是直接用個network,
link |
01:10:01.000
來決定說哪些位置要上Attention,
link |
01:10:03.000
哪些位置不用,
link |
01:10:05.000
他的performance有掉,
link |
01:10:07.000
但是速度相較於其他的方法,
link |
01:10:09.000
相較於原來的Transformer,
link |
01:10:11.000
有快上了一截,
link |
01:10:13.000
然後最速度最快的,
link |
01:10:15.000
是Linformer,
link |
01:10:16.000
Performer,
link |
01:10:17.000
還有Linear Transformer,
link |
01:10:18.000
他們的performance相較於原來的Transformer,
link |
01:10:20.000
也是有些掉,
link |
01:10:21.000
不過他們的這個速度,
link |
01:10:23.000
相較於原來的Transformer,
link |
01:10:25.000
是快上很多的,
link |
01:10:28.000
好,
link |
01:10:29.000
那這個,
link |
01:10:30.000
這個Linformer,
link |
01:10:31.000
Performer,
link |
01:10:32.000
跟Linear Transformer,
link |
01:10:33.000
是在做什麼呢?
link |
01:10:34.000
神奇的是,
link |
01:10:35.000
Linear Transformer不是Linformer這樣,
link |
01:10:37.000
他們兩個是不一樣的東西,
link |
01:10:39.000
雖然他們聽起來名字有點像,
link |
01:10:40.000
但他們是不一樣的東西,
link |
01:10:41.000
並不是Linear Transformer的縮寫,
link |
01:10:43.000
就是Linformer,
link |
01:10:44.000
他們是不同的東西,
link |
01:10:45.000
Linformer就是,
link |
01:10:46.000
我們只選一些有代表性的Key,
link |
01:10:49.000
叫做Linformer,
link |
01:10:50.000
而Linear Transformer跟Performer,
link |
01:10:52.000
他們就是我剛才說的,
link |
01:10:54.000
本來我們是先算Query跟Key,
link |
01:10:57.000
現在先算Value跟Key,
link |
01:11:00.000
這就是Linear Transformer跟Performer,
link |
01:11:03.000
好,
link |
01:11:04.000
到這邊,
link |
01:11:05.000
我們就把Long Range Arena裡面的每一種Transformer都介紹過了,
link |
01:11:12.000
這個就是我今天想跟大家分享的內容。