back to index

[DLHLP 2020] Speech Synthesis (1/2) - Tacotron


link |
00:00.000
好,那這一堂課呢,我們要講 Speech Synthesis,我們要講語音合成。
link |
00:07.680
好,在這堂課裡面呢,在這門課裡面,我們已經講過語音辨識,輸入聲音輸出文字。
link |
00:12.800
我們已經講過Voice Conversion,Speaker Separation,輸入聲音輸出聲音。
link |
00:19.200
接下來,我們要講語音合成,Text to Speech的Synthesis,輸入文字,
link |
00:25.600
產生聲音。
link |
00:26.880
那在下課之前呢,我們來回顧一下語音合成的歷史。
link |
00:33.280
當然今天語音合成就是end to end,硬吹一發,今天沒有什麼東西不是硬吹一發,每一個東西都是硬吹一發。
link |
00:39.680
但是在硬吹一發之前,語音辨識是怎麼做的呢?
link |
00:46.080
所以在下課之前,我們來講語音合成是怎麼做的呢?所以在下課之前,我們來講一下在有硬吹一發之前,
link |
00:52.220
語音合成是怎麼做的?然後接下來進入硬吹一發的時代。
link |
00:58.620
然後我們還會講說在硬吹一發之後,硬吹一發的後時代我們做的事情是什麼?
link |
01:05.020
然後再講說我們怎麼控制TTS語音合成合出我們要的聲音。
link |
01:11.420
好,我們先講過去在還沒有硬吹一發的時候,人們是怎麼做語音合成的。
link |
01:17.560
好,那我找了一下語音合成的緣起。
link |
01:23.960
其實在18世紀就有人嘗試過語音合成了啦,不過那個是太久遠以前的東西,我找不到任何的demo。
link |
01:30.360
那我找到語音合成最早的demo是1939年有一個東西
link |
01:36.760
叫做Voder,Voder這個東西它是在紐約的世博會上展示的一個
link |
01:42.900
語音合成的系統,它聽起來像是這樣的。
link |
02:13.100
Let's see how you put expression into a sentence. Say she saw me with no expression.
link |
02:19.500
She saw me. Now say it in answer to these questions.
link |
02:25.900
Who saw you? She saw me. Whom did she see? She saw me.
link |
02:32.300
Did she see you or hear you? She saw me.
link |
02:37.440
所以你會看到說1939年就有語音合成,不過這個語音合成感覺有點像這種
link |
02:43.840
電子琴的感覺,它是操控這個琴鍵
link |
02:50.240
類似琴鍵的東西去合出不同的聲音。
link |
02:56.640
那有一個知名的語音合成系統是用IBM的computer做的,它是1960年代
link |
03:02.780
在Bill Lab做的,它是一個最早的早期的語音合成的demo
link |
03:09.180
它應該是最早嘗試讓機器做唱歌這件事情。
link |
03:15.580
你可以在網路上找到當年的demo,當年的demo聽起來像是這個樣子。
link |
03:21.980
He saw the cat.
link |
03:28.120
Mr. Watson, come here, I want you.
link |
03:34.520
To be or not to be, that is the question.
link |
03:40.920
Whether it is nobler in the mind to suffer the slings and arrows of outrageous fortune
link |
03:47.320
or to take arms against a sea of troubles,
link |
03:53.460
and by opposing end them, to die, to sleep.
link |
03:59.860
Singing in purely physical terms is essentially a matter of pitch and timing.
link |
04:06.260
In the next selection, the computer sings a familiar ditty.
link |
04:12.660
Daisy, Daisy, give me your answer too.
link |
04:18.800
Yes, Daisy, all for the love of you.
link |
04:25.200
It won't be a stylish marriage. I can't afford a carriage.
link |
04:31.600
But you look sweet upon the seat of a bicycle built for two.
link |
04:38.000
所以大家聽到說
link |
04:44.140
早年的1960年代的語音合成,合成出來的聲音就比較像是我們一般
link |
04:50.540
對機器人應該有的聲音的想像。
link |
04:54.640
所以我們通常想像說機器人講話就要講說我是機器人這樣的感覺。
link |
05:01.040
這個感覺聽起來才像是機器人講話。其實今天語音合成合出來的聲音都太真實了。
link |
05:07.440
它的機器感實在太少了。我相信過幾年就會開始有人做一些復古的語音合成。
link |
05:13.580
明明可以合出很好的聲音,但是我們用Voice Conversion的技術把它轉成奇怪的機器人風格。
link |
05:19.980
也許有人就會開始說,這樣有什麼用呢?這樣的用處就是也許機器合出來的聲音
link |
05:26.380
太像真人會讓人聽起來不舒服,所以故意給它合一些機器人的聲音,讓大家聽起來
link |
05:32.780
會比較舒服。剛才我們聽到說這個iVM的電腦
link |
05:38.920
Daisy這首歌,其實在一個知名的科幻電影《太空漫遊2001》裡面
link |
05:45.320
就有致敬了類似的橋段。在《太空漫遊2001》裡面有一個人工智慧的電腦
link |
05:51.720
叫做HAL,中文翻譯成HAL,英文是HAL
link |
05:58.120
HAL就是iVM的字母-1,HAL就是iVM-1
link |
06:04.260
HAL其實它也有出現在《腦念涅羅》裡面
link |
06:10.660
《腦念涅羅》這不重要,它出現在《太空漫遊2001》裡面
link |
06:17.060
這個人工智慧最終想把人類都殺了,但是卻被人類反殺
link |
06:23.460
在臨死之前,他就唱了一首歌,是他這一生第一次學到的歌,就是那個Daisy
link |
06:29.600
HAL就是在致敬iVM這台電腦。而這個iVM這個電腦
link |
06:36.000
是那種需要打卡的電腦,有房間那麼大的電腦,我相信在座各位可能都沒有
link |
06:42.400
真的用過這種電腦,我也沒有用過,我只是在灣區的計算機博物館看過
link |
06:48.800
那邊還有實際有iVM的員工在操縱那些電腦
link |
06:54.940
那個電腦是有人在展示的,然後有一個老爺爺在那邊
link |
07:01.340
他說他是一個iVM的員工,然後展示操作那個電腦可以看
link |
07:05.180
給你看,這樣我覺得說也許50年之後我就要去科工館做這個工作啊,然後就是展示說
link |
07:11.580
怎麼train deep learning給大家看啦,然後就會拿出一個2080Ti,然後所有人就很震驚
link |
07:17.720
哇,居然有這麼大的processing unit,SPU現在都是像米粒一樣大,然後就會講一些
link |
07:25.660
這個2080Ti它的processing能力只有你指甲上的SPU的1%喔
link |
07:32.060
然後大家就哇,這樣,然後2080Ti上有個風扇,然後就轉起來了
link |
07:38.460
哇,上面居然有風扇,好可怕喔,會不會把人捲進去啊,然後我就開始寫個程式
link |
07:44.600
Import個TensorFlow,然後大家就覺得,哇,太可怕了,這個人居然是用手寫程式
link |
07:51.000
因為那時候人都用意念在寫程式了,就是這個樣子
link |
07:54.320
你可能覺得用意念寫程式也許太超過了,但是50年後至少應該用natural language寫程式吧
link |
08:00.720
雖然不過現在教授都是用natural language在寫程式了
link |
08:04.060
我不知道大家聽不聽得懂這個梗就是了
link |
08:07.380
好,這不太重要,好,那下一個這個語音合成,就一般如果你是商用的系統啊
link |
08:13.520
其實過去最常用的語音合成的技術
link |
08:17.620
是用一個叫做concatenative approach
link |
08:20.940
那concatenative approach是什麼意思呢,這個概念非常的簡單,一講你就聽得懂了
link |
08:27.340
就是你有一個很大的Database
link |
08:30.660
這個Database裡面呢
link |
08:32.460
有非常非常多的聲音訊號
link |
08:35.280
如果今天你要合一段聲音出來,比如說你要機器說你好嗎
link |
08:40.900
好,那你就去聲音訊號裡面
link |
08:42.700
挑一個你出來
link |
08:44.740
挑一個好出來
link |
08:46.280
再挑一個嘛出來
link |
08:47.820
串起來就是語音合成的結果了
link |
08:50.900
可是你可能會想說,直接把聲音訊號挑出來
link |
08:54.980
再串起來會不會聽起來很怪啊,會不會聽起來很不自然啊,會
link |
08:59.080
所以你需要解這個問題
link |
09:00.620
所以怎麼挑出聲音訊號讓他們串起來是順的
link |
09:04.720
怎麼挑出合適的訊號讓他串起來是順的,這個就是一個可以研究的問題
link |
09:10.360
所以很多研究都集中在怎麼挑出聲音訊號
link |
09:14.200
讓他聽起來是順的,這個就是這個投影片上寫的
link |
09:17.800
Concatenative Loss,怎麼把它接起來
link |
09:20.860
會是接得
link |
09:22.400
比較好的
link |
09:23.160
這個技術
link |
09:24.200
link |
09:25.220
完全可以想像,它其實沒有你想像的那麼容易,因為你要把這個concatenative的部分做好,其實沒有你想像的那麼容易
link |
09:31.620
不過這個技術你完全可以想像大概是要怎麼做的
link |
09:36.740
那很多
link |
09:37.500
在網路上不是有很多影片都是把政治人物的聲音就截一個一個詞彙下來就可以讓他說出他本來
link |
09:43.900
沒有講話嗎
link |
09:44.920
其實大概就是類似的概念
link |
09:47.480
不過像這樣子的語音合成
link |
09:51.060
有很多的局限性
link |
09:53.120
一個局限性是
link |
09:54.400
他沒有辦法任意合隨便某一個人的聲音
link |
09:57.720
如果你要合某一個人的聲音
link |
09:59.780
那你得要在Database裡面有接近那個人的聲音才辦得到
link |
10:04.900
你要合男生的聲音那你的Database要有男生的聲音
link |
10:07.200
你要合女生的聲音你的Database要合女生的聲音
link |
10:10.280
所以你如果要讓你的機器有
link |
10:12.320
很豐富的他講的話要很有異樣頓挫要非常豐富那你必須要收集一個
link |
10:18.720
非常大量的資料庫
link |
10:21.020
把各式各樣你合成時的時候需要的素材
link |
10:24.860
通通放在資料庫裡面
link |
10:26.920
你才有辦法合出
link |
10:28.200
你想要合的聲音
link |
10:30.500
而且你今天在
link |
10:32.540
用這個語音合成系統的時候
link |
10:34.600
這個資料庫必須要存在你的電腦裡面
link |
10:39.220
如果你比如說像今天iPhone4
link |
10:42.280
在離線的時候他也是可以合出聲音的
link |
10:44.840
那你在離線的時候要做合成的時候顯然你的Local端必須要存在一個非常大的資料庫才有辦法
link |
10:51.240
合成出聲音出來
link |
10:53.300
所以Concatenative這個做法
link |
10:55.340
雖然他
link |
10:56.620
過去比較常被用在Sound系統上
link |
10:59.960
不過他還是有很大的侷限性
link |
11:05.340
進入了機器學習的時代以後大家就會想說那能不能夠用Machine Learning的方法
link |
11:11.740
來進行合成呢那這個這系列的做法
link |
11:14.800
就叫Parametric
link |
11:16.340
的Approach
link |
11:17.360
那最早當然是用HAM
link |
11:20.180
那後來
link |
11:21.200
也有用一些
link |
11:22.480
Deep Learning Base
link |
11:23.760
的方法
link |
11:24.280
那其中最知名的一套這種Parametric Base的語音合成的Toolkit
link |
11:30.680
叫做HTS
link |
11:32.980
但是這種Parametric Base的方法
link |
11:35.800
其實也沒有你想像的那麼簡單
link |
11:39.380
這個下面是這個從HTS的官網上截下來的圖啦
link |
11:43.980
那這個是我們就不細講
link |
11:45.780
那你可能會想像說HAM就是一個Generative的Model啊
link |
11:50.140
我們今天HAM的聲音不就從一個Hidden Mark of Model裡面去
link |
11:53.980
Sample東西出來
link |
11:56.020
聽起來
link |
11:56.780
也許就是一段語音了
link |
11:59.100
但是你想想看假如我們今天叫HAM Generate聲音訊號
link |
12:02.940
是他覺得機率最高的聲音訊號
link |
12:06.000
那從每一個State裡面
link |
12:08.820
Sample出來機率最高的聲音訊號
link |
12:11.380
其實都是同一段對不對
link |
12:13.180
因為每一個State都是一個固定的Gaussian Distribution
link |
12:15.980
固定的Gaussian Distribution裡面
link |
12:18.040
Sample
link |
12:19.320
機率最大的
link |
12:20.080
一個Gaussian Distribution裡面機率最大的Sample
link |
12:24.940
就是他的Mean啊
link |
12:26.480
那如果你今天要讓機器產生他覺得機率最高的那段聲音
link |
12:32.360
其實會有很長一段聲音都是同樣的Vector
link |
12:34.920
其實非常的奇怪
link |
12:36.200
那過去當然有一些方法來解這個問題
link |
12:39.020
不過都
link |
12:39.780
頗為
link |
12:40.820
複雜
link |
12:41.580
那這個就不是我們今天可以細講的
link |
12:43.620
總之過去
link |
12:44.660
當然有用HAM DMN的方法來做Speed Synthesis
link |
12:47.720
他們不是M2M的他們叫Parametric Approach
link |
12:51.040
不過他們都
link |
12:52.080
頗為複雜
link |
12:54.380
那在進入M2M的時代硬券一發之前有一個最接近硬券一發但
link |
13:00.780
還不是硬券一發的想法
link |
13:02.560
叫做
link |
13:03.600
BigBoys
link |
13:04.360
這個是
link |
13:05.120
百度做的
link |
13:06.400
他是輸入一段文字輸出一段聲音訊號
link |
13:10.000
中間有很多的Module
link |
13:11.780
把這些Module串起來
link |
13:13.320
就可以從文字
link |
13:14.860
到聲音訊號
link |
13:16.140
那這裡面有什麼樣的Module呢
link |
13:18.440
第一個Module叫做Graphing to Phoning的Module
link |
13:21.780
Graphing to Phoning的意思是說給機器看一段文字的時候
link |
13:25.860
機器要從這段文字
link |
13:27.660
去猜測他的發音
link |
13:30.220
舉例來說你輸入一串字母你輸入CAT這三個字母
link |
13:34.580
那這三個字母應該怎麼唸呢
link |
13:36.880
C到底要怎麼唸呢
link |
13:38.160
他這邊是唸K嗎
link |
13:39.440
還是唸CH
link |
13:40.460
還是沒有發音呢
link |
13:41.480
這個
link |
13:42.260
需要由Graphing to Phoning這個Module來判斷
link |
13:45.060
假設今天Graphing to Phoning這個Module把CAT判斷說他就是發音
link |
13:50.940
K
link |
13:51.960
A跟T兩個刻
link |
13:55.800
然後把他決定要發音的結果
link |
13:58.120
輸入給另外兩個Module
link |
14:00.420
一個叫做Duration Prediction的Module
link |
14:02.980
這個Duration Prediction Module他做的事情就是
link |
14:05.540
給你一串封鈴
link |
14:07.320
他去判斷說
link |
14:08.600
每一個封鈴他的長度應該是多少
link |
14:11.680
舉例來說他可能說這個K我要發0.1秒
link |
14:15.780
這個A我要發0.5秒
link |
14:18.340
這個T我要發0.1秒
link |
14:20.640
這也是一個Network這個Network自己決定說每一個封鈴他要唸多長
link |
14:25.500
還有一個東西叫做Fundamental Frequency的Prediction Module
link |
14:29.600
這個Fundamental Frequency是什麼呢
link |
14:32.160
你可以把它想成就是
link |
14:33.940
音高
link |
14:34.720
今天機器決定說你的音高要有多高
link |
14:39.060
這個Fundamental Frequency
link |
14:40.600
其實他就是你的聲帶震動的
link |
14:44.960
頻率
link |
14:45.720
所以今天要讓機器去預測說
link |
14:48.540
人在發這些聲音的時候
link |
14:50.580
那你聲帶震動的頻率應該是多少
link |
14:54.420
那有一些封鈴啊
link |
14:56.480
有一些這個因素啊
link |
14:58.260
人在發音的時候聲帶是
link |
15:00.560
沒有震動的
link |
15:01.600
那如果是
link |
15:02.620
不需要震動聲帶就可以發的聲音
link |
15:04.920
那這邊Output就Output個XX
link |
15:07.480
不需要聲帶震動
link |
15:09.280
好那你這邊Output了Fundamental Frequency
link |
15:12.860
那我們有封鈴
link |
15:14.660
有每一個封鈴要輸出的長度
link |
15:16.960
有每一個封鈴的F0也就是他的音高
link |
15:20.280
把這三個東西湊起來丟到語音合成的一個Module
link |
15:25.160
這也是一個Network他吃這三個東西當作輸入然後就吐出一段聲音
link |
15:30.520
在這個圖上啊
link |
15:31.800
每一個這個藍色的這個Module啊
link |
15:35.140
他都是一個D的Network
link |
15:37.960
其實
link |
15:38.720
只要把他串起來M to M的Trend
link |
15:41.800
他就是
link |
15:43.080
M to M的硬Trend一發的Module
link |
15:45.640
不過在第一版的Deep Voice裡面呢
link |
15:48.200
不是M to M的Trend的每一個Module是分開Trend的
link |
15:51.780
然後再把他接起來
link |
15:53.560
那我覺得
link |
15:54.600
這個是賣最接近
link |
15:56.640
硬Trend一發M to M的一部
link |
15:59.200
就好像說
link |
16:00.220
生物從海洋直接走到陸地那這個呢
link |
16:03.040
Deep Voice的第一代就是一個兩棲類他已經爬到陸地上
link |
16:08.420
Deep Voice的第三代
link |
16:10.220
就是M to M的了
link |
16:12.780
好那我們在這邊呢
link |
16:14.820
休息休息一下我們11點半再回來然後接下來呢就要講真正
link |
16:21.220
M to M的TTS
link |
16:31.980
好那接下來呢我們要來講Tekotok
link |
16:35.300
他是一個真正M to M的
link |
16:38.880
語音合成系統
link |
16:41.700
Tekotok的這個Teko是什麼意思呢Teko呢
link |
16:46.820
是一種食物啊就可能中文翻譯成墨西哥捲餅吧反正就是類似這樣子的
link |
16:53.220
食物
link |
16:54.240
那為什麼後面要加Tron呢
link |
16:56.800
這個Tron
link |
16:57.820
沒有什麼意思這個Tron只是為了要增加他的科技感而已
link |
17:02.440
那這個第一作者呢
link |
17:05.260
link |
17:06.540
王宇軒我有聽過他的talk他的talk裡面有說這個Tekotron本來並沒有要叫Tekotron
link |
17:12.940
本來叫做Tokotron
link |
17:15.500
Talk就是
link |
17:16.780
說話的那個意思說話的那個talk
link |
17:19.340
再加Tron一樣沒有任何意思就是為了要增加他的科技感
link |
17:23.680
本來叫Tokotron
link |
17:25.220
後來覺得叫做Tekotron更有感了所以就叫做Tekotron
link |
17:29.060
然後在這個文章裡面呢他們還很有趣的加了一個註解
link |
17:33.680
有星號的作者
link |
17:35.720
是喜歡Tako的
link |
17:38.020
然後有加這個Dagger的作者
link |
17:41.100
是喜歡Susie的這樣子他們很認真的告訴我們他們的食物偏好是什麼
link |
17:48.260
那Tekotron他有兩個版本第一個版本發表在InterSpeech的17年的InterSpeech
link |
17:54.660
第二個版本發表在18年的icast
link |
17:57.220
那其實在Tekotron之前啊
link |
18:01.320
就已經有一些end-to-end TTS的嘗試
link |
18:05.920
Tekotron他是input
link |
18:08.740
character
link |
18:10.020
input字母
link |
18:11.300
然後直接輸出
link |
18:12.840
就是Spectrogram
link |
18:14.880
那Spectrogram
link |
18:16.160
跟Waveform啊他其實只差了一個face的資訊
link |
18:21.280
所以你要從Spectrogram轉成Waveform
link |
18:23.340
你不見得需要非常強的recorder你不見得需要Machine Learning Base的recorder
link |
18:29.740
你用一些raw base的方法比如說Graphenly
link |
18:32.800
你就可以直接把Spectrogram
link |
18:34.860
加上face
link |
18:36.380
轉成Waveform
link |
18:38.180
好這個是Tekotron
link |
18:39.720
那其實在Tekotron之前就已經有一些end-to-end的語音合成的嘗試
link |
18:46.120
舉例來說有人嘗試說直接inputphony
link |
18:49.700
然後輸出straight
link |
18:51.500
他的acoustic feature
link |
18:54.060
那phony跟character比起來當然還是差了一層啦
link |
18:58.420
比較接近
link |
19:00.460
聲音的訊號
link |
19:01.740
就你今天
link |
19:03.020
如果你像我們剛才在看那個
link |
19:06.100
deep voice的第一個版本的時候他就有一個module
link |
19:09.420
先把character轉成phony然後再去做接下來的事情
link |
19:14.540
所以用phony可能還是比character還要容易一些
link |
19:17.620
然後這邊的output啊
link |
19:18.900
是straight的acoustic feature
link |
19:22.980
也就是他不是一般的acoustic feature
link |
19:25.540
所以acoustic feature要丟到一種叫做straight的recorder裡面
link |
19:29.640
才能夠合出聲音訊號來
link |
19:32.720
那還有另外一個嘗試叫做character-to-wave
link |
19:35.780
那如果是character-to-wave的話呢
link |
19:37.840
他的輸入
link |
19:38.600
就是character
link |
19:40.400
而他的輸出呢
link |
19:41.680
是sample RN這個recorder的
link |
19:44.740
acoustic feature
link |
19:46.020
所以過去已經有一些end-to-end TTS的嘗試
link |
19:50.120
那Tabletron呢他是最狂的他的輸入跟輸出是最end-to-end的
link |
19:55.740
他輸入直接就是字母
link |
19:57.280
等於就你直接把文字丟進去沒有做任何處理
link |
20:00.100
希望never自己知道這每一個character每一個字母
link |
20:03.160
要怎麼發音
link |
20:04.200
輸出他雖然不是直接產生waveform
link |
20:06.760
但他產生
link |
20:07.780
spectrogram
link |
20:08.540
spectrogram跟waveform中間也只差了一個linear的transform而已
link |
20:12.900
好那Tabletron他到底是什麼樣的network架構呢其實
link |
20:19.300
講的大致一點大略說來他就是sequence-to-sequence model
link |
20:25.700
加attention
link |
20:26.220
就說完了
link |
20:28.000
就說完了就這樣
link |
20:29.020
所以input
link |
20:30.300
有一個encoder
link |
20:32.100
然後他有一個attention
link |
20:34.400
然後他有一個
link |
20:35.680
decoder
link |
20:36.960
那除了這個typical sequence-to-sequence model加attention的架構以外他還有一個
link |
20:42.340
post-processing的架構
link |
20:44.380
然後
link |
20:45.160
就產生
link |
20:46.440
spectrogram
link |
20:47.960
好那接下來呢我們就是來看Tabletron裡面的每一個module
link |
20:52.580
我們先來看encoder
link |
20:54.880
那這個encoder的目的啊
link |
20:56.920
就是吃一串文字
link |
20:58.720
吃一串字母
link |
21:00.000
然後呢把這串字母呢
link |
21:02.300
轉成一堆向量
link |
21:04.600
轉成latent representation
link |
21:06.920
再丟給attention的module
link |
21:08.960
跟decoder
link |
21:09.720
所以這個encoder他扮演的角色啊
link |
21:12.800
類似graphic-to-phonic的module
link |
21:15.600
我們剛才有看到說在deep voice裡面有一個graphic-to-phonic的module
link |
21:19.200
把character
link |
21:20.480
轉成phonic
link |
21:22.000
把字母
link |
21:23.280
轉成音速然後接下來的module才知道根據音速要怎麼發音
link |
21:27.380
所以encoder他這邊的作用
link |
21:29.440
像是把輸入的character
link |
21:31.740
轉成phonic
link |
21:32.760
告訴接下來的decoder的module還有attention的module說
link |
21:36.080
這些character
link |
21:37.120
他應該要怎麼發音
link |
21:39.940
所以encoder的輸入啊直接就是字母
link |
21:42.500
加上標點符號
link |
21:44.040
你甚至可以把標點符號當作輸入讓機器
link |
21:46.600
知道說看到我的逗號就要停頓
link |
21:49.420
看到驚嘆號就要表現出很驚嘆的樣子
link |
21:51.980
看到問號這個音調就要提高等等
link |
21:55.040
你可以把標點符號
link |
21:56.320
當作encoder的輸入
link |
21:58.380
好那這些字母呢通過一個transform變成input的embedding
link |
22:02.460
然後通過一個prenet沒有什麼神奇的就是幾層Fully Connected
link |
22:07.840
Feedforward Network那prenet裡面呢
link |
22:09.880
通常有加dropout
link |
22:12.440
好那prenet的輸出呢
link |
22:14.480
會再丟給一個叫做CBHG的module
link |
22:18.580
CBHG這個module啊
link |
22:20.380
就蠻複雜的
link |
22:21.920
不過我們這邊就很快的帶過去
link |
22:24.720
好這個CBHG的module是什麼樣子呢
link |
22:27.280
他這個是CBHG module input
link |
22:29.840
然後他通過這個1D的convolutional的filter bank也就是說他有一大堆的filter
link |
22:36.240
好那這個filter的那個
link |
22:37.780
receptive fill啊大小還是不太一樣的
link |
22:41.360
好接下來呢他有一個max pooling along time
link |
22:45.200
也就是把相鄰的feature啊
link |
22:47.240
做一個有點類似
link |
22:48.520
這個smoothing這樣的動作讓相鄰的feature比較像一點有點像是平滑化這樣的動作
link |
22:55.180
然後這邊有一個1D convolution layer然後做一個residual的connection
link |
22:59.540
然後再把他丟給highway的network然後再丟給bi-directional的GRU然後最終呢
link |
23:05.940
產生一些output
link |
23:07.220
如果這部分你聽得不是很懂的話反正沒有關係就記得說
link |
23:10.800
輸入
link |
23:11.580
一串character
link |
23:12.860
輸出就是每一個character變成一個相鄰就結束了
link |
23:17.460
那CBHG這個名字應該是來自於
link |
23:20.540
convolutional的bank
link |
23:23.340
加上
link |
23:24.620
highway network
link |
23:25.900
加上GRU所以CBHG
link |
23:32.300
這樣子
link |
23:34.340
好那我們這邊呢就不打算細講CBHG啊你可能會問說為什麼要用CBHG啊要用CBHG
link |
23:40.740
才可以嗎不用CBHG不會好嗎
link |
23:43.560
可以不用CBHG在第二個version的tabletrump裡面CBHG就默默的消失了
link |
23:49.960
他就變成說
link |
23:51.500
input文字然後呢產生character embedding再通過三層的convolutional layer
link |
23:57.900
再通過bi-directional的LSTM
link |
24:00.200
就得到這邊的embedding
link |
24:01.480
所以看起來CBHG
link |
24:03.020
不是非常必要的所以我們就不會花太多時間講CBHG這個東西
link |
24:07.880
好接下來講attention的部分
link |
24:09.920
那attention就是
link |
24:11.720
你知道的那個attention
link |
24:14.280
那今天在做語音合成跟語音辨識他們的attention有一個共同的地方就是
link |
24:20.160
audio跟text
link |
24:21.700
他們是monotonic的line
link |
24:25.540
也就是
link |
24:26.300
文字跟聲音
link |
24:27.840
他們是有一個
link |
24:29.120
共同的順序的
link |
24:30.660
等一下我們之後還會再來回頭來看attention的問題
link |
24:34.240
今天你輸入呢這一個timestamp的東西這一個
link |
24:38.600
character他對應的embedding
link |
24:40.380
就會給我們
link |
24:41.660
這一段
link |
24:42.440
聲音訊號
link |
24:43.200
今天在這個attention的metric上
link |
24:45.500
他的表示的意思是說
link |
24:47.560
縱軸
link |
24:48.580
代表的是
link |
24:49.600
encoder的輸出
link |
24:52.420
縱軸的
link |
24:53.440
每一個值縱軸的每一個點
link |
24:56.000
就代表了encoder輸出的一個embedding
link |
24:59.060
那橫軸
link |
25:00.100
代表今天在做decode的時候
link |
25:02.660
我們今天每一個embedding
link |
25:04.440
會輸出幾個timestamp
link |
25:06.240
所以今天這個圖上的意思就是說
link |
25:08.540
這邊有一個embedding
link |
25:09.820
這個embedding
link |
25:10.840
會給輸出的
link |
25:12.120
這樣子的
link |
25:13.400
這樣子的位置
link |
25:15.460
那所以今天你可以想像說
link |
25:17.500
這個東西啊就是應該是一條斜直線
link |
25:21.340
他的目標啊
link |
25:22.880
有點像是model duration
link |
25:25.180
我們剛剛在講deep voice的時候我們看到說
link |
25:27.740
Machine需要去預測說每一個phony
link |
25:30.040
要發音多長
link |
25:31.320
那attention的作用
link |
25:32.860
就像是要機器自動學出說
link |
25:35.680
每一個character所代表的embedding
link |
25:39.260
他在decoder那邊
link |
25:40.800
會產生多長的聲音訊號
link |
25:43.360
如果你今天你的attention的matrix長得像是這樣子
link |
25:47.960
是一條斜的線
link |
25:49.500
那通常是好的
link |
25:51.540
如果你今天感覺怪怪的他不是一條斜線感覺很糊那往往就代表你今天合出來的結果
link |
25:57.940
不太好
link |
25:58.720
你的model在訓練的時候出了什麼問題
link |
26:01.020
所以他沒有辦法合出好的聲音
link |
26:03.580
這個是attention的部分我們之後會再細講
link |
26:07.680
好那decoder的部分呢
link |
26:09.460
decoder就是吃
link |
26:11.260
attention的結果
link |
26:12.540
然後產生聲音訊號
link |
26:15.860
那這個decoder啊
link |
26:17.400
他就是一般sequence to sequence model裡面的decoder
link |
26:21.760
你丟一個zero vector進去代表其實
link |
26:25.340
然後這個zero vector呢
link |
26:26.880
通過一個pre-net再丟給RNN
link |
26:29.440
這個RNN呢
link |
26:30.720
會去做attention這件事情
link |
26:33.020
產生attention的context vector
link |
26:35.320
再丟給下一層的RNN
link |
26:37.880
然後產生出輸出
link |
26:40.180
然後今天在Tagotron裡面
link |
26:42.980
decoder有一個比較特別的地方是
link |
26:45.800
他不是一次只產生一個vector
link |
26:48.360
他會一次
link |
26:49.900
產生好幾個vector
link |
26:52.200
decoder這邊產生出來的輸出
link |
26:54.500
就是
link |
26:55.540
male spectrogram
link |
26:56.560
所以我們今天在訓練的時候我們就會要decoder呢
link |
26:59.880
產生
link |
27:00.900
male spectrogram
link |
27:02.180
但是今天我們不是一次只產生一個
link |
27:05.520
male spectrogram的vector
link |
27:07.060
我們會一次要這個RNN
link |
27:09.360
產生好幾個vector
link |
27:11.920
產生出來的vector數目呢
link |
27:13.700
叫做R
link |
27:15.760
那在這個decoder的第一版裡面這個R
link |
27:19.080
可能可以設3
link |
27:20.360
可能可以設5
link |
27:22.160
那為什麼要讓這個decoder一次產生數個vector呢
link |
27:26.240
為什麼不是像一般的sequence to sequence model decoder一樣一次只產生一個vector呢
link |
27:31.360
這個可能的原因是因為聲音訊號
link |
27:34.440
非常非常的長
link |
27:37.000
我們今天在產生聲音訊號的時候
link |
27:39.040
每一個male spectrogram這種acoustic feature裡面的vector
link |
27:43.400
才代表了非常短的一段聲音訊號通常是代表了0.01秒的聲音訊號
link |
27:50.300
所以如果你今天要產生一段一秒鐘的聲音
link |
27:53.380
那你要產生100個vector
link |
27:55.940
他這100個vector拼起來
link |
27:58.500
才是一秒鐘的聲音
link |
28:00.300
你要產生100個vector才是一秒鐘的聲音
link |
28:03.360
所以今天這個sequence to sequence的model
link |
28:05.920
對decoder那邊來說
link |
28:07.960
他的負擔是很大的
link |
28:10.000
一般sequence to sequence model應用的情境不一樣
link |
28:13.080
我們之前在講sequence to sequence model的時候
link |
28:15.640
說我們可以用在
link |
28:17.420
翻譯上我們可以用在語音辨識上
link |
28:20.240
你把sequence to sequence model用在語音辨識上的時候
link |
28:23.060
他的輸出一句話可能了不起
link |
28:25.100
十幾二十個文
link |
28:26.380
所以你的decoder
link |
28:27.660
只需要產生
link |
28:28.940
十幾二十個token
link |
28:30.740
就結束了
link |
28:31.760
但是今天
link |
28:32.780
如果你要把decoder把sequence to sequence model用在語音和聲上
link |
28:37.140
那你必須要產生一個
link |
28:39.180
非常長的sequence
link |
28:41.480
你要產生
link |
28:42.760
超過上百個可以產生超過上百個vector的sequence
link |
28:47.120
你的decoder
link |
28:48.140
必須要產生超過上百個vector
link |
28:50.700
才能夠合出
link |
28:51.980
一段短短的聲音訊號
link |
28:54.280
那RNN在產生這種上百個vector的時候在產生這種非常長的sequence的時候
link |
28:59.920
很容易壞掉
link |
29:00.940
而且RNN產生長的sequence
link |
29:03.240
是非常沒有效率
link |
29:04.780
因為產生長的sequence
link |
29:05.800
它是sequential的
link |
29:07.580
你今天sequence有多長
link |
29:09.120
你就要花多長的時間你要花多少的timestamp
link |
29:11.940
去產生這個sequence
link |
29:14.240
所以就有了這樣子的一個一次產生R的frame產生R的vector的想法
link |
29:20.380
如果你今天一次產生
link |
29:22.180
三個vector
link |
29:23.460
那這個
link |
29:24.480
要產生的這個sequence的長度
link |
29:26.780
就減少三倍
link |
29:28.320
你RNN的這個decoder
link |
29:30.120
他今天要decode的長度
link |
29:32.160
就變成原來的三分之一
link |
29:33.960
如果你這個R是一次產生五個vector
link |
29:37.040
那你今天decode的sequence長度
link |
29:39.340
就變成
link |
29:40.360
五分之一
link |
29:41.120
那這樣子的好處就是
link |
29:42.660
讓你
link |
29:43.440
減少你的運算量讓你在訓練的時候
link |
29:46.760
更容易一點
link |
29:47.780
所以在今天在Tacotron裡面一個有趣的設計是
link |
29:51.360
decoder一次
link |
29:52.400
產生數個vector
link |
29:54.960
所以這個是
link |
29:56.240
Tacotron第一代的一個非常自豪的獨特的設計
link |
30:00.080
但是實際上有趣的地方是在第二代裡面
link |
30:02.880
R就設1
link |
30:04.680
所以就跟一般的decoder一樣也沒一次產生多個vector
link |
30:07.480
R就設1反正也
link |
30:09.020
秤得起來就是了
link |
30:11.080
好那這個decoder在第一個time step的輸出啊會變成第二個time step的輸入
link |
30:16.700
認為在第一個time step你是一次輸入三個vector
link |
30:19.520
要把哪一個vector
link |
30:21.060
當作下一個time step的輸入呢
link |
30:23.620
有各種不同的做法你可以直接把三個vector串起來當作下一個time step的輸入
link |
30:28.220
不過在第一代的Tacotron裡面就用了非常簡單的設計把最後一個vector
link |
30:34.360
如果你一次產生三個vector把第三個vector當作下一個time step的輸入
link |
30:40.240
把第二個time step吃一個vector當作進去然後就吐出接下來要產生的三個vector
link |
30:45.360
然後再把最後一個vector當作下一個time step的輸入
link |
30:48.440
再產生三個vector
link |
30:49.980
然後直到把整段聲音訊號產生完
link |
30:52.800
這個東西
link |
30:53.820
就是Tacotron的decoder
link |
30:55.600
好那這個pre-net裡面呢一樣要有抓抱這個pre-net裡面的抓抱呢等一下會看到說它
link |
31:02.000
扮演了非常重要的角色
link |
31:05.060
今天在訓練decoder的時候跟做語音辨識一樣我們一樣需要
link |
31:10.180
teacher forcing
link |
31:11.720
那有一個我們還沒有講過的東西是
link |
31:14.280
如果我們用teacher forcing
link |
31:16.580
每一次機器在產生sequence的時候呢
link |
31:19.920
它都會看到正確的答案但是因為在測試的時候是沒有正確的答案的啊
link |
31:25.300
所以會造成訓練跟測試的一個mismatch
link |
31:29.400
那沒有關係
link |
31:30.660
反正在Tacotron裡面的decoder你的pre-net裡面有抓抱
link |
31:34.500
這個抓抱呢它的特色就像是
link |
31:37.580
Schedule sampling一樣
link |
31:39.120
它雖然說你這邊在training的時候輸入的是正確答案
link |
31:42.440
在training的時候你輸入的是正確答案那pre-net裡面有一些抓抱它可以模擬你在測試的時候
link |
31:48.340
你的RNN有可能出錯的情形
link |
31:51.400
在做這個decoder的時候你還要有一個module去決定說
link |
31:57.800
什麼時候應該結束
link |
32:00.100
我們之前在講語音辨識的時候知道說我們只要產生一個特殊的token這個特殊的token代表
link |
32:06.500
辨識結束
link |
32:07.520
那RNN decoder就不會再decode東西了
link |
32:11.120
但是今天在語音合成的時候不一樣
link |
32:14.960
在語音合成的時候我們產生出來的東西並不是
link |
32:18.020
token並不是token是continuous的vector
link |
32:22.120
所以decoder怎麼知道什麼時候應該要結束呢
link |
32:24.920
所以這邊加了一個額外的module
link |
32:26.980
這個module叫做我們要不要結束了
link |
32:30.300
那這個module就是一個binary的classifier
link |
32:33.880
它把RNN的hidden layer把它接出來把RNN的
link |
32:38.240
memory裡面輸出的值把它接出來丟到這個classifier裡面
link |
32:42.840
然後這個classifier就去判斷說現在
link |
32:44.900
要結束還是不要結束
link |
32:46.940
如果這個classifier判斷不要結束
link |
32:49.240
好那RNN的輸出就丟到下一個timestamp
link |
32:52.320
就再產生新的output
link |
32:54.100
然後再判斷一下要不要結束不要結束
link |
32:56.420
好那RNN的輸出再丟到下一個timestamp
link |
32:59.480
再產生新的output再判斷要不要結束現在要結束了
link |
33:02.820
那就結束了
link |
33:03.840
這個綠色的module它就是一個binary的classifier
link |
33:06.660
它吃RNN的hidden layer然後
link |
33:09.220
output就是
link |
33:10.240
一個scalar
link |
33:11.520
決定說現在要不要結束它output就是一個數值
link |
33:14.340
這個數值小於0.5
link |
33:15.620
就結束小於0.5就是不結束大於0.5就代表結束
link |
33:22.020
這個是decoder
link |
33:25.360
在PanelTron裡面的decoder之後啊還有一個
link |
33:28.940
Post-processing的network
link |
33:30.980
這個Post-processing的network是什麼呢
link |
33:33.280
這個Post-processing的network啊
link |
33:35.080
它也是一個CBHG在第一代裡面是一個CBHG在第二代裡面呢就是一堆的
link |
33:41.480
convolution
link |
33:42.240
這個CBHG啊它會把RNN輸出來的這些vector當作輸入
link |
33:48.140
然後再吐出另外一排vector
link |
33:53.000
那為什麼我們要把RNN的輸出丟到CBHG裡面再吐出另外一排vector呢
link |
33:58.880
因為今天RNN在產生的時候
link |
34:01.180
它是call久了
link |
34:02.220
就是它這些向量是按照順序產生的
link |
34:05.540
這個Spectrogram裡面的這些acoustic feature
link |
34:08.100
它是按照順序一個一個產生的
link |
34:10.660
所以今天每次它都只能夠看前面已經產生的vector然後產生後面的vector
link |
34:16.540
所以也許在某一個步驟它
link |
34:18.840
再產生新的vector以後它覺得想要回頭過來改
link |
34:22.440
那已經沒有機會了你看到後面的東西覺得之前產生的不太好想要做來改
link |
34:26.520
然後再回頭過來改已經沒有機會了
link |
34:29.080
那怎麼辦呢
link |
34:30.120
加上一個後處理的network
link |
34:32.680
這個後處理的network再給你一次修正的機會
link |
34:35.740
這個後處理的network會把
link |
34:37.020
整個句子都看過把整個句子讀進來再產生
link |
34:41.380
新的輸出
link |
34:43.160
然後今天在訓練的時候啊
link |
34:45.220
你其實有兩個loss
link |
34:47.520
所以Tacotron在訓練的時候
link |
34:49.300
其實有兩個training target
link |
34:51.860
這兩個training target在
link |
34:53.660
第一代Tacotron跟第二代Tacotron裡面都有
link |
34:56.980
所以顯然這個這件事情是頗重要的
link |
34:59.540
它的兩個training target是這樣子
link |
35:01.860
我們會希望RNN的decoder輸出來的
link |
35:05.700
就是male spectrogram
link |
35:08.260
這是第一個loss
link |
35:09.540
我們希望RNN輸出來的東西
link |
35:11.580
跟正確答案我們訓練這個TTS的時候我們有正確答案嘛有pair的data有文字跟
link |
35:17.480
聲音訊號的pair data
link |
35:19.280
所以我們希望說RNN的decoder輸出來的這段聲音訊號
link |
35:23.120
link |
35:23.880
male spectrogram跟你光tube正確答案越接近越好
link |
35:27.980
但同時我們也希望說
link |
35:29.760
這個RNN的輸出通過CBHGCBHG是non-codal的它可以看整段聲音訊號
link |
35:36.160
決定說輸出什麼
link |
35:37.700
那CBHG的輸出
link |
35:39.740
也要跟male spectrogram越接近越好
link |
35:42.560
那在Tacotron裡面有試說
link |
35:45.640
這個CBHG的輸出要跟male spectrogram越接近越好還是跟linear spectrogram越接近越好
link |
35:52.040
這兩個都是可以的
link |
35:53.820
而現在TracTacotron的時候你就是同時minimize
link |
35:56.640
這兩個loss
link |
35:57.660
你希望這邊
link |
35:58.440
輸出的是male spectrogram
link |
35:59.980
這邊輸出的也是
link |
36:02.040
male spectrogram
link |
36:03.060
但是我們最後真正需要的
link |
36:05.360
是CBHG這邊的
link |
36:08.180
輸出這個東西
link |
36:09.460
才是我們真正
link |
36:10.740
會拿來
link |
36:12.020
丟到vocoder
link |
36:13.300
去合出聲音的Acoustic feature
link |
36:15.860
我們產生male spectrogram或linear spectrogram以後它沒有辦法馬上聽
link |
36:19.700
所以這些東西
link |
36:20.980
要丟到vocoder裡面
link |
36:22.760
才能產生聲音訊號
link |
36:24.300
那至於vocoder的細節
link |
36:26.100
這個我們之後會講反正你現在就記得說
link |
36:28.140
有一個module就是可以吃Acoustic feature
link |
36:31.460
然後這個Acoustic feature會產生聲音訊號
link |
36:33.000
然後這個module往往
link |
36:34.540
是獨立出來訓練的
link |
36:36.580
它不會跟network的其他部分
link |
36:38.380
合在一起做jointly的訓練
link |
36:40.680
那在第一代的TracTacotron裡面
link |
36:43.500
它的vocoder
link |
36:44.780
就是單純的WaveNet
link |
36:46.820
它是一個raw base的vocoder
link |
36:48.620
那在第二代裡面
link |
36:50.160
就換成WaveNet
link |
36:51.940
它是
link |
36:52.460
串出來的
link |
36:53.220
它是一個network base的vocoder
link |
36:58.340
那TracTacotron做出來的結果
link |
37:00.640
好不好呢
link |
37:01.660
我們來看一下第一代跟第二代的TracTacotron的結果
link |
37:05.000
我們現在看第一代的TracTacotron
link |
37:07.560
這邊衡量語音合成好壞
link |
37:10.380
通常會用一個東西叫做
link |
37:12.160
Mean Opinion Score
link |
37:13.440
所寫的是MOS
link |
37:15.500
那這個Mean Opinion Score MOS是什麼呢
link |
37:18.820
這個MOS
link |
37:20.100
它不是什麼神奇的東西
link |
37:22.920
它無甚神奇之處它就是找一群人來
link |
37:27.020
找一群
link |
37:28.300
工讀生來
link |
37:31.100
然後叫他聽聲音然後給分數
link |
37:33.660
那這個分數呢就是
link |
37:35.460
1到5分之間
link |
37:36.480
最高分
link |
37:37.760
就是5分
link |
37:40.320
好那這個TracTacotron
link |
37:41.600
評出來的分數的平均是
link |
37:43.400
3.82
link |
37:44.940
Parametric Approach
link |
37:46.220
評出來的聲音平均是
link |
37:47.740
3.69
link |
37:49.020
Concatenative Approach
link |
37:50.820
評出來的聲音是
link |
37:51.580
4.09
link |
37:53.120
所以如果你看第一代的TracTacotron
link |
37:55.160
它是贏過了過去用Machine Learning做出來的用Deep Learning Based Approach做出來的Parametric Approach
link |
38:01.560
但它贏不過Concatenative Approach
link |
38:04.120
你直接把聲音訊號接起來
link |
38:06.180
聽起來
link |
38:07.200
使用者聽起來還是覺得比較好的
link |
38:10.020
所以Concatenative Approach的分數還是比較高的
link |
38:13.860
好進入了第二代的TracTacotron以後啊
link |
38:16.420
我們來看一下Parametric Approach
link |
38:18.460
3.5分
link |
38:20.000
第一代的TracTacotron
link |
38:21.020
link |
38:22.040
4分
link |
38:22.820
這個分數我重新評啦不同人評分數本來就不太一樣嘛
link |
38:25.620
Concatenative Approach
link |
38:27.160
4.1分
link |
38:28.440
那有一個是用WaveNet的方法
link |
38:30.240
但WaveNet的方法不完全是end to end的
link |
38:32.280
因為它要給它一些Linguistic的feature
link |
38:35.100
它的輸入呢並不是單純的字母
link |
38:37.660
你需要做過一些後處理
link |
38:39.460
你需要把輸入的文字做一些很複雜的處理以後
link |
38:42.520
才能丟給WaveNet去產生聲音訊號
link |
38:44.820
它的分數是4.3分
link |
38:46.880
而Ground Truth
link |
38:47.900
就是原來的原始的聲音不是語音合成的聲音
link |
38:51.740
拿去給使用者聽
link |
38:53.280
使用者給的分數
link |
38:54.560
是4.58
link |
38:56.080
神奇的是第二代TracTacotron的分數
link |
38:58.400
居然有
link |
38:59.420
4.526
link |
39:00.960
第二代TracTacotron的分數
link |
39:02.740
不只贏過了Concatenative Approach
link |
39:05.300
它居然也已經逼近了
link |
39:07.600
Ground Truth
link |
39:08.880
那為什麼第二代的TracTacotron這麼強呢
link |
39:11.440
其實第一代的TracTacotron跟第二代的TracTacotron都是end to end的
link |
39:14.520
都是Sequence to Sequence的model加上Attention
link |
39:17.340
那為什麼第二代的TracTacotron
link |
39:20.140
會如此的強悍呢
link |
39:21.940
一個很關鍵的原因
link |
39:25.260
其實是換了Vocoder
link |
39:27.060
所以Vocoder其實扮演了蠻關鍵的角色
link |
39:29.620
如果一樣是第二代的TracTacotron
link |
39:31.920
你產生Linear的Spectral Grain以後用GL
link |
39:35.260
GL就是Graphene Lin
link |
39:36.540
用Graphene Lin的這個Vocoder
link |
39:38.320
你的Analysis Score是3.9
link |
39:41.140
那如果你換成WaveNet
link |
39:43.180
你就從3.9暴增到4.51了
link |
39:46.000
如果你今天不是Linear加WaveNet
link |
39:49.320
而是用Mirror Spectral Grain當作WaveNet的輸入的話
link |
39:52.400
那是4.52
link |
39:53.420
那沒有差很多啦
link |
39:54.700
所以你發現說只要換成WaveNet
link |
39:57.000
把Graphene Lin換成WaveNet就從3.9暴增到
link |
40:00.600
4.5
link |
40:01.620
那這個結論其實也是很
link |
40:03.160
這個這個結果也是可預期的
link |
40:04.680
因為Graphene Lin其實他沒有
link |
40:06.220
真的很強
link |
40:07.240
他是一個Rule Based的方法
link |
40:09.560
那WaveNet
link |
40:10.840
他比較強他是認出來的他是一個
link |
40:13.140
New Wave Network Based的方法他比較強他可以
link |
40:16.460
Spectral Grain
link |
40:17.240
產生非常好的聲音訊號
link |
40:21.080
好那
link |
40:22.360
今天這邊還有一個有趣的問題就是WaveNet啊他是認出來的
link |
40:27.220
所以你今天在Train WaveNet的時候你需要一些Training Data
link |
40:31.580
那Train WaveNet這種Vocoder啊
link |
40:33.880
link |
40:34.640
就是就跟你一般訓練一個Network是一樣的你就是需要輸入跟輸出啊你要給他Acoustic Feature當作輸入
link |
40:41.040
你需要給他
link |
40:42.060
正確的Ground Truth的Waveform當作輸出然後給他這樣子Acoustic Feature
link |
40:47.440
跟Ground Truth的Pair Data
link |
40:48.980
你就可以訓練一個WaveNet出來
link |
40:52.300
但是你用什麼樣的Data去做訓練
link |
40:55.120
其實是會稍微影響到你的結果
link |
40:58.440
所以在Tackle From 2裡面有一個很有趣的實驗是說
link |
41:02.040
如果我們今天
link |
41:03.820
link |
41:04.840
Ground Truth的Data
link |
41:06.380
用真正的聲音不是合成出來的聲音
link |
41:09.720
去訓練WaveNet
link |
41:10.740
但是
link |
41:12.520
我們給他合成出來的
link |
41:15.340
Spectrogram
link |
41:16.360
我們把這個Tackle From合成出來的Spectrogram
link |
41:19.440
丟給
link |
41:20.720
用真正的聲音訓練出來的WaveNet
link |
41:24.040
結果是只有
link |
41:25.320
4.3分
link |
41:26.860
但是如果你今天是用
link |
41:29.680
這個Tackle From合成出來的Spectrogram去訓練WaveNet
link |
41:33.780
然後測試的時候也是給他聽
link |
41:36.840
這個Tackle From合成出來的Spectrogram
link |
41:38.900
那分數才會更高一點,分數才會是
link |
41:42.480
4.526
link |
41:44.020
所以這顯示說
link |
41:45.560
其實Tackle From合出來的那個Spectrogram跟真正的Spectrogram
link |
41:49.140
還是有一些
link |
41:50.420
微妙的差異
link |
41:52.200
如果你認真的去看
link |
41:54.000
你會覺得沒有什麼差別,但他還是有一些微妙的差異
link |
41:58.100
所以對WaveNet來說
link |
41:59.880
真正的Spectrogram跟Tackle From合成出來的Spectrogram還是有一些微妙的差異的
link |
42:05.780
所以你今天要得到真正最好的結果
link |
42:08.340
你的WaveNet
link |
42:09.360
最好是用你的Tackle From
link |
42:11.420
產生出來的Spectrogram做訓練,讓WaveNet知道說現在Tackle From產生出來的Spectrogram長什麼樣子
link |
42:17.820
你才能夠真正得到最好的結果
link |
42:21.400
那在用Tackle From的時候
link |
42:23.180
有一個
link |
42:23.960
非常有趣的
link |
42:26.000
實作的時候發現了問題
link |
42:28.820
這個問題是這樣子的
link |
42:30.860
Tackle From在
link |
42:32.400
Inference的時候,也就是測試的時候
link |
42:35.480
需要加抓包
link |
42:37.260
這件事情
link |
42:38.800
很重要所以要說三遍
link |
42:41.100
Tackle From在Inference的時候要加抓包
link |
42:43.660
Tackle From在Inference的時候要加抓包
link |
42:45.960
Tackle From在Inference的時候要加抓包
link |
42:48.020
因為我們一般今天
link |
42:49.300
為什麼這件事情這麼奇怪呢,因為我們在講抓包的時候,你記不記得在Machine Learning課在講抓包的時候
link |
42:54.660
我有反覆強調說抓包
link |
42:56.980
是訓練的時候才用的
link |
43:00.040
測試的時候
link |
43:01.060
你就會把抓包直接給他
link |
43:03.380
關起來
link |
43:03.880
沒有人測試的時候在抓包的,訓練的時候要抓包讓你的model比較robust比較不overfitting
link |
43:10.280
測試的時候加抓包就是腦袋有問題
link |
43:12.580
如果有人測試的時候要抓抓抓包我就會斥責他
link |
43:15.920
但是奇妙的事情是
link |
43:17.700
Tackle From測試的時候
link |
43:19.760
要加抓包
link |
43:21.280
結果才會好
link |
43:22.820
Tackle From在測試的時候,在testing在用他的時候,你要把抓包加在你的decoder的primate裡面
link |
43:29.220
那我們現在來聽一下Tackle From的聲音,一般Tackle From
link |
43:32.800
在使用他的時候
link |
43:34.600
會加抓包
link |
43:35.620
Tackle From的聲音聽起來是這樣子的
link |
43:41.500
聲音可能有一些不自然的地方,不過這主要是來自於vocoder,那這邊vocoder用的是
link |
43:47.900
如果用
link |
43:48.940
Neural Network Based Vocoder的話,聲音聽起來就會自然很多
link |
43:54.820
但是如果今天你把primate的抓包關起來
link |
43:58.660
同樣的句子
link |
43:59.680
你合出來的聲音可能會是這樣的
link |
44:10.940
這個不是你電腦壞掉啦,就是
link |
44:14.020
當抓包不見的時候
link |
44:16.060
聲音聽起來
link |
44:17.340
就是
link |
44:18.120
這麼奇怪
link |
44:19.140
那為什麼會這樣子呢
link |
44:20.920
其實我也沒有非常好的解釋啦
link |
44:24.760
不過呢
link |
44:25.540
在natural language的generation,在NLG裡面,當你用RNN要生成句子的時候
link |
44:31.940
其實也有類似的問題
link |
44:35.260
那有人嘗試用GPET2來生成句子的時候,發現說
link |
44:39.880
當你在使用GPET2產生句子的時候
link |
44:42.680
如果你每次
link |
44:43.960
都讓GPET2
link |
44:45.500
輸出機率最大那個詞彙
link |
44:48.060
那麼GPET2
link |
44:49.340
可能就會陷入奇怪的迴圈
link |
44:51.640
他會不斷的跳針
link |
44:52.920
不斷的產生重複的句子
link |
44:55.740
所以我們今天在真的要用GPET2產生句子產生文章的時候
link |
45:00.600
你會需要一些隨機性
link |
45:03.160
所以我們不一定會是從每一個time step選擇機率最大的那個詞彙出來
link |
45:09.040
你會根據GPET2 output的那個distribution來做sample
link |
45:13.140
根據distribution來sample詞彙
link |
45:15.180
有時候sample出機率最大的token當作輸出
link |
45:18.260
有時候不見得輸出機率最大的token
link |
45:21.340
那這樣GPET2
link |
45:22.360
才能產生比較自然的句子
link |
45:25.420
那我想這個Tagotron啊
link |
45:27.480
需要抓爆的理由也是很像的
link |
45:29.780
如果你沒有抓爆
link |
45:31.320
那每一次Tagotron output的東西
link |
45:34.140
都是decoder覺得
link |
45:36.180
最有可能的輸出
link |
45:38.220
那可能就會遇到跟用GPET2生句子的時候一樣的問題
link |
45:42.320
他可能會陷入一個無窮迴圈
link |
45:44.120
就產生像剛才那樣機槍的聲音
link |
45:47.180
而在一般NLG裡面因為輸出是一個distribution
link |
45:50.520
你可以透過從那個distribution做sample
link |
45:53.840
來增加一些隨機性
link |
45:56.140
而在這個
link |
45:57.940
Tagotron裡面
link |
45:59.220
因為我們的輸出不是distribution
link |
46:02.040
所以我們沒有辦法在這個地方加隨機性
link |
46:05.100
所以怎麼辦呢
link |
46:06.140
我們把抓爆加在pre-net的地方
link |
46:08.700
如果你把抓爆加在pre-net的地方
link |
46:11.000
你就可以增加一些隨機性
link |
46:12.780
反而合出來的聲音
link |
46:14.840
比較好
link |
46:15.860
接下來呢
link |
46:17.140
我們來看一下用Tagotron呢
link |
46:18.940
做台語的語音合成
link |
46:22.000
怎麼用Tagotron做台語的語音合成呢
link |
46:24.820
有一個公開的Compass
link |
46:27.120
叫做台灣
link |
46:29.180
什麼聲
link |
46:29.940
這個字
link |
46:30.960
有點不知道怎麼唸
link |
46:31.980
那其他台語呢是
link |
46:33.520
台灣衰蝦啦
link |
46:35.820
這個台語是衰蝦應該就是美好的聲音的意思
link |
46:39.660
那裡面呢
link |
46:40.700
有提供了台羅拼音
link |
46:43.000
跟台語的語音訊號的對應關係
link |
46:45.820
所以你有這樣的paradata
link |
46:47.600
你就可以直接拿來訓練一個Tagotron
link |
46:51.440
這個Tagotron呢
link |
46:52.460
他的輸入
link |
46:53.480
是台羅拼音
link |
46:55.020
輸出
link |
46:55.800
直接就是台語的聲音訊號
link |
46:58.360
intent下去就結束了
link |
47:00.660
但是難的地方是
link |
47:02.200
我們今天
link |
47:03.220
今天你要想要講一句話
link |
47:06.280
你其實不知道他的台羅拼音是長什麼樣子啊
link |
47:09.620
所以怎麼辦呢
link |
47:10.640
你需要把中文
link |
47:12.940
轉成台羅拼音
link |
47:14.740
還好有一個東西叫做
link |
47:16.280
有一個
link |
47:16.780
工具叫做台灣語言工具
link |
47:18.820
他可以做有點像是翻譯這樣的事情
link |
47:21.640
把中文
link |
47:22.660
轉成台羅拼音
link |
47:24.200
所以你就可以把這兩個系統接起來
link |
47:26.500
把中文轉成台羅拼音
link |
47:28.560
再把台羅拼音丟到Tagotron裡面
link |
47:30.860
就可以讓機器
link |
47:32.140
合出台語的聲音訊號
link |
47:34.960
這邊呢我們就來做一下台語的聽力測驗啦看你聽不聽得懂Tagotron
link |
47:40.340
講的台語在講什麼
link |
47:59.540
機器說最近肺炎真嚴重然後
link |
48:03.380
要記得戴口罩勤洗手有病就要看醫生
link |
48:07.980
這個合出來的聲音聽起來還算蠻不錯的
link |
48:12.580
我不知道第二句這個講的台語是不是對的啦那如果這句話講的台語是不對的你再告訴我好了
link |
48:30.240
沒有一拳無法解決問題如果有那就是兩拳
link |
48:33.840