文章目錄
本文爲李弘毅老師【Vocoder】的課程筆記,這次課程由助教同學許博竣講授,課程視頻youtube地址,點這裏👈(需翻牆)。
下文中用到的圖片均來自於李宏毅老師的PPT,若有侵權,必定刪除。
文章索引:
下篇 - 待更新
1 Introduction
我們在之前的課程中有講過TTS(Text to Speech)模型和VC(Voice Conversion)模型。這兩個模型一般吐出來的都是一個叫做Spectrogram的東西,Spectrogram不是語音,它是一個表示各個時間點各個頻率的聲音強度的圖譜(下圖的圖譜中,橫軸爲時間,縱軸爲聲音頻率,顏色深淺表示強度)。因此要轉化爲最終的語音,還需要一個叫做Vocoder的模型。總而言之,Vocoder就是把Spectrogram轉化爲語音的模型。
爲什麼我們必須要有一個Vocoder,而不是讓我們的網絡直接生成一段語音呢?假設我們有一段語音,然後這段語音經過短時傅里葉變換之後,可以得到一個與時間和頻率相關的複數,這個複數的幅值就是我們剛纔聊到的Spectrogram,而就是相位。TTS或者VC直接生成的結果都是,沒有相位。相位不同,產生的音質的差別是很大的,所以相位是必須要有的,這個相位就需要一個叫做Vocoder的模型去生成。
其實要把相位直接放到模型裏去end-to-end的train也行,但是這一方面會加大模型的訓練難度,另一方面Vocoder是TTS和VC這樣的任務都需要的,單獨拿出來train的話,既可以兩邊通用,又可以降低TTS和VC的訓練難度。
2 WaveNet
我們的聲音信號放大來看,就是一串點的序列,WaveNet借鑑了autogressive model的思想,泛一點來說就是輸入前個點,輸出第個點,然後把新生成的點放到隊列當中去,繼續生成下一個點。WaveNet最重要的部分就是Causal Convolutions,說簡單點就是一堆卷積。
2.1 WaveNet的架構
WaveNet的整體架構如下圖所示。Input就是聲音信號的前個點,然後Input會經過一個Causal Conv,經過Causal Conv之後,會經過k層layers,layers就是由dialated conv和卷積組成的殘差網絡,每層都會輸出一個特徵,利用skip-connection組合起來之後,再經過兩個卷積和Softmax就得到了最終的結果。
2.2 Softmax Distribution
我們的輸入和輸出都是one-hot的向量,所以這裏要用到softmax。我們的聲音信號上每個點的數值是一個16-bit的int,範圍在[-32768, 32767],如果直接把這個進行one-hot的話,我們softmax的layer將會有65536個類別,這太難了。所以這裏用了一個叫做μ-law的方法,把[-32768, 32767] (16-bit int)的信號轉變到了[0, 255] (8-bit int)。這個過程如下所示,先將信號數值轉化到[-1, 1],然後用一個叫做μ-law的方法再轉換一下,範圍仍在[-1, 1],最後再轉化到[0, 255]。之所以要用μ-law是因爲μ-law可以減小量化誤差。
μ-law就是下面這個公式,這裏不做過多介紹。
2.3 Causal Convolution和Dilated Convolution
Causal Convolution(因果卷積)就是下圖這個東西。它是專門針對時間序列設計的,所以它輸出的時候,不會考慮未來的信息,而且隱藏層越多,考慮過去的時間越久遠。比如下圖是一個kernel size爲2的Causal Convolution,最終的output會考慮前5個時間點的信息。
而Dilatied Convolution則是下圖所示的這樣,它的目的是在卷積中加入空洞來增加感受野。這樣一來就不用像標準的CNN那樣去pooling了。
而把這兩者結合起來就是Dilated Causal Convolution了。這樣一來模型就可以看到更長遠的信息了,這在點非常密集的語音裏是非常必要的。
2.4 Gated Activation Unit
這裏還有一個需要提一下的就是這個Gated Activation Unit,那其實就是經過了兩個不同的激活函數,如下圖所示。
如果我們要給模型加一些條件的話,就可以加載這個Gated Activation Unit的部分。如果一些全局的特徵,比如說話人的一些條件,就像Global Condition那樣加,如果是要加Spectrogram這樣的隨時間變化的條件,就可以像Local condition這樣加。
2.5 小結
WaveNet可以直接使用waveform level的特徵,利用到了Dilated Causal Convolution去增大感受野,同時也可以接受各種的條件輸入,最終出來的結果也是比較不錯的。但是,它有一個問題就是速度太慢了,這也可以想象,畢竟autogressive這種方法計算下一個時間點的輸出時,是需要利用到之前輸出的結果的,因此無法並行計算。所以之後提出的一些網絡,基本都是爲了解決速度的問題。
3 FFTNet
FFTNet和WaveNet一樣都是autogressive model,它簡化了WaveNet中的一些繁瑣計算,同時提出了一種可以用到所有的autogressive model上的訓練和合成技巧。
FFTNet的模型架構如下圖所示,它會把輸入分爲和兩個部分,然後分別經過一個卷積之後,加起來,再過一層卷積,使得總長度減半,這樣運行兩層,得到最終結果。這樣得到的特徵,也是考慮了一定範圍的語音特徵的,比如下圖中輸出的綠色部分就是考慮了生成的。
FFTNet提出了四個技巧:
- 在開頭做zero-padding可以讓訓練結果更好
- 最後取結果是,不是直接去最大概率的那個值,而是根據概率分佈去做sample
- 在訓練時,給輸入加上一些噪聲
- 加入去噪聲的後處理
FFTNet最終可以達到和WaveNet差不多的效果,但速度卻快上很多。
4 WaveRNN
WaveRNN是Google提出來的,說簡單點就是用RNN去代替之前的CNN。
4.1 Dual Softmax Layer
WaveRNN沒有用之前把16bit轉成8bit的方法,而是把16bit轉成了兩個8bit,然後做兩次softmax的操作。
4.2 Model Coarse
產生的部分如下圖所示,中間這塊我們可以把它看成一個GRU,它喫和,以及上一個time step的hiddent state,輸出。
4.3 Model Fine
產生的部分如下圖所示,中間這塊我們可以把它看成一個GRU,它喫和,以及上一個time step的hiddent state,除此之外,還有剛纔產生的,輸出。
4.4 小結
WaveRNN還有一些加速的技巧,最終可以達到在手機cpu上real time的效果,非常強~
5 WaveGlow
WaveGlow放棄了autogressive的方法,基於flow-based model去做的,這個模型非常難train,有興趣的同學可以看一下視頻或者相關資料學習,這裏不做介紹了。