Chapter2-1_Voice Conversion(Feature Disentangle)
文章目錄
- 1 什么是Voice Conversion
- 2 實際實現中的細節
- 3 根據數據集分類
- 4 Feature disentangle
- 5 訓練技巧
本文為李弘毅老師【Voice Conversion - Feature Disentangle】的課程筆記,課程視頻youtube地址,點這里👈(需翻墻)。
下文中用到的圖片均來自于李宏毅老師的PPT,若有侵權,必定刪除。
文章索引:
上篇 - 1-7 Language Modeling
下篇 - 2-2 CycleGAN and StarGAN
總目錄
1 什么是Voice Conversion
Voice Conversion指的就是輸入一段聲音,輸出另一段聲音。這兩段聲音的文字內容是一樣的,但其他的某些方面是不一樣的。
這個某些方面指的是什么呢?
(1)說話人(Speaker)的轉變。就是讓這段語音聽起來像是另一個人在說一樣。
- 不同的人說同樣一段話,會有不同的效果;
- 可以用來詐騙(Deep fake);
- 做個性化的語音轉換,比如小孩一個人在家,別人敲門時,可以用大人的聲音回答;
- 保護個人隱私,從聲音中可以獲取一個人很多的信息。
(2)說話風格(Speaking Style)的轉換。
- 說話情緒的轉變,有些人說話很溫柔,想要嚴厲批評別人的時候,可以用這個;
- Normal to Lombard。Normal是指正常環境下說話的聲音,Lombard是指在酒吧這種嘈雜環境下說話的聲音。做這個的原因是,也許有一天,我們的機器人需要在嘈雜的環境下說話,轉成Lombard可以讓別人聽的更清楚。
- Whisper to Normal。悄悄話轉成正常人說話的聲音。也許我們在圖書館或者哪里用很輕的聲音打電話時,希望電話另一頭的人聽到的是正常的聲音。
- 唱歌技巧轉換。比如加彈唇,加顫音。
(3)增強說人話的可理解性(Improving Intelligibility)。
- 說話有障礙的人群說的話,可以被轉化成更容易理解的聲音。
- 口音轉換。比如讓中國人說英文時,聽不出中國人在說的感覺。
(4)數據增強(Data Augmentation)
- 擴大數據集。
2 實際實現中的細節
在實際的實現中,我們往往會假定輸入和輸出的長度是一致的,這樣會讓我們的模型比較簡單,一個encoder就夠了。同時,輸出的聲音特征向量不能直接作為語音輸出,還差個相位,轉化為語音時,還需要一個vocoder。這個vocoder如果做的不好,就會讓我們合成的聲音聽起來比較假,一聽就聽出來是合成的了。
這次不講vocoder,只講voicer conversion的部分。
3 根據數據集分類
用于語音轉換的數據集可以是成對的(parallel data),也可以是不成對的(unparallel data)。
成對就是指,同樣一段話,讓不同的人念一遍。這樣的數據往往成本比較高,很難找到很多。如果有這樣的數據的話,硬train一發,就可以了。
不成對就是每個說話人說的話,甚至語言都是不一樣的。這樣的數據往往比較好找。這里就需要借助于圖像中風格轉換的一些技術。Feature Disentangle,顧名思義,就是說我們的聲音信號中包含著各種各樣的特征,有關于內容的特征,有關于說話人的特征,有背景噪音的特征等等。我們的目的就是把這些特征給分離開來,然后如果要做speaker的轉換的話,就把speaker這部分的特征替換掉就可以了。
4 Feature disentangle
下面在描述時,以speaker的轉換為例。同樣的方法也可以用來轉換其他的特征。
假設我們今天有一個content encoder可以提取出語音中的文字信息;又有一個speaker encoder可以無視文字信息,只提取出說話人的說話特征;還有一個decoder吃content encoder和speaker encoder的輸出,然后可以吐出speaker encoder說話人說出content encoder內容的語音了。這就實現了voice conversion。
那么,要怎么訓練這兩個encoder加上一個decoder呢?訓練的總體方法和auto-encoder非常相似,就是經過encoder之后,會有一個特征,然后再把這個特征放進decoder里之后,希望得到輸入盡可能一致的聲音信號。但是,如果完全按照auto-encoder的方法來訓練的話,模型并不知道要把兩個encoder分為content和speaker兩部分,兩個encoder學成一樣的也是完全有可能的。如何讓模型知道要學一個content的特征,一個speaker的特征就是voice conversion和auto-encoder的區別所在。
目前主要有以下幾種方法:
(1)用one-hot向量來代替speaker encoder
一種做法就是,我們干脆不要這個speaker encoder了。我們用一個one-hot encoder的向量來表示是哪個說話人說的。這個做法的前提是,我們知道是哪個說話人說的,且這個說話人屬于一個已知的有限集合,如果有一個新的說話人進來,就需要重train這個模型。這個做法的另一個缺點是,沒有辦法保證content encoder的輸出中,不包含說話人相關的特征,不過這個可以通過控制encoder輸出的維度來加以限制。此法雖然看似很簡單,但卻會有還不錯的結果。
(2)Pretrained Encoder
另一種做法就是我們先事先train好一個speaker embedding的模型來當作這個speaker encoder,然后再訓練的時候,只需要微調一下這個speaker encoder就可以了。至于content encoder的部分,我們也可以用一個事先train好的語音識別的模型來做這個encoder。一般的語音識別的模型都是輸出的文字,不太好直接放上去,一個比較好的content encoder就是HMM中用來計算輸入的acoustic feature屬于哪個state的那個DNN。
這個方案是工業界比較常用的方案。
(3)Adversarial Training
還有一種思路就是在訓練content encoder的時候引入對抗學習。我們會添加一個speaker classifier作為discriminator,用來區分這句或是哪個說話人說的,而content encoder就要做到讓speaker classifier區別不了這句話是哪個人說的,這樣就可以盡可能地保證content encoder中不包含說話人的特征。
(4)設計網絡
這里借用了image style transfer中的思想來實現feature dsentangle。首先,會在content encoder這里加上Instance Normalization來去除說人話的相關特征。然后會在decoder上加入一個Adaptive Instance Normalization來加入說話人的特征。
IN(Instance Normalization)就是對輸出特征的每一個channel做normalization,因為每一個channel其實代表了模型捕捉到的聲音信號中的某一個特征,將這些特征normalize之后,就可以把全局的特征抹去了,也就抹去了說話人的特征。
AdaIN(Adaptive Instance Normalization)是會先對decoder輸出的特征加上一個IN,消除說話人的信息,然后再結合speaker encoder的輸出,把說話人的信息,也就是全局信息給加上。
5 訓練技巧
由于受到訓練數據的限制,我們在類似auto-encoder這樣traning的時候,從content這一路過來的聲音和speaker這一路過來的都是同一個,而我們在testing的時候,卻希望content這一路的聲音,和speaker這一路過來的不是同一個人。這樣我們的模型在testing的時候,表現就會不太好。
事實上,我們在訓練的時候沒法得到不同speaker從兩路過來輸出結果的ground truth,所以也只能這樣訓練。
為了解決這個問題,我們可以做2nd stage的training。這次訓練時,兩路過來的speaker時不同的,然后我們會把最終的輸出放到一個discriminator里去判斷這句話是否真實,我們希望輸出越真實越好。同時,也會把輸出放到一個speaker classifier當中去,來對進行speaker的判斷。不過,這樣直接train的話,很難train,我們還需要在另外加一個pather作為補償器,這個patcher和decoder吃一樣的輸入,然后把輸出加到decoder的輸出上去。相當于給輸出打了一個打補丁。這個補丁在1st stage training的時候是不需要的。
這樣的做法可以讓模型的效果提升很多。
總結
以上是生活随笔為你收集整理的Chapter2-1_Voice Conversion(Feature Disentangle)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: LeetCode 2130. 链表最大孪
- 下一篇: RDD 编程