[論文メモ] TRAINING ROBUST ZERO-SHOT VOICE CONVERSION MODELS WITH SELF-SUPERVISED FEATURES

arxiv.org
教師なし学習によるVoice Conversion(VC) modelの学習
執筆当時、結果のURL。
trungd.github.io

あくまでメモ。間違っているかもしれない。
f:id:Ninhydrin:20211214095741p:plain

手法

 \textbf{X}_u, \textbf{X}_vをそれぞれソース・ターゲットの音声、 \boldsymbol{x}_u, \boldsymbol{x}_vをそれぞれソース・ターゲットの音声特徴(MFCCとか)とする。
ソース音声のコンテンツ埋め込み \boldsymbol{c}_u E_cをコンテンツencoderとして \boldsymbol{c}_u = E_c(\textbf{X}_u) \in \mathcal{R}^{d_{inp} \times d_c} ( d_{inp}は入力の時間方向の次元、 d_cはコンテンツの埋め込み次元)。
ターゲット音声の話者埋め込み \boldsymbol{s}_v E_sを話者encoderとして \boldsymbol{s}_v = E_s(\boldsymbol{x}_v) \in \mathcal{R}^{d_s} ( d_sは話者埋め込みの次元数)。
それぞれのencoderは入力は異なる(音声、音声特徴)ので注意。

decoderはコンテンツ埋め込みと話者埋め込みを入力として長さ d_{out} d次元の音声特徴を出力する(ここではスペクトログラム) D(\boldsymbol{c}, \boldsymbol{s}):\mathcal{R}^{d_s} \times \mathcal{R}^{d_{imp} \times d_c} \rightarrow \mathcal{R}^{d_{out} \times d}

なおパラレルデータは利用できないとする( \textbf{X}_u = \textbf{X}_v = \textbf{X}, \boldsymbol{c}_u = \boldsymbol{c}_v = \boldsymbol{c},  \boldsymbol{s}_u = \boldsymbol{s}_v = \boldsymbol{s})。
なので再構成lossは自己再構成になり \mathcal{L}_{slef-same} = ||\boldsymbol{x} - D(\boldsymbol{c}, \boldsymbol{s})||_2

Length resampling decoder

ここはよくわからなかったのであまり参考にせず。

一般的なアーキテクチャだとdecoderはコンテンツ埋め込みから音声特徴を生成し、それをvocoderで音声にする。
このとき長さのミスマッチが起こる。
vocoderは高いサンプリングレートかつ小さいwindow sizeの入力が好ましいが、音声特徴はより大きいwindow size、むしろ生の音声の方が効率的。
そのためdecoderの入力長 d_{inp}と出力長 d_{out}が異なる。
これを修正するためにupsamplingとpoolingを行う。

例としてコンテンツencoderが16kHzの音声を受け取り1/320倍の特徴を出力する。
vocoderはwindow size 300で24kHzの音声を出力する。つまり d_{inp}: d_{out} = 5:8
なのでdecoderの入力を8倍し、stride 5のaverage poolingを行うことでコンテンツencoderの自己教師あり学習が出来る。

ちょっとよくわからなかった。 d_{inp} d_{out}はそもそも別の特徴なので長さが異なるのは当然では?読むときに何か見落としているかも?

Self-reconstructing from pairs of utterances

一般的なself-reconstructionは \boldsymbol{x}_u = \boldsymbol{x}_v = \boldsymbol{x}の設定で、 \boldsymbol{x} = D(E_c(\boldsymbol{x}), E_s(\boldsymbol{x}))で学習するが、これだと話者埋め込みにコンテンツ情報が混ざり、話者とコンテンツが分離できない。
そこで同じ話者の別のセグメントを利用する。
f:id:Ninhydrin:20211214092922p:plain

Enforcing consistency and separability for speaker embeddings

話者埋め込みは同じ話者なら当然同じになってほしいのでcycle-consistencyを導入。
 \boldsymbol{x}'_u,  \boldsymbol{x}'_vをdecoderに生成された音声特徴とする( \boldsymbol{x}'_u = D(\boldsymbol{c}_u,  \boldsymbol{s}_v),  \boldsymbol{x}'_v=D(\boldsymbol{c}_v,  \boldsymbol{c}_u))。
cycle-consistency lossは以下。
f:id:Ninhydrin:20211214093524p:plain
2項目と3項目がおかしく感じるが気のせい? E_s(\boldsymbol{x}'_u)からは話者 vの話者埋め込みが得られそうだが。

上記のlossだと話者埋め込みが他の話者の埋め込みと分離が悪くなる。そこで出力付近にヘッドを追加し、話者IDをを利用したクラス分類lossも追加。
 Projが新しいヘッド、 yはone-hotの正解の話者IDのラベル、 \mathcal{L}_xentがcross entropy loss。
f:id:Ninhydrin:20211214094206p:plain

所感

よくあるZero-shot VCの形。言葉の統一感等が少々悪くわかりにくい論文だった(小並感)。
Length resampling decoderがちょっとよくわからなかった。
同じ話者の発話の違うセグメントを利用して話者埋め込みを作るのは以前試してなかなかうまく行かなかったが、自分の実装が悪かったのだろうか。
セグメントの切り出しに関してもどれくらいの長さを利用すれば良い埋め込みが得られるのかなどわかっておらず適当だったのも良くなかったかも。
暇があれば応用してみる予定。