back to index

【機器學習2021】Transformer (下)


link |
00:01.000
各位同學大家好,我們來上課吧!
link |
00:05.000
接下來我們要講Decoder,我們上上週已經講了Encoder,接下來我們要講Decoder。
link |
00:17.000
Decoder其實有兩種,等一下會花比較多時間介紹你比較常見的,這個叫做Auto-Regressive的Decoder。
link |
00:28.000
這個Auto-Regressive的Decoder是怎麼運作的呢?等一下我們是用語音辨識來當作例子跟大家說明,
link |
00:36.000
不過用在作業裡面的機器翻譯其實是一模一樣的,你只是把輸入輸出改成不同的東西而已。
link |
00:46.000
語音辨識是怎麼做的呢?你知道語音辨識就是輸入一段聲音輸出一串文字。
link |
00:53.000
你會把一段聲音輸入給Encoder,比如說你對機器說機器學習,機器收到一段聲音訊號,
link |
01:00.000
聲音訊號進入Encoder以後,輸出會是什麼呢?輸出會變成一排Vector。
link |
01:07.000
我們上週花了很多時間講Encoder裡面有什麼樣的內容,它裡面非常的複雜,
link |
01:12.000
如果你忘了的話就算了,你就記得Encoder做的事情就是輸入一個Vector Sequence,輸出另外一個Vector Sequence。
link |
01:21.000
接下來就輪到Decoder運作了,Decoder要做的事情就是產生輸出,接下來輪到Decoder產生語音辨識的結果。
link |
01:33.000
Decoder怎麼產生語音辨識的結果呢?Decoder做的事情就是把Encoder的輸出先讀進去。
link |
01:41.000
至於怎麼讀進去,這個我們等一下再講。你先假設商號有某種方法把Encoder的輸出讀到Decoder裡面,這部我們等一下再處理。
link |
01:53.000
Decoder怎麼產生一段文字呢?語音辨識機器的輸出就是一段文字,Decoder怎麼產生一段文字呢?
link |
02:02.000
首先你要先給它一個特殊的符號,這個特殊的符號代表開始。
link |
02:09.000
那在助教投影片裡面是寫Begin of Sentence,所寫是BOS。
link |
02:15.000
那我這邊因為怕你不知道BOS是什麼,所以我就把它的意思明確的寫出來,就是開始,就是Begin的意思。
link |
02:22.000
那這個是一個Special的Token,就是在你的Lesson裡面,就是在你本來Decoder可能產生的文字裡面,多加一個特殊的符號,多加一個特殊的字。
link |
02:35.000
那這個字就代表了Begin,代表了開始這個事情。
link |
02:40.000
好,所以Decoder就吃到這個特殊的符號,那在這個機器學習裡面,假設你要處理NLP的問題,每一個Token你都可以把它用一個One-Hot Vector來表示。
link |
02:53.000
One-Hot Vector就其中一位是1,其他都是0,所以Begin也是用One-Hot Vector來表示,其中一位是1,其他是0。
link |
03:00.000
那接下來Decoder會吐出一個項量,這個項量裡面有什麼呢?這個Vector裡面有什麼呢?
link |
03:08.000
這個Vector的長度,它很長,它的長度跟你的Vocabulary的Size是一樣的。
link |
03:17.000
這邊的Vocabulary指的是什麼意思呢?你就先想好說你的Decoder輸出的單位是什麼。
link |
03:24.000
假設我們今天做的是中文的語音辨識,我們Decoder輸出的是中文,那你這邊的Vocabulary的Size可能就是中文的方塊字的數目。
link |
03:39.000
那中文的方塊字有多少呢?不同的字典給你的數字可能是不一樣的。
link |
03:46.000
常用的中文的方塊字大概兩三千個,一般人可能認得的四五千個,再更多都是罕見字、冷僻的字,你可能看到也不知道它要怎麼念,你平常寫也寫不出來。
link |
03:58.000
所以你就看看說你要讓你的Decoder輸出哪些可能的中文的方塊字,你就把它列在這邊。
link |
04:07.000
舉例來說,你覺得這個Decoder能夠輸出常見的三千個方塊字就好了,你就把它列在這個地方。
link |
04:15.000
那不同的語言,它輸出的單位不會不一樣,這個取決於你對那個語言的理解。
link |
04:22.000
比如說英文,你可以選擇輸出字母A到Z,但你可能會覺得字母這個單位太小了,有人可能會選擇輸出英文的詞彙,英文的詞彙是用空白作為間隔的。
link |
04:38.000
但如果用詞彙當作輸出又太多了,所以你會發現剛才在助教投影片裡面,助教說他是用Subword當作英文的單位。
link |
04:48.000
就有一些方法可以把英文的字首字根切出來,拿字首字根當作單位。
link |
04:53.000
那如果中文的話,我覺得就比較單純,通常今天你可能就用中文的方塊字來當作單位。
link |
05:01.000
那在這個項量裡面,這個項量的長度就跟中文裡面的方塊字,你希望機器可以輸出的方塊字的數目是一樣多的。
link |
05:12.000
那每一個中文的字都會對應到一個數值。
link |
05:18.000
那因為在產生這個項量之前,你通常會先跑一個softmax,就跟做分類一樣,在得到最終的輸出前我們不是會跑一個softmax嗎?
link |
05:29.000
跑一個softmax,所以這個項量裡面的分數,它是一個distribution,也就是它這個項量裡面的值,它全部加起來總和會是1。
link |
05:41.000
那得到這個項量以後,還不是最終輸出的結果。
link |
05:46.000
這個項量會給每一個中文的字一個分數,那分數最高的那個中文字,它就是最終的輸出。
link |
05:54.000
在這個例子裡面,機的分數最高,所以機就當作是這個decoder第一個輸出。
link |
06:01.000
接下來,你把機當作是decoder新的input。
link |
06:07.000
原來decoder的input只有begin這個特別的符號,現在它除了begin以外,它還有機作為它的input。
link |
06:14.000
那機也是表示成一個one-hot vector當作decoder的輸入。
link |
06:20.000
所以decoder現在還有兩個輸入,一個是begin這個符號,一個是機。
link |
06:24.000
根據這兩個輸入,它就要得到一個輸出,它輸出一個藍色的項量。
link |
06:29.000
根據這個藍色的項量裡面給每一個中文字的分數,我們會決定第二個輸出是什麼。
link |
06:37.000
誰哪一個字的分數最高,他就是輸出。
link |
06:40.000
假如是氣的分數最高,那氣就是輸出。
link |
06:43.000
那decoder接下來會拿氣當作輸入。
link |
06:46.000
然後現在decoder看到了begin、看到了機、看到了氣。
link |
06:51.000
那它接下來還要再決定接下來要輸出什麼,那它可能就輸出學。
link |
06:56.000
這個過程就反覆地持續下去。
link |
07:00.000
機器輸出學以後,學會再被當作輸入。
link |
07:03.000
所以現在decoder看到了begin、機、氣、還有學。
link |
07:08.000
那incoder這邊其實也有輸入啦,那我們等一下再講incoder的輸入,decoder是怎麼處理的。
link |
07:14.000
所以decoder看到incoder這邊的輸入,看到機、看到氣、看到學,決定接下來要輸出習。
link |
07:21.000
它會輸出一個項量,這個項量裡面習這個中文字的分數最高的,所以它就輸出習。
link |
07:26.000
這個process就反覆持續下去。
link |
07:29.000
那這邊有一個關鍵的地方,我們特別用紅色的虛線把它標出來。
link |
07:34.000
也就是說decoder看到的輸入,其實是它在前一個時間點自己的輸出。
link |
07:41.000
decoder會把自己的輸出當作接下來的輸入,會把自己的輸出當作接下來的輸入。
link |
07:49.000
所以當我們decoder在產生一個句子的時候,它其實有可能看到錯誤的東西。
link |
07:55.000
因為它看到的是自己的輸出嘛,那如果今天decoder有語音辨識的錯誤,
link |
08:00.000
它把機器的氣辨識錯成天氣的氣,那接下來decoder就會看到錯誤的辨識結果。
link |
08:07.000
它還是要想辦法根據錯誤的辨識結果產生它想要產生的,期待是正確的輸出。
link |
08:14.000
那你可能會覺得說,讓decoder看到錯誤的輸入,讓decoder看到自己產生出來的錯誤的輸入,
link |
08:21.000
再被decoder自己吃進去,會不會造成問題呢?會不會造成error propagation的問題呢?
link |
08:27.000
所謂error propagation的問題就是一步錯,步步錯。
link |
08:33.000
就是在這個地方,如果不小心把機器的氣不小心寫成天氣的氣,
link |
08:38.000
會不會接下來就整個句子都壞掉了,都沒有辦法再產生正確的詞彙了。
link |
08:44.000
有可能,那這個等一下我們最後會稍微講一下這個問題要怎麼處理。
link |
08:50.000
我們現在先無視這個問題,繼續走下去。
link |
08:55.000
我們來看一下這個decoder它內部的結構長什麼樣子。
link |
09:03.000
我們這邊把encoder的部分先暫時省略掉。
link |
09:07.000
在transformer裡面,decoder的結構長的是這個樣子的,
link |
09:12.000
看起來有點複雜,比encoder還稍微複雜一點。
link |
09:16.000
我們現在先把encoder跟decoder放在一起,稍微比較一下它們之間的差異。
link |
09:23.000
你會發現說,如果我們把decoder中間這一塊蓋起來,
link |
09:30.000
其實encoder跟decoder並沒有那麼大的差別。
link |
09:35.000
你看encoder這邊,multi-head attention,add and no,feedforward,add and no,重複n次。
link |
09:42.000
decoder其實也是一樣,當我們把中間這一塊遮起來以後,
link |
09:45.000
我們等一下再講遮起來這一塊裡面做了什麼事。
link |
09:48.000
當我們把中間這一塊遮起來以後,decoder也是有一個multi-head attention,
link |
09:54.000
add and no,feedforward,add and no。
link |
09:58.000
所以encoder跟decoder其實並沒有非常大的差別,
link |
10:02.000
除了中間這一塊不一樣的地方,被遮起來的地方以外。
link |
10:05.000
其實encoder跟decoder是一樣的,
link |
10:09.000
只是最後我們可能會再做一個softmax,使得它的輸出變成一個機率。
link |
10:15.000
那這邊有一個稍微不一樣的地方是,
link |
10:18.000
在decoder這邊,multi-head attention這個block上面還加了一個mask。
link |
10:25.000
這個mask是什麼意思呢?
link |
10:27.000
這個mask的意思是這樣子的,這是我們原來的self-attention。
link |
10:32.000
input一排vector,output另外一排vector。
link |
10:36.000
這一排vector每一個輸出都要看過完整的input以後才做決定。
link |
10:42.000
所以輸出B1的時候,其實是根據A1到A4所有的資訊去輸出B1。
link |
10:49.000
當我們把self-attention轉成mask-attention的時候,
link |
10:53.000
它的不同點在哪裡呢?
link |
10:55.000
它的不同點是,現在我們不能再看右邊的部分。
link |
11:00.000
也就是產生B1的時候,我們只能考慮A1的資訊,
link |
11:04.000
你不能夠再考慮A2、A3、A4。
link |
11:07.000
產生B2的時候,你只能考慮A1、A2的資訊,不能再考慮A3、A4的資訊。
link |
11:13.000
產生B3的時候,你就不能考慮A4的資訊。
link |
11:17.000
產生B4的時候,你可以用整個input sequence的資訊。
link |
11:21.000
這個就是mask的self-attention。
link |
11:24.000
講得更具體一點,你做的事情是這樣。
link |
11:27.000
當我們要產生B2的時候,
link |
11:29.000
我們只拿第二個位置的query去跟第一個位置的key和第二個位置的key去計算attention。
link |
11:41.000
第三個位置跟第四個位置就不管它,不去計算attention。
link |
11:48.000
我們這樣子不去管A2右邊的地方,只考慮A1跟A2,只考慮Q1、Q2,只考慮K1、K2。
link |
11:59.000
Q2只跟K1跟K2去計算attention,最後只計算B1跟B2的weighted sum。
link |
12:05.000
當我們輸出B2的時候,B2就只考慮了A1跟A2,就沒有考慮到A3跟A4。
link |
12:12.000
那為什麼會這樣呢?為什麼需要加masking呢?
link |
12:17.000
這件事情其實非常的直覺。
link |
12:20.000
你想想看我們一開始decoder的運作方式,它是一個一個輸出,它的輸出是一個一個產生的。
link |
12:28.000
所以是先有A1,再有A2,再有A3,再有A4。
link |
12:32.000
這跟原來的self-attention不一樣。原來的self-attention,A1跟A4是一次整個輸進去你的model裡面的。
link |
12:40.000
在我們講encoder的時候,encoder是一次把A1跟A4整個都讀進去。
link |
12:45.000
但是對decoder而言,先有A1,才有A2,才有A3,才有A4。
link |
12:50.000
所以實際上,當你有A2,你要計算B2的時候,你是沒有A3跟A4的。
link |
12:56.000
所以你根本就沒有辦法把A3、A4考慮進來。
link |
13:00.000
所以這就是為什麼在那個decoder的那個圖上面,transformer原始的paper特別跟你強調說,
link |
13:07.000
那不是一個一般的attention,這是一個masked self-attention。
link |
13:12.000
其實只是想要告訴你說,decoder,它的token,它輸出的東西是一個一個產生的。
link |
13:17.000
所以它只能考慮它左邊的東西,它沒有辦法考慮它右邊的東西。
link |
13:25.000
但是講到這裡,我們講了decoder的運作方式,但是這邊還有一個非常關鍵的問題。
link |
13:34.000
這個關鍵的問題是,decoder必須自己決定輸出的sequence的長度。
link |
13:41.000
可是到底輸出的sequence的長度應該是多少呢?我們不知道。
link |
13:47.000
你沒有辦法輕易地從輸入的sequence的長度就知道輸出的sequence的長度是多少。
link |
13:53.000
並不是說輸入是四個向量,輸出一定就是四個向量。
link |
13:59.000
這邊在這個例子裡面輸入跟輸出的長度是一樣的,但是你知道實際上在你真正的應用裡面並不是這樣。
link |
14:05.000
輸入跟輸出長度的關係是非常複雜的。
link |
14:09.000
我們其實是期待機器可以自己學到今天給它一個input sequence的時候,output sequence應該要多長。
link |
14:17.000
但在我們目前的整個decoder的運作機制裡面,機器不知道它什麼時候應該停下來。
link |
14:26.000
它產生完C以後,它還可以繼續重複一模一樣的process,
link |
14:31.000
就把C當作輸入,然後也許decoder就會接一個慣,然後接下來就一直持續下去,永遠都不會停下來。
link |
14:42.000
這讓我想到推文接龍,我不知道大家知不知道是什麼。
link |
14:47.000
這是一個古老的民俗傳統,流傳在PTT上面。
link |
14:53.000
這個民俗傳統是怎麼運作的呢?
link |
14:55.000
就是有一個人先推一個中文字,推一個超,然後接下來就會有另外一個鄉民去推另外一個字,然後可以接上去的。
link |
15:05.000
所以就可以產生一排的詞彙、一排字,就是超人、政大、中天、外非、仙草,我不知道在說些什麼。
link |
15:12.000
這個process可以持續好幾個月都不停下來,我也不知道為什麼。
link |
15:18.000
那怎麼讓這個process停下來呢?
link |
15:22.000
要怎麼讓它停下來呢?要有人冒險去推一個段,推一個段,它就停下來了。
link |
15:29.000
所以我們要讓decoder做的事情也是一樣,要讓它可以輸出一個段。
link |
15:36.000
所以你要準備一個特別的符號,這個符號就叫做段,這邊用end來表示這個特殊的符號。
link |
15:46.000
所以除了所有中文的方塊字還有begin以外,你還要準備一個特殊的符號叫做段。
link |
15:54.000
那其實在助教的程式裡面,它是把begin跟end,就是開始跟這個段用同一個符號來表示。
link |
16:02.000
反正這個begin只會在輸入的時候出現,段只會在輸出的時候出現。
link |
16:07.000
所以在助教程式裡面,如果你仔細研究一下的話,會發現說end跟begin用的其實是同一個符號。
link |
16:13.000
那你用不同的符號也是完全可以的,也完全沒有問題。
link |
16:18.000
所以我們現在讓decoder它可以輸出段這個符號,輸出end這個符號。
link |
16:25.000
那我們期待說,當今天產生完習以後,再把習當作decoder的輸入以後,decoder就要能夠輸出段。
link |
16:36.000
也就是說,當把習當作輸入以後,就decoder看到encoder輸出的embedding,看到了begin,然後機器學習以後。
link |
16:46.000
看到這些資訊以後,它要知道說,這個語音辨識的結果已經結束了,不需要再產生更多的詞彙了。
link |
16:54.000
它產生出來的向量裡面,這個end,就是段的那個符號,它的機率必須要是最大的,然後你就輸出段這個符號。
link |
17:03.000
那整個運作的過程,整個decoder產生sequence的過程就結束了。
link |
17:09.000
好,那這個就是autoregressive的decoder它運作的方式。
link |
17:16.000
好,那接下來呢,我們用兩頁投影片,非常簡短的講一下non-autoregressive的model。
link |
17:25.000
non-autoregressive的model通常縮寫成NAT,所以有時候autoregressive的model也縮寫成AT。
link |
17:33.000
non-autoregressive的model是怎麼運作的呢?
link |
17:36.000
這個non-autoregressive的model是先輸入begin,然後出現W1,然後再把W1當作輸入,再輸出W2,直到輸出end的為止。
link |
17:47.000
那NAT是這樣,它不是一次產生,就假設我們現在要產生的是中文的句子,它不是一次產生一個字,它是一次把整個句子都產生出來。
link |
17:58.000
怎麼一次把整個句子都產生出來呢?
link |
18:01.000
NAT的decoder啊,它可能吃的是一整排的begin的token,你就把一堆一排begin的token都丟給它,讓它一次產生一排token就結束了。
link |
18:13.000
舉例來說,如果你丟給它四個begin的token,它就產生四個中文的字,變成一個句子,就結束了。
link |
18:20.000
所以它只要一個步驟就可以完成句子的生成。
link |
18:25.000
這邊你可能就會問一個問題,剛才不是說不知道輸出的長度應該是多少嗎?
link |
18:32.000
那我們這邊怎麼知道begin要放多少個當作NAT decoder的輸入呢?
link |
18:37.000
沒錯,這件事沒有辦法很自然的知道,沒有辦法很直接的知道。
link |
18:41.000
所以有幾個做法,一個做法是你另外認一個classifier,這個classifier它吃encoder的input,然後輸出是什麼?
link |
18:53.000
輸出是一個數字,這個數字代表decoder應該要輸出的長度。
link |
18:58.000
所以你就認一個classifier,這個classifier可能吃encoder的input,可能吃把encoder output的那些向量讀進去,它output一個數字,比如說output4,把它output4以後,NAT的decoder就會吃到四個begin的token,然後它就產生四個中文的字。
link |
19:16.000
這是一種可能的做法。
link |
19:18.000
另一種可能的做法就是,你就不管3721,給它一堆begin的token,你就假設說你現在輸出的句子的長度絕對不會超過300個字,你就假設一個句子長度的上限,然後begin你就給它300個begin,然後就會輸出300個字。
link |
19:35.000
然後你再看看說什麼地方輸出了段,什麼地方輸出end,輸出end的右邊的,就當作它沒有輸出,就結束了。這是另外一種處理NAT的decoder它應該輸出的長度的方法。
link |
19:52.000
NAT的decoder它有什麼樣的好處呢?它第一個好處是平行化。這個AT的decoder,它在輸出它的句子的時候,是一個一個一個字產生的。
link |
20:07.000
所以假設你要輸出長度100個字的句子,那你就需要做100次的decode。但是NAT的decoder不是這樣,不管句子的長度如何,都是一個步驟就產生出完整的句子。
link |
20:24.000
所以在速度上,NAT的decoder它會跑得比AT的decoder要快。你可以想像說,這個NAT的decoder的想法顯然是在由transformer以後,有這種SELM attention的decoder以後才有的。
link |
20:41.000
因為以前如果你是用LSTM、RNN的話,你就算給它一排begin,它也沒有辦法同時產生全部的輸出,它的輸出還是一個一個產生的。
link |
20:53.000
所以在沒有SELM attention之前,只有RNN、LSTM的時候,根本就不會有人想要做什麼NAT的decoder。不過自從有了SELM attention以後,NAT的decoder現在就算是一個熱門研究的主題了。
link |
21:09.000
NAT的decoder還有另外一個好處,就是你比較能夠控制它輸出的長度。
link |
21:18.000
怎麼說呢?舉語音合成為例好了。其實在語音合成裡面,NAT的decoder算是非常常用的,它並不是一個什麼稀罕罕見的招數。
link |
21:30.000
比如說語音合成,今天你都可以用sequence-to-sequence的模型來做,最知名的是一個叫做Tacotron的模型,它是AT的decoder。
link |
21:41.000
另外一個模型叫Fast Speech,它是NAT的decoder。
link |
21:46.000
NAT的decoder有一個好處,就是你可以控制你輸出的長度。我們剛才說,怎麼決定NAT的decoder輸出多長呢?你可能有一個classifier決定NAT的decoder應該輸出的長度。
link |
22:00.000
如果在做語音合成的時候,假設你現在突然想要讓你的系統講快一點、加速,那你就把classifier的output除以2,它講話速度就變兩倍快。如果你想要講話放慢速度,那你就把classifier輸出的長度,它predict出來的長度,乘兩倍。
link |
22:18.000
你的decoder說話的速度就變兩倍慢。如果有這種NAT的decoder,你有explicit的去model output的長度應該是多少的話,你就比較有機會去控制你的decoder輸出的長度應該是多少,你就可以做種種的變化。
link |
22:36.000
為什麼NAT的decoder最近是一個熱門的研究主題呢?它之所以是一個熱門的研究主題,就是它雖然表面上看起來有種種的厲害之處,尤其是平行化是它最大的優勢,但是NAT的decoder的performance往往都不如AT的decoder。
link |
22:57.000
所以發現有很多很多的研究試圖讓NAT的decoder的performance越來越好,試圖去逼近AT的decoder。不過今天你要讓NAT的decoder跟AT的decoder的performance一樣好,你必須要用非常多的trick才能辦到。
link |
23:12.000
NAT的decoder隨便train一下,NAT的decoder你要花很多力氣才有可能跟AT的performance差不多。
link |
23:17.000
為什麼NAT的decoder的performance不好呢?有一個問題我們今天就不細講了,叫做multi-modality的問題。
link |
23:27.000
如果你想要深入了解NAT,就把之前助教上課補充的內容連結放在這邊給大家參考。NAT也是一個大坑,助教也是講了一個半小時才稍微給大家一個大概大致的描述。所以這也是一個大坑,不是我們今天可以講的,就只是告訴大家說世界上有NAT這個東西而已。
link |
23:51.000
接下來我們就要講encoder跟decoder它們中間是怎麼傳遞資訊的了,也就是我們要講剛才我們刻意把它遮起來的那一塊。
link |
24:05.000
如果你仔細觀察這一塊的話,這一塊叫做cross-attention,它是連接encoder跟decoder之間的橋梁。這一塊裡面你會發現有兩個輸入來自於encoder,encoder提供兩個箭頭,decoder提供了一個箭頭。
link |
24:28.000
所以從左邊這兩個箭頭,decoder可以讀到encoder的輸出。
link |
24:35.000
那這個模組實際上是怎麼運作的呢?那我們就實際把它運作的過程跟大家展示一下。
link |
24:42.000
這個是你的encoder,輸入一排向量,輸出一排向量,我們叫它A1、A2、A3。
link |
24:47.000
接下來輪到你的decoder,你的decoder會先吃begin,當作begin這個special的token。那begin這個special的token讀進來以後,你可能會經過self-attention。
link |
25:00.000
這個self-attention是有做mask的,然後得到一個向量。
link |
25:05.000
就像self-attention就算是有做mask,還是一樣輸入多少長度的向量,輸出就是多少向量。
link |
25:11.000
所以輸入一個向量,輸出一個向量。然後接下來把這個向量乘上一個矩陣,做一個transform,得到一個query,叫做Q。
link |
25:21.000
然後這邊的A1、A2、A3也都產生key,key1、key2、key3。
link |
25:27.000
那把這個Q跟K1、K2、K3去計算attention的分數,得到α1、α2、α3。
link |
25:34.000
當然你可能一樣會做softmax,把它稍微做一下normalization,所以我這邊加一個π,代表它可能是做過normalization。
link |
25:42.000
接下來再把α1、α2、α3乘上V1、V2、V3,再把它weighted上加起來,你得到V。
link |
25:51.000
那這個V就是接下來會丟到fully connected的network做接下來的處理。
link |
25:59.000
那這個步驟就是Q來自於decoder,K跟V來自於encoder,這個步驟就叫做cross-attention。
link |
26:10.000
所以decoder就是憑藉著產生一個Q,去encoder這邊抽取資訊出來,當作接下來的decoder裡面的fully connected network的input。
link |
26:22.000
那這個就是cross-attention的運作的過程,當然現在假設產生第一個中文的字,產生一個G,接下來的運作也是一模一樣的。
link |
26:35.000
輸入begin,輸入G,產生一個向量,這個向量一樣乘上一個linear transform,得到Q'、得到一個query。
link |
26:43.000
這個query一樣跟K1、K2、K3去計算attention的分數,一樣跟V1、V2、V3做weighted上做加權,然後加起來得到V',交給接下來的fully connected network做處理。
link |
26:58.000
所以這就是這個cross-attention的運作的過程。
link |
27:03.000
那這邊有一個實際的文獻上的cross-attention,它所做的事情的效果展示,不過我這邊要稍微說明一下,這個圖並不是來自於Transformer。
link |
27:15.000
這篇paper它的title叫做Listen, Attend, Spill,是比較早的使用sequence-to-sequence model成功做語音辨識的一篇文章。
link |
27:25.000
它發表在ICAST 2016,2016年的ICAST,我記得那一次是在上海辦的,我還特別有親耳聽了這篇paper的報告,現場還是人山人海。
link |
27:36.000
大家都覺得,哇,這個非常的神奇,sequence-to-sequence,運作居然可以做語音辨識,而且跟state-of-the-art的結果當時也就只差了一點點而已。
link |
27:48.000
當時這篇paper裡面的結果,它展現的sequence-to-sequence model其實沒有贏過state-of-the-art,就是當時最好的語音辨識系統,但是只差一點點而已。
link |
27:58.000
所以讓大家覺得說,sequence-to-sequence用在語音辨識上似乎是有潛力的。
link |
28:05.000
所以它其實不是transformer,那時候的encoder跟decoder都是用LSTM,不過那個時候就已經有cross-attention這樣的機制了。
link |
28:17.000
所以在有transformer之前,其實就已經有cross-attention這樣的機制,只是沒有self-attention的機制,所以是先有cross-attention,後來才有self-attention。
link |
28:27.000
那個時候,如果你是用sequence-to-sequence的model,不知道為什麼paper的title一定要有三個動詞,才能夠代表你是在做sequence-to-sequence的model。
link |
28:40.000
所以像這邊,就是listen, attend, and spell,告訴他說機器要聽聲音,然後做attention,就是cross-attention,spell就是把他聽到的東西拼出來。
link |
28:51.000
我特別放這個圖是想要讓你比較容易想像這個cross-attention是怎麼運作的。
link |
28:58.000
這一段是聲音訊號,是機器的輸入。聲音訊號輸入給encoder的時候,它是用一串向量來表示,一排向量來表示。
link |
29:06.000
所以這是時間,然後這邊是一排一排一個一個的向量。然後這一排是decoder的輸出,decoder一次只吐一個英文的字母,所以它會吐H,吐O,吐W,就代表號。
link |
29:23.000
如果它已經到一個詞彙的邊界,它會自動吐出空白,空白當作是一個特殊的字母來處理。所以機器decoder有可能輸出空白,代表一個詞彙結束了,換一個新的詞彙。
link |
29:37.000
接下來輸出much,再輸出空白,再輸出W。
link |
29:42.000
這句話其實是一個英文的繞口令,這句話完整的句子是How much wood would a woodchuck charge?實際上內容是什麼其實不太重要,它就是一句繞口令就是了。
link |
29:53.000
很神奇,機器可以一次吐一個字母,而且它可以聽對正確的詞彙。
link |
30:01.000
這邊這個值是什麼呢?這個值就是Attention的分數,所以當你要產生這個H的時候,在產生這個H之前,你的decoder會去對encoder的輸出做Attention。
link |
30:16.000
所以它就Attent在這個地方,然後產生H,然後Attent在這個地方,產生O,Attent在這個地方,產生W。這邊顏色越深,就代表說那個Attention的分數,就是那個alpha的值越大。
link |
30:32.000
所以你會發現說它產生H的時候,它就是聽到這個地方有H的聲音,所以產生H。接下來再往右移一點,產生O,再往右移一點,產生W。接下來Attent在這個地方,產生Space,然後Attent在這個地方,產生N。
link |
30:48.000
你會看到說這個Attention的weight是由左上到右下移動的,跟你想像Attention應該運作的機制很像。因為當我們這邊每次產生一個詞彙的時候,我們想要專注、我們想要考慮的聲音訊號應該就是由左向右移動。
link |
31:04.000
所以確實,如果你看model的Attention的話,它的分數高的地方可能也是從左上一直排到右下。
link |
31:14.000
講到這邊,也許有同學會問說,那這個encoder有很多層啊,decoder也有很多層啊。從剛才的講解裡面,好像聽起來這個decoder不管哪一層,都是拿encoder最後一層的輸出,這樣對嗎?
link |
31:32.000
對,在原始paper裡面的實作是這樣子的。那一定要這樣嗎?不一定要這樣,你永遠可以自己兜一些新的想法。所以我這邊就是引用一篇論文告訴你說,也有人嘗試不同的cross-attention的方式。
link |
31:49.000
encoder這邊有很多層,decoder這邊有很多層,為什麼decoder這邊每一層都一定要看encoder最後一層的輸出呢?能不能夠有各式各樣不同的連接方式,這完全可以當作一個研究的問題來study。
link |
32:03.000
那最後呢,我們就要講訓練這件事了。我們已經講了encoder、decoder、encoder、decoder怎麼互動的,你已經清楚說inbringer sequence是怎麼得到最終的輸出。那接下來就進入訓練的部分。
link |
32:19.000
我們剛才都還沒有講訓練的部分喔,我們剛才講的都還只是假設你模型訓練好以後,它是怎麼運作的,它是怎麼做testing的,它是怎麼做inference的。inference就testing啦,所以當我說inference的時候,我指的就是testing,我指的是同一件事情。
link |
32:37.000
那是怎麼做訓練的呢?接下來就要講怎麼做訓練。那如果是做語音辨識,那你要有訓練資料,需要什麼樣的訓練資料呢?你要收集一大堆的聲音訊號,每一句聲音訊號都要有工讀生來聽打一下,打出說它對應的詞彙是什麼。
link |
32:55.000
工讀生聽這段是機器學習,他就把機器學習四個字打出來,所以就知道說你的transformer應該要學到聽到這段聲音訊號,它的輸出就是機器學習這四個中文字。
link |
33:09.000
那怎麼讓機器學到這件事呢?我們已經知道說輸入這段聲音訊號,第一個應該要輸出的中文字是機。所以今天當我們把begin丟給decoder的時候,它第一個輸出應該要跟機越接近越好。
link |
33:27.000
怎麼叫做跟機越接近越好呢?機這個字會被表示成一個one-hot vector,在這個vector裡面只有機對應的那個維度是1,其他都是0,這是正確的答案。
link |
33:40.000
那我們的decoder它的輸出是一個distribution,是一個機率的分布,我們會希望這個機率的分布跟這個one-hot vector越接近越好。所以你會去計算這個ground truth跟這個distribution它們之間的cross entropy,然後我們希望這個cross entropy的值越小越好,就這樣。
link |
34:00.000
那你可能會發現說,這件事情跟分類很像。沒錯,它就跟分類很像。剛才助教在講解作業的時候,也有提到這件事情。
link |
34:11.000
你可以想成,每一次decoder在產生一個中文字的時候,其實就是做了一次分類的問題。
link |
34:22.000
每一次中文字假設有四千個,那就是做有四千個類別的分類的問題。所以實際上訓練的時候這個樣子,我們已經知道輸出應該是機器學習這四個字。
link |
34:36.000
那你就告訴機器說,你就告訴你的decoder說,現在你第一次的輸出、第二次的輸出、第三次的輸出、第四次的輸出,應該分別就是機器學跟習這四個中文字的one-hot vector。我們希望我們的輸出跟這四個字的one-hot vector越接近越好。
link |
34:54.000
在訓練的時候,每一個輸出都會有一個cross entropy,每一個輸出跟one-hot vector,跟它對應的正確答案都有一個cross entropy。我們要希望所有的cross entropy的總和越小越好。
link |
35:10.000
所以這邊做了四次分類的問題,我們希望這些分類的問題,它總和起來的cross entropy越小越好。但這邊不要忘了,還有斷這個東西,還有end這個東西。
link |
35:24.000
所以其實今天假設這個句子中文的字是四個,但是你學習的時候,你要decoder輸出的不是只有這四個中文字。你還要叫它記得說,這四個中文字輸出完以後,你還要記得輸出斷這個特別的符號。
link |
35:42.000
所以你要告訴你的decoder說,你最終第五個位置輸出的這個向量,應該跟斷的one-hot vector它的cross entropy越小越好。
link |
35:55.000
那這個就是decoder的訓練。你把one-truth給它,正確答案給它,希望decoder的輸出跟正確答案越接近越好。
link |
36:05.000
那這邊有一件值得我們注意的事情,這件事是這樣的。你看看decoder的輸入是什麼?decoder的輸入是正確答案。
link |
36:18.000
我們會給decoder,在訓練的時候我們會給decoder看正確答案。
link |
36:24.000
也就是我們會告訴它說,在已經有begin、有g的情況下,你就要輸出g,有begin、有g、有g的情況下輸出g,有begin、有g、有g、有g的情況下輸出g,有begin、有g、有g、有g、有g的情況下,你就要輸出g。
link |
36:40.000
在decoder訓練的時候,我們會在輸入的時候給它正確的答案。
link |
36:48.000
這件事情叫做teacher forcing,其實我不太確定為什麼叫teacher forcing,好像是老師會強迫你做什麼事情一樣,聽起來好像沒有很好。
link |
36:58.000
但是這個技術就叫做teacher forcing,也就是我們把正確的答案當作decoder的輸入。
link |
37:06.000
這個時候你馬上就會有一個問題了,訓練的時候decoder有偷看到正確答案了,但是測試的時候顯然沒有正確答案可以給decoder看。
link |
37:17.000
剛才也有強調說在真正使用這個模型在influence的時候,decoder看到的是自己的輸入,這中間顯然有一個mismatch。
link |
37:27.000
對,這中間有一個mismatch,等一下我們會有一頁投影片說明有什麼樣可能的解決方式。
link |
37:35.000
接下來就是要講不侷限於transformer訓練與訓練這種sequence-to-sequence model的一些tips。
link |
37:48.000
第一個tips是copy mechanism,對很多任務而言,在我們剛才的討論裡面,我們都要求decoder自己產生輸出。
link |
38:00.000
但是對很多任務而言,也許decoder沒有必要自己創造輸出出來,它需要做的事情也許是從輸入的東西裡面複製一些東西出來。
link |
38:12.000
那我們有沒有辦法讓decoder複製從輸入複製一些東西出來呢?其實是有辦法的。
link |
38:19.000
像這種複製的行為在哪些任務會用得上呢?一個例子是做聊天機器人。
link |
38:26.000
舉例來說,人對機器說,你好,我是庫洛洛。庫洛洛就是團長啦,他是誰其實也沒那麼重要,已經很久沒有見到他了。
link |
38:34.000
我是庫洛洛。機器應該要回什麼呢?機器應該要回答說,庫洛洛,你好,很高興認識你。
link |
38:42.000
對機器來說,它其實沒有必要創造庫洛洛這個詞彙,這對機器來說一定會是一個非常怪異的詞彙。
link |
38:49.000
所以它可能很難,在訓練資料裡面可能一次也沒有出現過,所以它不太可能正確地產生這段句子出來。
link |
38:58.000
但是假設今天機器在學的時候,它學到的並不是它要產生庫洛洛這三個中文字,
link |
39:06.000
它學到的是看到輸入的時候說我是某某某,就直接把某某某,不管這邊是什麼,複製出來說某某某,你好。
link |
39:15.000
這樣子機器的訓練顯然會比較容易,它顯然比較有可能得到正確的結果。
link |
39:22.000
所以複製對於對話來說可能是一個需要的技術、需要的能力。
link |
39:29.000
我這邊舉另外一個例子,小傑不能用唸能力了,你可能會回答說,你所謂的不能用唸能力是什麼意思?
link |
39:38.000
對機器來說,它要做的事情去複述這一段它聽不懂的話,它不需要從頭去創造這一段文字,
link |
39:46.000
它要學的也許是從使用者人的輸入去copy一些詞彙當作它的輸出。
link |
39:54.000
或者是在做摘要的時候,你可能更需要copy這樣子的技能。
link |
40:00.000
所謂的摘要就是你要訓練一個模型,然後這個模型去讀一篇文章,然後產生這篇文章的摘要。
link |
40:07.000
這個任務完全是有辦法做的,你就是蒐集大量的文章,每一篇文章都有人寫的摘要,然後你就訓練一個sequence-to-sequence的模型,就結束了。
link |
40:20.000
你要做這樣的任務,只有一點點的資料是做不起來的。
link |
40:23.000
有同學蒐集幾萬篇文章,然後訓練一個這樣的sequence-to-sequence的模型,發現結果有點差,然後來問我為什麼。
link |
40:31.000
這時候我就告訴你說,你要叫機器說合理的句子,通常百萬篇文章是需要的。
link |
40:39.000
所以如果你有百萬篇文章,那些文章都有人標的摘要,那有時候你會直接把文章的標題當作摘要,那這樣就不需要花太多的人力來標了。
link |
40:48.000
你是可以訓練一個直接可以幫你讀一篇文章,就下一個標題做一個摘要的模型。
link |
40:55.000
但是我們知道,做摘要的時候,有時候很多的詞彙其實就是直接從原來的文章裡面複製出來的。
link |
41:03.000
小時候老師叫我們寫國文課的課文摘要的時候,其實你也沒有自己創造詞彙,你就是從課文裡面找一些句子出來,然後把它改寫一下,其實就變成摘要了。
link |
41:17.000
所以對摘要這個任務而言,其實從文章裡面直接複製一些資訊出來,可能是一個很關鍵的能力。
link |
41:24.000
那Sequence-to-Sequence Model有沒有辦法做到這件事呢?
link |
41:29.000
簡單來說就是有,那我們就不會細講。
link |
41:32.000
最早有從輸入複製東西的能力的模型叫做Pointer Network,這個過去上課是有講過的,我把錄影放在這邊給大家參考。
link |
41:42.000
後來還有一個變形叫做Copying Network,你可以看一下這篇Copying Mechanism in Sequence-to-Sequence Learning,看看Sequence-to-Sequence Model是怎麼做到從輸入複製東西到輸出來的。
link |
41:57.000
其實這個Sequence-to-Sequence Model,因為你知道機器就是一個黑盒子,有時候它裡面學到什麼東西,你實在是考不清楚。
link |
42:09.000
有時候它會犯非常低級的錯誤。什麼樣低級的錯誤呢?這邊就舉一個真實的低級錯誤的例子。
link |
42:18.000
這邊舉的例子是語音合成。
link |
42:21.000
今天語音合成,你完全可以訓練一個Sequence-to-Sequence Model。
link |
42:26.000
Sequence-to-Sequence Model大家都很熟嘛,Transformer就是一個例子。
link |
42:29.000
你就拿出來,然後輸入是什麼,你就收集很多的文字跟聲音訊號的對應關係,然後接下來告訴你的Sequence-to-Sequence Model說,看到這段中文的句子,你就輸出這段聲音。
link |
42:44.000
然後就沒有然後,就一圈一發,就結束了,然後機器就可以學會做語音合成了。
link |
42:51.000
那像這樣的方法做出來的結果怎麼樣呢?
link |
42:54.000
其實還不錯,舉例來說我叫機器連縮四次發財,看看它會怎麼講,機器輸出的結果是這樣子。
link |
43:03.000
發財,發財,發財,發財,發財,發財,發財,發財
link |
43:06.000
這很神奇耶,我輸入的發財明明是同樣的詞彙,只是重複四次,機器居然自己有一些意羊頓挫。
link |
43:14.000
你說它為什麼有意羊頓挫?你再仔細聽聽看。
link |
43:16.000
發財,發財,發財,發財,發財,發財
link |
43:18.000
四個發財的聲音不是一樣的耶。
link |
43:20.000
發財,發財,發財,發財,發財,發財,發財
link |
43:22.000
發財發財
link |
43:23.000
他是有抑揚頓挫的
link |
43:24.000
他怎麼學到這件事
link |
43:25.000
不知道啊
link |
43:26.000
他自己訓練出來就是這個樣子
link |
43:28.000
那你讓他講三次發財
link |
43:30.000
發財發財發財
link |
43:32.000
也沒問題
link |
43:33.000
讓他講兩次發財
link |
43:35.000
發財發財
link |
43:36.000
發財發財
link |
43:37.000
也沒問題
link |
43:38.000
讓他講一次發財
link |
43:39.000
發財發財發財
link |
43:43.000
發現 欸 怎麼沒有念發
link |
43:45.000
他不發啊
link |
43:46.000
為什麼
link |
43:47.000
就是不知道為什麼這樣子
link |
43:49.000
就是你的Sequence to Sequence Model
link |
43:51.000
出來就是
link |
43:52.000
會產生莫名其妙的結果
link |
43:54.000
也許在訓練資料裡面
link |
43:56.000
這種非常短的句子
link |
43:58.000
很少
link |
43:59.000
所以機器他根本
link |
44:00.000
沒有辦法處理
link |
44:01.000
不知道怎麼處理
link |
44:02.000
這種非常短的句子
link |
44:03.000
你叫他念發財
link |
44:04.000
他把發省略掉
link |
44:05.000
只念財
link |
44:06.000
你居然叫他念四次發財
link |
44:08.000
重複四次沒問題
link |
44:09.000
叫他只念一次
link |
44:10.000
居然會有問題
link |
44:12.000
就是這麼的奇怪
link |
44:15.000
但其實這個例子
link |
44:16.000
並沒有那麼常出現啦
link |
44:17.000
就這個用Sequence to Sequence
link |
44:19.000
認出來TTS
link |
44:20.000
也沒有你想像的那麼差
link |
44:21.000
這個要找這種差的例子
link |
44:23.000
也是挺花時間的
link |
44:24.000
要花很多時間
link |
44:25.000
才找得到這種差的例子
link |
44:26.000
但這樣子的例子
link |
44:27.000
是存在的
link |
44:30.000
好 所以怎麼辦呢
link |
44:32.000
有一個可能的方法是
link |
44:34.000
因為我們剛才發現說
link |
44:35.000
機器居然漏字了
link |
44:38.000
輸入有一些東西
link |
44:39.000
他居然沒有看到
link |
44:41.000
我們能不能夠
link |
44:42.000
強迫他一定要把
link |
44:44.000
輸入的每一個東西
link |
44:46.000
通通看過呢
link |
44:47.000
這個是有可能的
link |
44:49.000
這招就叫做Guided Attention
link |
44:52.000
像這種Guided的任務
link |
44:54.000
都用得上
link |
44:55.000
我覺得它最適合的
link |
44:56.000
是像這種語音辨識
link |
44:59.000
語音合成這種任務
link |
45:01.000
因為像語音辨識這種任務
link |
45:03.000
你其實很難接受說
link |
45:04.000
你講一句話
link |
45:05.000
今天辨識出來
link |
45:06.000
居然有一段機器沒聽到
link |
45:08.000
或語音合成
link |
45:09.000
你輸入一段文字
link |
45:10.000
語音合出來
link |
45:11.000
居然有一段沒有念到
link |
45:12.000
這個人很難接受
link |
45:13.000
那如果是其他應用
link |
45:14.000
比如說Chatbot
link |
45:15.000
或者是Summary
link |
45:17.000
可能就沒有那麼嚴格
link |
45:18.000
因為對一個Chatbot來說
link |
45:20.000
你輸入一句話
link |
45:21.000
他就回一句話
link |
45:22.000
他到底有沒有把整句話看完
link |
45:23.000
其實你三號也不在乎
link |
45:24.000
你其實也搞不清楚
link |
45:25.000
但是對語音辨識
link |
45:26.000
語音合成
link |
45:27.000
Guided Attention
link |
45:28.000
可能就是一個
link |
45:29.000
比較重要的技術
link |
45:30.000
Guided Attention
link |
45:31.000
要做的事情就是
link |
45:32.000
要求機器
link |
45:34.000
我們要去蓋的
link |
45:37.000
去領導Attention的過程
link |
45:39.000
要求機器
link |
45:40.000
他在做Attention的時候
link |
45:42.000
是有固定的方式的
link |
45:45.000
舉例來說
link |
45:46.000
對語音合成
link |
45:47.000
或者是語音辨識來說
link |
45:49.000
我們想像中的Attention
link |
45:51.000
應該就是由左向右
link |
45:53.000
在這個例子裡面
link |
45:54.000
我們用紅色的這個曲線
link |
45:56.000
來代表Attention的分數
link |
45:58.000
這個越高就代表
link |
45:59.000
Attention的值越大
link |
46:01.000
那如果今天
link |
46:02.000
不管是做語音辨識
link |
46:03.000
還是語音合成
link |
46:04.000
我們以語音合成為例好了
link |
46:06.000
那你的輸入就是一串文字
link |
46:08.000
那你在合成聲音的時候
link |
46:10.000
顯然是由左念到右
link |
46:12.000
所以機器應該是
link |
46:13.000
先看最左邊輸入的詞彙
link |
46:16.000
產生聲音
link |
46:17.000
再看中間的詞彙產生聲音
link |
46:19.000
再看右邊的詞彙產生聲音
link |
46:22.000
如果你今天在做語音合成的時候
link |
46:24.000
你發現機器的Attention
link |
46:26.000
是顛三倒四的
link |
46:28.000
他先看最後面
link |
46:29.000
接下來再看前面
link |
46:31.000
再胡亂看整個句子
link |
46:33.000
那顯然有些事做錯了
link |
46:35.000
顯然有些事做錯了
link |
46:39.000
那顯然這樣子的Attention
link |
46:42.000
是有問題的
link |
46:43.000
你在做語音合成的時候
link |
46:45.000
你沒有辦法合出好的結果
link |
46:48.000
所以該給Attention
link |
46:49.000
要做的事情就是
link |
46:50.000
強迫Attention
link |
46:51.000
有一個固定的樣貌
link |
46:53.000
那如果你對這個問題
link |
46:54.000
本身就已經有理解
link |
46:55.000
知道說語音合成TTS
link |
46:57.000
這樣的問題
link |
46:58.000
你的Attention的分數
link |
46:59.000
Attention的位置
link |
47:00.000
都應該由左向右
link |
47:01.000
那不如就直接把這個限制
link |
47:03.000
放進你的training裡面
link |
47:05.000
要求機器學到Attention
link |
47:06.000
就應該要由左向右
link |
47:09.000
那這件事怎麼做呢
link |
47:10.000
有一些關鍵詞彙
link |
47:12.000
我就放在這邊
link |
47:13.000
讓大家自己Google啦
link |
47:14.000
比如說Monotonic Attention
link |
47:15.000
或Location Aware的Attention
link |
47:17.000
那這個部分也是大坑
link |
47:20.000
也不細講
link |
47:21.000
那就留給大家自己研究
link |
47:24.000
還有一個東西叫做Bin Search
link |
47:26.000
Bin Search這個東西
link |
47:27.000
剛才助教在講解作業的時候
link |
47:30.000
也是有提到這個詞彙的
link |
47:32.000
Bin Search是什麼呢
link |
47:33.000
我們這邊舉一個例子
link |
47:35.000
在這個例子裡面
link |
47:36.000
我們假設說
link |
47:38.000
我們現在的Decoder
link |
47:41.000
它就只能產生兩個字
link |
47:45.000
我們假設說
link |
47:46.000
這個世界上就只有
link |
47:48.000
兩個可能的輸出
link |
47:50.000
一個叫做A
link |
47:51.000
一個叫做B
link |
47:52.000
假設世界上只有兩個字
link |
47:53.000
A跟B
link |
47:55.000
那對Decoder而言
link |
47:57.000
它做的事情就是
link |
47:58.000
每一次在第一個Time Step
link |
48:00.000
它在AB裡面決定一個
link |
48:02.000
然後決定了A以後
link |
48:03.000
再把A當作輸入
link |
48:05.000
然後再決定AB要選哪一個
link |
48:07.000
舉例來說
link |
48:08.000
它可能選B當作輸入
link |
48:09.000
再決定AB要選哪一個
link |
48:12.000
那在我們剛才講的Process裡面
link |
48:15.000
每一次Decoder
link |
48:16.000
都是選分數最高的那一個
link |
48:19.000
記不記得
link |
48:20.000
我們每次都是選Max的那一個
link |
48:23.000
所以假設A的分數0.6
link |
48:24.000
B的分數0.4
link |
48:26.000
Decoder第一次就會輸出A
link |
48:29.000
然後接下來
link |
48:30.000
假設B的分數0.6
link |
48:31.000
A的分數0.4
link |
48:32.000
Decoder就會輸出B
link |
48:34.000
然後再假設
link |
48:35.000
把B當作Input
link |
48:37.000
輸入已經有A有B了
link |
48:39.000
然後接下來
link |
48:40.000
A的分數0.4
link |
48:41.000
B的分數0.6
link |
48:42.000
Decoder就會選擇輸出B
link |
48:44.000
所以輸出就是A跟B跟B
link |
48:47.000
那像這樣子
link |
48:48.000
每次找分數最高的Token
link |
48:52.000
每次找分數最高的那個字
link |
48:53.000
來當作輸出這件事情
link |
48:55.000
叫做Greedy Decoding
link |
48:58.000
但是Greedy Decoding
link |
49:00.000
一定是更好的方法嗎
link |
49:02.000
有沒有可能
link |
49:03.000
我們在第一步的時候
link |
49:05.000
先稍微捨棄一點東西
link |
49:08.000
比如說
link |
49:09.000
第一步雖然B是0.4
link |
49:11.000
但我們就先選0.4這個B
link |
49:14.000
然後接下來
link |
49:15.000
我們選了B以後
link |
49:16.000
也許接下來的B的可能性
link |
49:18.000
就大增
link |
49:19.000
就變成0.9
link |
49:20.000
然後接下來
link |
49:21.000
第三個步驟
link |
49:22.000
B的可能性也是0.9
link |
49:24.000
如果你比較紅色的這條路
link |
49:27.000
跟綠色的這條路的話
link |
49:28.000
你會發現說
link |
49:29.000
綠色這條路
link |
49:30.000
雖然一開始
link |
49:31.000
第一個步驟
link |
49:32.000
你選了一個
link |
49:33.000
比較差的輸出
link |
49:35.000
但是接下來的結果
link |
49:37.000
是好的
link |
49:38.000
這個就跟天龍八部的
link |
49:39.000
真龍棋局一樣
link |
49:40.000
對不對
link |
49:41.000
先毒死自己一塊
link |
49:42.000
結果接下來反而贏了
link |
49:45.000
所以如果你比較紅色這條路
link |
49:46.000
跟綠色這條路
link |
49:47.000
紅色這條路
link |
49:48.000
第一步不好
link |
49:49.000
第一步好
link |
49:50.000
但接下來
link |
49:51.000
全部乘起來
link |
49:52.000
是不好比較差的
link |
49:53.000
然後綠色這條路
link |
49:54.000
一開始比較差
link |
49:55.000
但最終的結果
link |
49:56.000
其實是比較好的
link |
49:58.000
那我們其實是不是
link |
49:59.000
應該要選綠色這條路
link |
50:02.000
這就讓我想到什麼
link |
50:04.000
讓我想到謙博啦
link |
50:05.000
你知不知道
link |
50:06.000
我知道這個假設
link |
50:07.000
是你人生的轉捩點
link |
50:08.000
你正在決定
link |
50:09.000
要謙下去
link |
50:10.000
還是不謙下去
link |
50:12.000
然後謙下去
link |
50:13.000
雖然短時間內比較辛苦
link |
50:14.000
但也許未來是比較好的
link |
50:16.000
不謙下去
link |
50:17.000
你就去找工作
link |
50:18.000
短時間內可以賺到比較多錢
link |
50:19.000
但也許未來
link |
50:20.000
是比較不好的
link |
50:21.000
所以你到底
link |
50:22.000
應該是謙下去
link |
50:23.000
還是不謙下去呢
link |
50:25.000
我知道現在都沒什麼念博班啦
link |
50:26.000
所以我們上課的時候
link |
50:27.000
就是要忍不防的
link |
50:28.000
開始業配念博班
link |
50:29.000
這件事情
link |
50:32.000
好 那
link |
50:33.000
所以我們要怎麼找到
link |
50:34.000
這個最好的綠色這條路呢
link |
50:37.000
也許一個可能是
link |
50:38.000
報收所有可能的路徑
link |
50:40.000
但問題是
link |
50:41.000
我們實際上
link |
50:42.000
並沒有辦法報收
link |
50:43.000
所有可能的路徑
link |
50:44.000
因為實際上
link |
50:45.000
每一個轉捩點
link |
50:46.000
可以的選擇太多了
link |
50:48.000
如果是在對中文而言
link |
50:50.000
我們中文有四千個字啊
link |
50:52.000
所以這個數啊
link |
50:53.000
每一個地方的分岔
link |
50:54.000
都是四千個可能的路徑
link |
50:56.000
你走兩三步以後
link |
50:57.000
你就無法重舉了
link |
50:59.000
所以怎麼辦呢
link |
51:00.000
有一個演算法
link |
51:01.000
叫做bin search
link |
51:03.000
他用比較有效的方法
link |
51:05.000
找一個approximate
link |
51:07.000
找一個估測的solution
link |
51:09.000
找一個不是很精準的
link |
51:11.000
不是完全精準的solution
link |
51:13.000
這個技術叫做bin search
link |
51:15.000
這個也留給大家
link |
51:17.000
自己google
link |
51:20.000
好 那這個bin search
link |
51:22.000
這個技術到底有沒有用呢
link |
51:24.000
有趣的事就是
link |
51:25.000
他有時候有用
link |
51:28.000
有時候沒有用
link |
51:30.000
你會看到有些文獻告訴你說
link |
51:32.000
bin search
link |
51:33.000
是一個很爛的東西
link |
51:34.000
怎麼說呢
link |
51:35.000
舉例來說
link |
51:36.000
這篇paper叫做
link |
51:37.000
The Curious Case of Neurotech Degeneration
link |
51:41.000
這個任務要做的事情呢
link |
51:42.000
是sentence completion
link |
51:44.000
也就是機器先讀一段句子
link |
51:47.000
接下來呢
link |
51:48.000
他要把這個句子的後半段
link |
51:50.000
把它完成
link |
51:51.000
你給他一則新聞
link |
51:53.000
或者是一個故事的前半部
link |
51:55.000
他自己發揮他的想像創造力
link |
51:57.000
把這個文章
link |
51:59.000
把故事的後半部
link |
52:00.000
把它寫完
link |
52:02.000
那你會發現說
link |
52:03.000
bin search
link |
52:04.000
在這篇文章裡面
link |
52:05.000
一開始的時候就告訴你說
link |
52:07.000
bin search
link |
52:08.000
自己有問題啊
link |
52:09.000
如果你用bin search的話
link |
52:11.000
會發現說
link |
52:12.000
機器不斷講重複的話
link |
52:14.000
他不斷開始陷入鬼打牆啊
link |
52:16.000
無窮迴圈啊
link |
52:17.000
不斷說重複的話
link |
52:19.000
那如果你今天不是用bin search
link |
52:21.000
有加一些隨機性
link |
52:23.000
雖然結果不一定完全好
link |
52:25.000
但是看起來至少是
link |
52:27.000
比較正常的句子
link |
52:29.000
所以有趣的事情是
link |
52:31.000
有時候對decoder來說
link |
52:34.000
沒有找出分數最高的路
link |
52:36.000
反而結果是比較好的
link |
52:39.000
那這個時候你又覺得
link |
52:41.000
亂亂的對不對
link |
52:42.000
就是剛才前一頁的投影片才說
link |
52:44.000
要找出分數最高的路
link |
52:46.000
現在又突然又講說
link |
52:48.000
找出分數最高的路
link |
52:50.000
不見得比較好
link |
52:51.000
到底是怎麼回事呢
link |
52:53.000
那其實這個就是要看你的
link |
52:55.000
任務的本身的特性
link |
52:57.000
就假設一個任務
link |
52:58.000
他的答案非常的明確
link |
53:01.000
舉例來說
link |
53:02.000
什麼叫答案非常明確呢
link |
53:03.000
比如說語音辨識
link |
53:04.000
說一句話
link |
53:05.000
辨識的結果
link |
53:06.000
就只有一個可能嘛
link |
53:08.000
就那一串文字
link |
53:09.000
就是你唯一可能的正確答案
link |
53:11.000
並沒有什麼模糊的地帶
link |
53:12.000
我覺得對這種任務而言
link |
53:14.000
通常bin search就會比較有幫助
link |
53:16.000
那什麼樣的任務
link |
53:17.000
bin search比較沒有幫助呢
link |
53:19.000
就是你需要機器
link |
53:20.000
發揮一點創造力的時候
link |
53:23.000
這時候bin search
link |
53:24.000
就比較沒有幫助
link |
53:25.000
舉例來說在這邊的
link |
53:26.000
sentence completion
link |
53:27.000
給你一個句子
link |
53:28.000
給你故事的前半部
link |
53:30.000
後半部有無窮多可能的
link |
53:31.000
發展方式啊
link |
53:32.000
那這種需要有一些創造力的
link |
53:35.000
不是只有一個答案的任務
link |
53:38.000
往往會比較需要
link |
53:40.000
在decoder裡面加入隨機性
link |
53:43.000
還有另外一個decoder
link |
53:44.000
也非常需要隨機性的任務
link |
53:46.000
叫做語音合成
link |
53:48.000
TTS就是語音合成的縮寫
link |
53:51.000
那這個我印象很深刻
link |
53:52.000
因為我們實驗室一開始
link |
53:54.000
想要用這個
link |
53:55.000
sequence to sequence model
link |
53:57.000
做語音合成的時候
link |
53:58.000
有很長一段時間
link |
53:59.000
都做不起來
link |
54:01.000
都合不出聲音來
link |
54:02.000
有一次有個Google的人
link |
54:04.000
來我們實驗室visit
link |
54:05.000
我們就拿這個問題
link |
54:06.000
來跟他請教
link |
54:08.000
然後就說
link |
54:09.000
你們不知道在做TTS的時候
link |
54:12.000
decoder要加noise
link |
54:15.000
這聽起來很神奇
link |
54:16.000
完全違背就是正常的
link |
54:18.000
machine learning會做的想法
link |
54:19.000
你知道在machine learning
link |
54:21.000
有時候你在訓練的時候
link |
54:22.000
會加noise
link |
54:23.000
比如說你訓練的時候
link |
54:24.000
會加抓爆
link |
54:25.000
雖然我們這門課還沒有講抓爆
link |
54:27.000
但有些同學可能知道
link |
54:28.000
那如果你不知道的話
link |
54:29.000
你就想像說
link |
54:30.000
我們在訓練的時候
link |
54:31.000
我們會加上一些雜訊
link |
54:32.000
讓我們在訓練的時候
link |
54:34.000
機器看過更多不同的可能性
link |
54:36.000
所以訓練的時候
link |
54:37.000
會比較強健
link |
54:38.000
比較能夠對抗它
link |
54:40.000
在測試的時候
link |
54:41.000
沒有看過的狀況
link |
54:42.000
那沒有人會傻到說
link |
54:44.000
你在測試的時候
link |
54:45.000
居然還要加一些雜訊
link |
54:47.000
那也不是把測試的狀況
link |
54:48.000
弄得更困難
link |
54:49.000
你不是結果會更差嗎
link |
54:50.000
但TTS神奇的地方是
link |
54:53.000
測試的時候
link |
54:54.000
模型訓練好以後
link |
54:55.000
測試的時候
link |
54:56.000
你要加入一些雜訊
link |
54:58.000
合出來的聲音才會好
link |
55:00.000
這樣非常的神奇
link |
55:02.000
你用正常的decoder方法
link |
55:04.000
傳出來的聲音
link |
55:05.000
就有點像是機關槍那樣
link |
55:06.000
根本聽不太出來是人聲
link |
55:08.000
你要產生出比較好的聲音
link |
55:10.000
居然是需要一些隨機性的
link |
55:12.000
所以這也是一個
link |
55:13.000
非常神奇的地方
link |
55:14.000
有時候我們其實期待decoder
link |
55:17.000
有隨機性
link |
55:18.000
反而會得到比較好的結果
link |
55:21.000
這也許就呼應了
link |
55:22.000
一個英文的諺語
link |
55:24.000
就是要接受
link |
55:26.000
沒有事情是完美的
link |
55:28.000
真正的美
link |
55:29.000
也許就在不完美之中
link |
55:32.000
對於TTS或sentence Completion來說
link |
55:34.000
decoder找出最好的結果
link |
55:36.000
不見得是人類覺得最好的結果
link |
55:38.000
反而是奇怪的結果
link |
55:40.000
那你加入一些隨機性
link |
55:42.000
結果反而會是比較好的
link |
55:45.000
接下來還有另外一個問題
link |
55:48.000
大家知道說我們今天
link |
55:50.000
就拿我們的作業為例
link |
55:52.000
在我們的作業裡面
link |
55:54.000
我們評估的標準
link |
55:56.000
用的是Blue Score
link |
55:58.000
那Blue Score怎麼量呢
link |
55:59.000
Blue Score是你的decoder
link |
56:01.000
先產生一個完整的句子以後
link |
56:03.000
再去跟正確的答案
link |
56:05.000
一整句做比較
link |
56:07.000
我們是拿兩個句子
link |
56:08.000
之間做比較
link |
56:09.000
才算出Blue Score
link |
56:11.000
那我們在訓練的時候
link |
56:13.000
顯然不是這樣啊
link |
56:14.000
訓練的時候
link |
56:15.000
這邊每一個詞彙
link |
56:17.000
是分開考慮的
link |
56:19.000
訓練的時候
link |
56:20.000
我們minimize的是
link |
56:22.000
Cross Entropy
link |
56:23.000
Minimize Cross Entropy
link |
56:25.000
真的可以Maximize Blue Score嗎
link |
56:28.000
不一定
link |
56:29.000
因為這兩個根本就是
link |
56:30.000
他們可能有一點點的關聯
link |
56:32.000
但他們又沒有那麼直接相關
link |
56:34.000
他們根本就是兩個
link |
56:35.000
不同的數值嘛
link |
56:37.000
所以我們Minimize Cross Entropy
link |
56:39.000
不見得可以讓Blue Score
link |
56:41.000
Blue Score比較大
link |
56:43.000
所以你發現說
link |
56:44.000
在助教的程式裡面
link |
56:46.000
譬如說在
link |
56:47.000
助教在做Validation的時候
link |
56:49.000
並不是拿Cross Entropy
link |
56:51.000
來挑最好的model
link |
56:53.000
他並不是挑
link |
56:54.000
Cross Entropy最低的那個model
link |
56:56.000
而是挑Blue Score
link |
56:58.000
最高的那一個model
link |
57:00.000
所以我們訓練的時候
link |
57:01.000
是看Cross Entropy
link |
57:03.000
但是我們實際上
link |
57:04.000
你作業真正評估的時候
link |
57:06.000
看的是Blue Score啊
link |
57:07.000
所以你Validation Set
link |
57:08.000
其實應該考慮用Blue Score
link |
57:10.000
對不對
link |
57:11.000
那接下來有人就會想說
link |
57:12.000
那我們能不能
link |
57:13.000
在Training的時候
link |
57:14.000
就考慮Blue Score呢
link |
57:15.000
我們能不能夠訓練的時候
link |
57:17.000
就說我的Loss
link |
57:19.000
就是Blue Score成一個負號
link |
57:21.000
那我們要Minimize那個Loss
link |
57:23.000
假設你的Loss是
link |
57:24.000
Blue Score成一個負號
link |
57:25.000
那你就是Maximize Blue Score
link |
57:27.000
但是這件事實際上
link |
57:28.000
沒有那麼容易
link |
57:29.000
你當然可以把Blue Score
link |
57:30.000
當作你訓練的時候
link |
57:32.000
你要最大化的一個目標
link |
57:34.000
但是Blue Score本身很複雜
link |
57:35.000
它是不能為分的
link |
57:37.000
你把它當作你的Loss
link |
57:39.000
你根本不知道你要怎麼算
link |
57:41.000
回一點Descent
link |
57:42.000
這邊之所以採用Cross Entropy
link |
57:44.000
而且是每一個中文的字
link |
57:46.000
分開來算
link |
57:47.000
就是因為這樣我們才有辦法處理
link |
57:49.000
如果你是要計算
link |
57:50.000
兩個句子之間的Blue Score
link |
57:52.000
這一個Loss
link |
57:54.000
根本就沒有辦法做為分
link |
57:56.000
那怎麼辦呢
link |
57:57.000
這邊就教大家一個口訣啦
link |
57:59.000
這個口訣就是
link |
58:00.000
遇到你在Optimization
link |
58:03.000
無法解決的問題
link |
58:04.000
用RL硬勸一發就對了
link |
58:07.000
遇到你無法Optimize的Loss Function
link |
58:10.000
把它當作是RL的Reward
link |
58:13.000
把你的Decoder當作是Agent
link |
58:15.000
把它當作是RL
link |
58:16.000
Reinforcement Learning的問題
link |
58:18.000
硬做其實也是有可能可以做的
link |
58:21.000
那有人真的這樣試過嗎
link |
58:22.000
有人真的這樣試過
link |
58:24.000
我把Reference列在這邊
link |
58:26.000
給大家參考
link |
58:27.000
當然這是一個比較難的做法啦
link |
58:29.000
那並沒有特別推薦
link |
58:31.000
你在作業裡面用這一招
link |
58:34.000
好 那我們要講到
link |
58:36.000
我們剛才反覆提到的問題了
link |
58:38.000
就是訓練跟測試居然是不一致的
link |
58:42.000
測試的時候
link |
58:44.000
Decoder看到的是自己的輸出
link |
58:46.000
所以測試的時候
link |
58:47.000
Decoder會看到一些錯誤的東西
link |
58:50.000
但是在訓練的時候
link |
58:51.000
Decoder看到的是完全正確的
link |
58:54.000
那這個不一致的現象
link |
58:56.000
叫做Exposure Bias
link |
58:59.000
那假設Decoder在訓練的時候
link |
59:01.000
永遠只看過正確的東西
link |
59:03.000
那在測試的時候
link |
59:04.000
你只要有一個錯
link |
59:06.000
那就會一步錯 步步錯
link |
59:07.000
因為對Decoder來說
link |
59:08.000
他從來沒有看過錯的東西啊
link |
59:10.000
所以他看到錯的東西
link |
59:11.000
會非常的驚奇
link |
59:12.000
然後接下來
link |
59:13.000
他產生的結果可能都會錯掉
link |
59:15.000
所以要怎麼解決這個問題呢
link |
59:17.000
有一個可以思考的方向是
link |
59:19.000
給Decoder的輸入
link |
59:21.000
加一些錯誤的東西
link |
59:23.000
就這麼直覺
link |
59:24.000
你不要給Decoder
link |
59:25.000
都是正確的答案啊
link |
59:27.000
偶爾給他一些錯的東西
link |
59:29.000
他反而會學得更好
link |
59:32.000
這一招叫做Schedule Sampling
link |
59:35.000
它不是那個Schedule Learning Rate
link |
59:37.000
剛才助教有講Schedule Learning Rate
link |
59:38.000
那是另外一件事
link |
59:39.000
不相干的事情
link |
59:40.000
這個是Schedule Sampling
link |
59:43.000
Schedule Sampling其實很早就有了
link |
59:45.000
這個是15年的paper
link |
59:47.000
很早就有Schedule Sampling
link |
59:49.000
在還沒有Transformer
link |
59:50.000
只有LSTM的時候
link |
59:52.000
就已經有Schedule Sampling了
link |
59:55.000
這個Schedule Sampling這一招
link |
59:57.000
它其實會傷害到
link |
59:59.000
Transformer的平行化的能力
link |
01:00:02.000
那細節可以再自己去了解一下
link |
01:00:04.000
所以對Transformer來說
link |
01:00:06.000
它的Schedule Sampling
link |
01:00:07.000
另有招數跟傳統的招數
link |
01:00:10.000
跟原來最早在這個LSTM上
link |
01:00:13.000
被提出來的招數也不太一樣
link |
01:00:15.000
那我把一些reference
link |
01:00:16.000
列在這邊給大家參考
link |
01:00:20.000
那以上呢
link |
01:00:21.000
我們就講完了Transformer
link |
01:00:23.000
和種種的訓練技巧
link |
01:00:25.000
這個我們已經講完了Encoder
link |
01:00:27.000
講完了Decoder
link |
01:00:28.000
也講完它們中間的關係
link |
01:00:29.000
也講了怎麼訓練
link |
01:00:30.000
也講了種種的Deep
link |
01:00:33.000
好 那