在轉換和訓練,這些 model 的輸入是不同的。
(a) 訓練期間:
來源語音 (X1) 被送入內容編碼器 Ec(·),來源語音的另一段聲音 (X1') 送入語者編碼器 Es(·),最後解碼器跟內容編碼器最小化 reconstruction error (見下面說明)。
(b) 轉換期間:
來源語音 (X1) 被送入內容編碼器 Ec(·)。目標語者的語音 (X2) 送入語者編碼器 Es(·),最後解碼器產生轉換結果。
其中
reconstruction error 就是經過 Decoder 後的預測輸出跟真實的 MSE。
content error 則是把經過 Decoder 後的預測輸出丟進 Encoder 然後跟把真實也的丟進 Encoder 後的輸出做 MAE
寫出來的話就像這樣
encoder_out = encoder(x)
decoder_out = decoder(encoder_out)
# reconstruction error
L_recon = mse_loss(x_real, x_decoder)
# content error
code_reconst = encoder(decoder_out)
L_content = mae_loss(encoder_out , code_reconst)
同一個人但說不同的話,他們的 speaker Embedding 我們假設 D_VECTOR 會處理到一模一樣
if U1 = U2 then Es(X1) = Es(X2)
不同人講的話(不管內容是否一樣),他們的 speaker Embedding 我們假設 D_VECTOR 會處理到完全不一樣
if U1 != U2 then Es(X1) != Es(X2).
{X1( 1: T)} 是有限的二階矩陣遍歷 (order-τ) 的馬爾可夫過程,即
pX1(t)(·|X1(1 : t − 1), U1) = pX1(t)(·|X1(t − τ : t − 1), U1).
進一步可以假設 X1 是有限基數,將 n 表示為 C1 的維度,則 n 為
n = n* + T^2/3 where n* is the optimal coding length of pX1(·|U1)^2
那麼下方的假設就成立了:
1. 對於每個 T ,存在一個內容編碼器 Ec∗(·;T) 和解碼器 D∗(·,·;T)
2. limT→∞ L = 0,KL 就是 KL-divergence
這說明了如果幀數 T 足夠大,且 n (瓶頸維度) 設置得當,則 loss function 將近似於理想轉換
pXˆ1→2 (·|U2 = u2, Z1 = z1) = pX(·|U = u2, Z = z1)
一段語音裡包含了兩種訊息 - 語者的特徵 (塗滿灰色) 以及說的內容(斜線)
(a) -> (c) 在訓練時目標跟來源都是一樣的人
(a)當瓶頸太寬時,內容會包含一些來源語者的特徵
(b)當瓶頸過窄時,內容會丟失,導致重構不完善
(c)當瓶頸剛好時,可以實現完美的重構,嵌入的內容不包含來源語者特徵
(d)實際轉換過程中,輸出不應包含來源語者的特徵,因此轉換質量應與進行自我重構時一樣高
(a)內容編碼器
輸入: 80 維的梅爾倒頻譜圖 X1 與語者特徵 Es(X1) concatenate。
進 3 個 5X1 的 Conv + BN + ReLU ,out_put_channel = 512
進 2 個 cell = 32 的 BLSTM (合起來 = 64)
接著進行對 bottleneck 的下採樣,這兩個就是輸出
dim_neck = 3
# 以上圖(e)來看的話 dim_neck = 3
out_forward = outputs[:, :, :dim_neck]
# 上圖(f),同上
out_backward = outputs[:, :, dim_neck:]
# 實際上我的實驗結果,dim_neck 的設定我覺得是
(sample_rate/1000)*2
(b) 語者編碼器 (這個是沒有要訓練的 - D_VECTOR)
根據前面的假設,語者編碼器的目標是對同一個人的不同話語產生相同的嵌入,對不同的則產生不同的嵌入。在傳統的多對多語音轉換,這一步只需要 one-hot encoding 就可以了,但這裡要達成零樣本轉換的話,Auto_VC 參考了Generalized end-to-end loss for speaker verification 中的設計
(c) 解碼器
輸入:內容編碼器的輸出個別再上採樣加上語者編碼器的輸出 Copy T 次 總共 3 個 concatenate
最後把得到的 MEL 轉回 Waveform 就完成了,因此要特別注意的是,拿來訓練 Auto_VC 的 MEL 就已經是可以用 MelGan 或其他 Vocoder 轉換的 MEL 了!
明天開始我們就試著用官方的 pytorch 版本 run 吧!