iT邦幫忙

2021 iThome 鐵人賽

DAY 11
1
AI & Data

AI Voice Conversion系列 第 11

【Day11】 AutoVC 簡介

AutoVC 框架

  • AUTOVC 就是由上圖三個 model 所組成,
    1. 內容編碼器 Ec(·) 產生從語音中嵌入的內容。
    2. 語者編碼器 Es(·) 產生從語音中嵌入的,(這邊用的是 pretrain model,也就是 D_VECTOR)
    3. 解碼器 D(·,·) 產生從內容和語者嵌入的語音。

在轉換和訓練,這些 model 的輸入是不同的。

  • (a) 訓練期間:
    來源語音 (X1) 被送入內容編碼器 Ec(·),來源語音的另一段聲音 (X1') 送入語者編碼器 Es(·),最後解碼器跟內容編碼器最小化 reconstruction error (見下面說明)。

  • (b) 轉換期間:
    來源語音 (X1) 被送入內容編碼器 Ec(·)。目標語者的語音 (X2) 送入語者編碼器 Es(·),最後解碼器產生轉換結果。

What is reconstruction error and Why this work ?

  • 下面是在 Autovc 裏頭用的 loss function

其中

  • 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)

以下說明這 Loss 為什麼有用

同一個人但說不同的話,他們的 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)

更直觀一點的解釋 dim_neck

  • 一段語音裡包含了兩種訊息 - 語者的特徵 (塗滿灰色) 以及說的內容(斜線)

    (a) -> (c) 在訓練時目標跟來源都是一樣的人

    (a)當瓶頸太寬時,內容會包含一些來源語者的特徵
    (b)當瓶頸過窄時,內容會丟失,導致重構不完善
    (c)當瓶頸剛好時,可以實現完美的重構,嵌入的內容不包含來源語者特徵
    (d)實際轉換過程中,輸出不應包含來源語者的特徵,因此轉換質量應與進行自我重構時一樣高

放大一點來看 AutoVC 結構

  • (a)內容編碼器

    1. 輸入: 80 維的梅爾倒頻譜圖 X1 與語者特徵 Es(X1) concatenate。

    2. 進 3 個 5X1 的 Conv + BN + ReLU ,out_put_channel = 512

    3. 進 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

    1. 進 3 個 5x1 Conv + BN + ReLU, out_put_channel = 512
    2. 進 3 個 cell = 1024 的 LSTM
    3. 進 1 個 1X1 Conv, out_put_channel = 80 這邊是第一個輸出
    4. 進 4 個 5X1 Conv + BN + ReLU, out_put_channel = 512
    5. 進 1 個 5X1 Conv + BN + ReLU, out_put_channel = 80 這邊是第二個輸出
    6. 最後輸出 = 第一個輸出 + 第二個輸出

最後把得到的 MEL 轉回 Waveform 就完成了,因此要特別注意的是,拿來訓練 Auto_VC 的 MEL 就已經是可以用 MelGan 或其他 Vocoder 轉換的 MEL 了!

小結

明天開始我們就試著用官方的 pytorch 版本 run 吧!

/images/emoticon/emoticon09.gif/images/emoticon/emoticon13.gif/images/emoticon/emoticon14.gif/images/emoticon/emoticon22.gif/images/emoticon/emoticon28.gif


上一篇
【Day10】 聲音轉換概述 - 再次出發!
下一篇
【Day12】 AutoVC 實作 Pytorch 篇 - 1
系列文
AI Voice Conversion30

尚未有邦友留言

立即登入留言