読者です 読者をやめる 読者になる 読者になる

人工知能に関する断創録

人工知能、認知科学、心理学、ロボティクス、生物学などに興味を持っています。このブログでは人工知能のさまざまな分野について調査したことをまとめています。最近は、機械学習・Deep Learningに関する記事が多いです。



統計的声質変換 (7) GMMによる声質変換

音声合成 音声信号処理

統計的声質変換 (6) 声質変換モデルの学習の続き。今回が統計的声質変換シリーズの最終回です。

今回は、前回学習した声質変換モデルを使って本当に声が変換できるか試してみたい。前回やったGMMの学習で

 \displaystyle P(z_t|\lambda^{(z)}) = \sum_{m=1}^M w_m N(z_t; \mu_m^{(z)}, \Sigma_{m}^{(z)})

における各コンポーネント mw_m\mu_m^{(z)}\Sigma_m^{(z)} が学習データから推定された状態である。\mu_m^{(z)}\Sigma_m^{(z)} は、

\mu_m^{(z)} = \begin{bmatrix} \mu_m^{(x)} \\ \mu_m^{(y)} \end{bmatrix}

\Sigma_m^{(z)} = \begin{bmatrix} \Sigma_m^{(xx)} & \Sigma_m^{(xy)} \\ \Sigma_m^{(yx)} & \Sigma_m^{(yy)} \end{bmatrix}

のように分割できる。この学習結果は、

clb_slt.gmm
clb_slt.gmm_01.npy
clb_slt.gmm_02.npy
clb_slt.gmm_03.npy

の4つのファイルにダンプされている。

GMMによる声質変換

GMMによる声質変換は、x_tが与えられたときのy_tの期待値を求めることで行う。

\displaystyle (13) \hspace{50pt} \hat{y_t} = E[y_t|x_t] = \sum_{m=1}^M P(m|x_t, \lambda^{(z)}) E_{m, t}^{(y)}

ここで、

 \displaystyle (9) \hspace{50pt} P(m|x_t, \lambda^{(z)}) = \frac{w_m N(x_t; \mu_m^{(x)}, \Sigma_m^{(xx)})}{\sum_{n=1}^M w_n N(x_t; \mu_n^{(x)}, \Sigma_n^{(xx)})}

 \displaystyle (11) \hspace{50pt} E_{m, t}^{(y)} = \mu_{m}^{(y)} + \Sigma_m^{(yx)} \Sigma_m^{(xx)-1} (x_t - \mu_m^{(x)})

である。今回は導出は省いて、論文(PDF)の結果をそのまま借用しよう。

たとえば、Aさんの声をBさんの声に変換することを考える。Aさんの声から抽出したメルケプストラムパラメータ x_t を使って上の式で変換すると \hat{y_t} が求められる。この \hat{y_t} を使って分析合成すると元のAさんの声がBさんの声になっているというわけ。今回は、ピッチの変換モデルは学習していないので変換元のAさんから抽出したパラメータをそのまま使う。

f:id:aidiary:20150419092011p:plain

当たり前であるが変換モデルを学習するときにはAさんとBさんの両方の声が必要だったが、実際に声質を変換するときはAさんの声だけあればよい。上の式で本当にAさんの声がBさんの声になるかさっそく実装して試してみよう。

作成したスクリプト

上の式では、コンポーネントを表す変数に m を使っているが、スクリプトではメルケプストラムの次数に使ってしまったため代わりに K を使っているので注意。

先の式はすべてのフレーム t について計算する必要があるためそのまま実装すると非常に計算が重い。そこで、計算を高速化するためにいくつか工夫している。

  • 式 (11) のフレームtに依存しない項(共分散行列の積)を最初に計算して保存しておく
  • 式 (9) の分母を先に計算して保存しておき、分子は再計算しない
  • 式 (9) の多次元正規分布のオブジェクトをあらかじめ作成しておく

順に確かめたところ3つめが一番高速化に寄与していた。オブジェクト作成というのはけっこう重い処理のようだ。

声質変換例

さっそく上のスクリプトを使って音声を変換してみよう。今回は、clbさんの声をsltさんの声に変換する。aセットの最初の50文はGMMの学習に使用したのでそれ以外の文を使ってテストした。

python convert_voice.py wav/clb/arctic_b0001.wav clb_slt.gmm converted_b0001.wav

変換元(clb)の音声

変換先(slt)の音声

clbからsltへ変換した合成音声

別の例。

変換元(clb)の音声

変換先(slt)の音声

clbからsltへ変換した合成音声

GMMの学習に使用したa0028だと・・・

変換元(clb)の音声

変換先(slt)の音声

clbからsltへ変換した合成音声

今回は、ピッチの変換はしていないのでイントネーションはオリジナルのものがそのまま維持される。本来は声質変換したclbの音はsltと似ていなくてはいけないのだが、元の二人の声が似ていることもあり、本当に正しく変換されているのかよくわからない結果になってしまった・・・音質が悪いこともあるがむしろ似ていないように思える。

音質の改善は元のチュートリアル記事にあるようにWORLDという分析合成システムを使うとよさそう。あと学習データ数を増やしたり、GMMの数を調整したり、別の話者でも試してみるとよいかもしれない。今回の手法はかなり昔の基本技術のようで最新の技術はずっと進んでいるようだ。戸田さんの講演資料が参考になりそう。クッソムズそうだけどね。