美少女声への変換と合成

Introduction

今までは主に可愛い女の子の画像(or 動画)を生成することに取り組んできましたが、画面上に映せるようになったらやはり可愛い声で話して欲しいものです。そこで今回は、別の人の声が与えられた時に美少女声へと変換するための声質変換と、テキストが与えられた時に美少女声を生成するText-to-Speech(TTS)を行なった試行結果について述べようと思います。

Voice Conversion

Introduction

声質変換のデータには2種類あります。それが、パラレルデータとノンパラレルデータです。以下にそれぞれの特徴を述べていきます。

  • パラレルデータを用いた声質変換
    同じセリフを発する2種類の声を学習データとして用います。発話内容が同じのため、言語特徴を気にせず音響特徴量の変換を行うことが可能です。しかし、話速の違い等によって言葉を発するタイミングがずれてしまうのでDynamic Time Warping(DTW)等を用いることでアライメントを取る必要があります。この場合の声質変換は、データセットの用意を考慮した時に同じ言葉を発していることが必須になるため場合によっては簡単に集められません。
  • ノンパラレルデータを用いた声質変換
    先ほどのパラレルデータが同じセリフを発する2種類の声なら、こちらは違うセリフを発する2種類の声を学習データとして用います。こちらの場合は、アライメントを取る必要がない上にデータセットもパラレルデータに比べると集めやすいです。

今回の実験では、後者のノンパラレルデータを用いた声質変換を試みました。

Network Architecture

今回参考にした論文はCycleGAN VC2です。ノンパラレルな画像データの変換にもCycleGANが使われますが、音声でも同様にCycleGANを使った手法が存在します。CycleGAN VC2は、CycleGAN VCを発展させた手法です。従って、まずCycleGAN VCについて述べようと思います。

CycleGAN VCの構造は以下のようになっています。

Takuhiro Kaneko, et al., “CycleGAN-VC: Non-parallel Voice ConversionUsing Cycle-Consistent Adversarial Networks”

CycleGANでのGenerator, Discriminatorの構造とそこまで大きくは変わっていません。細かい点(Pixel Shuffler等)を除けばGeneratorが1D CNNを主体にした構造、活性化関数にGated Linear Units(GLU)を使用していることが異なっている点です。音声は自然言語と同じSequentialなデータであるため画像に比べて大きいKernel sizeを用いた1D CNNを用いたり、GLUを使っています。
ニューラルネットワークの入力としては、様々に考えられる音声特徴量から人の声色を表すメルケプストラム(MCEPs)を用いています。WORLDを用いて24次元のMCEPsを抽出し、これをネットワークの入力へと用いています。
最後に損失関数ですが、これはCylceGANと同様です。Adversarial lossとCylce-consistency loss, Identity-mapping lossを用いてます。論文中では最後のIdentity-mapping lossによって言語的な構造が保たれていると主張しています。

以上がCycleGAN VCの説明です。そして以下の構造が今回検討したCycleGAN VC2です。

Takuhiro Kaneko, et al., “CYCLEGAN-VC2:IMPROVED CYCLEGAN-BASED NON-PARALLEL VOICE CONVERSION”

CycleGAN VCとは異なりGeneratorは1D CNNを主体にした構造ではなく、2D-1D-2D CNN構造となっています。2D CNNで広範囲に特徴を捉え、メインの変換は1D CNNの部分で行うと論文では述べられています。また、DiscriminatorにPatchGANが用いられているのもCycleGAN VCと異なる点です。
また、CycleGAN VCと異なる点として損失関数として用いるAdversarial lossの変更があります。それが、以下の図で表されるTwo-step adversarial lossです。

Takuhiro Kaneko, et al., “CYCLEGAN-VC2:IMPROVED CYCLEGAN-BASED NON-PARALLEL VOICE CONVERSION”

上図左のようなCycleGANで用いられるOne-step adversarial lossでは変換先において正解データとのAdversarial lossを取るだけですが、今回のTwo-step adversarial lossでは変換先から再び戻ってきて正解データとのAdversarial lossを取るということをします。これは、Cycle-consistency lossで用いられるL1 lossでは過剰に滑らかになってしまうのを軽減するためであると、論文中では述べられています。

以上が、CycleGAN VC2の説明です。それでは実験に移ります。

Dataset

ノンパラレルデータでの声質変換は大量にデータが必要だと思い、今回は変換元のデータとしてJSUTのBasic5000全て、変換先のデータとして綾波レイ(の声真似)データセットを用いました。綾波レイデータセットは、あくまでも声真似のデータセットですが5089文という大量のデータを含んでおり、また声真似のレベルとしても非常に高いです。こちらのデータセットは東北大学の能勢隆准教授にいただきました、この場を借りましてお礼を厚く申し上げます。
お互いの声の例は以下に示します。

  • JSUT
  • 綾波レイ

Experiment

それでは実際にCycleGAN VC2のネットワークを組み、MCEPsを入力に用いて学習を行っていくのですが、学習時と推論時で処理が変わるので、まずそのフローについて述べます。

Training

  • 変換元音声データを22050Hzにダウンサンプリングして、WORLDを用いて513次元のスペクトル包絡を抽出、この時frame periodは5msとした。
  • WORLDのCodeSpectralEnvelopeメソッドを用いて、スペクトル包絡から36次元のMCEPsを求めた後、連続した128フレームをランダムに抜き出し、それをネットワークの入力に用いた。
  • 変換先音声データも同様に36次元のMCEPsを求めておいて、ネットワークの出力も用いて損失関数を計算し、誤差逆伝搬してネットワークの重みを更新

Inference

  • 予め変換元と変換先の対数基本周波数の平均と標準偏差を求めておく。基本周波数はWORLDを用いてそれぞれ1000文から抽出し、対数にして平均と標準偏差を求めた。この平均と標準偏差は後に基本周波数の変換において用いる。
  • 変換元音声データを22050Hzにダウンサンプリングして、WORLDを用いて513次元のスペクトル包絡、基本周波数、非同期周期性を抽出、この時frame periodは5msとした。
  • WORLDのCodeSpectralEnvelopeメソッドを用いて、36次元のMCEPsを求めた後、前から128フレームずつ学習済モデルを用いて変換した。
  • WORLDのDecodeSpectralEnvelopeメソッドを用いて、変換したMCEPsを513次元のスペクトル包絡に復元。変換先の基本周波数は先に求めておいた、変換元と変換先の対数基本周波数の平均と標準偏差から以下のように計算する。変換先の非同期周期性は変換元のものをそのまま用いる。
  • 変換したスペクトル包絡、基本周波数、非同期周期性を用いてWORLDによって音声へ合成する。

また、学習時の詳細は以下に示します。

  • バッチサイズは16
  • 最適化手法はAdam(β1=0.9、αはGeneratorで0.0002、Discriminatorで0.0001)
  • Adversarial loss, Cycle-consistency loss, Identity-mapping lossの係数はそれぞれ1.0, 10.0, 5.0とした。Identity-mapping lossは初めの20epochだけ用いた。

Results

それではJSUT -> 綾波レイの変換結果を以下に示します。WaveCycleGANWaveCycleGAN

聞いていただくと分かるかと思いますが、音質はそこそこで声質も変換されているものの肝心の発話内容が不明瞭です。これは、Two-Adversarial Stepにおいて互いの分布を過剰に近づけようとして発話内容が保存されてないのではと思い、CylceGAN VCと同様のOne-step adversarial lossに戻しました。その結果が以下になります。

聞いていただくと声質も変わりつつ発話内容も明瞭であることが分かります。

今回はCycleGAN VC2を用いてノンパラレルデータでの声質変換を行いました。発話内容が異なるデータを学習データとしてもそれなりに出来ています。次なる方向としては、以下の2点を考えています。

  • 少量のノンパラレルデータでの学習
    今回は、変換元も変換先も5000文ほどの大量のデータで学習しました。しかし実際はここまで集められない場合もあります。綾波レイのデータセットを5000文 -> 500文にした時の声質変換結果を以下に示しますが、音質が下がり発話内容が不明瞭になってしまっています。従って、より少量のデータで学習が出来ないか手法を考えていきたいです。
  • 音質向上
    音声を音響特徴量に戻し、変換して再び音声へと戻しているので合成音声のような機械的な声になっています。合成音声から自然な発話への変換はWaveCycleGANという手法があります、また一旦音響特徴量に変換することなく音声波形ベースで変換する等など手法は様々に考えられそうです。

Text-to-Speech

声質変換は変換元の声の情報を用いて変換するので、単純な言語特徴以外にも様々な音声特徴を利用できます。ですがやはり理想としてはテキストから音声を生成したいものです。そこで今回は、GoogleのTacotron2を用いてText-to-Speechを行いました。

Introduction

テキストから音声を生成するには、テキスト→言語特徴量→音響特徴量→音声という段階を踏みます。テキストから直行で音声へ変換したり、一つずつ段階を踏むやり方等様々に手法は存在します、今回紹介するTacotron2ではテキストから音響特徴量であるメルスペクトログラムまでの生成と、メルスペクトログラムから音声の合成(Vocoder)を分けて行っています。論文中ではVocoderを従来のGriffin-LimではなくWaveNetを用いています、WaveNetは特に目新しい構造ではないので、テキストからメルスペクトログラムを生成する部分を見ていきます。

Network Architecture

Tacotron2の全体図は以下のようになっています。

https://github.com/Rayhane-mamah/Tacotron-2←こちらのページより拝借しました。

EncoderとDecoderに分かれていて、Encoderではテキストの特徴抽出を行い、Decoderでメルスペクトログラムを生成していきます。
Decoder部分は自己回帰モデルとなっており、1フレームずつ2 Layer Pre-Net→2 LSTM Layers→Linear Projectionを通してメルスペクトログラムを生成します。この時、Encoderの出力からAttention Matrixを計算します。このAttentionではどのタイミングでどの文字を読むかについて注視します、タイミングがずれていくについて読まれる文字も同様にずれていくのでAttention Matrixは以下のように対角成分に値を持つようになります。

また、2 LSTM Layers後に分岐がありLinear Projectionを通した後Sigmoid関数で文章が終わったかどうかの判別を行います。実験では、文章の終わりにピリオドを入れないとこのStop Tokenが終了だと判別しないのか、冗長な音声になっていました。Decoderでメルスペクトログラム生成後は、5 Conv Layer Post-Netを通したものと残差結合をして更に改善をさせます。以上が、Tacotron2でテキストからメルスペクトログラムを生成する流れです。メルスペクトログラム生成後は、Vocoderに通して音声を合成します。
最後に損失関数についてですが、これはPostNet前後において正解データのメルスペクトログラムと平均二乗誤差を取ります。

Dataset

データセットとしては、声質変換と同様に綾波レイデータセットの5089文すべてを用いました。日本語のテキストのペアも一緒にいただいているので、それらからなるべく音素に近いアルファベットに変換しました。
例) こんにちは(日本語表記)→Konnichiha(ローマ字表記)→Konnichiwa(音素に近づけた表記)

Experiment

今回は一から実装せずNVIDIAのTacotron2実装を拝借しました。この実装ではメルスペクトログラムを生成するところまではTacotron2と同じなのですが、Vocoder部分でWaveGlowを用いています。Tacotron2論文で述べられているWaveNet Vocoderは高品質であるものの自己回帰モデルであるため低速という問題がありました。そこで、Parallel WaveNetWaveRNNで高速化を狙いましたが品質的にはWaveNetに劣ります。WaveGlowは波形の生成をメルスペクトログラムの条件付けをしてFlowベースに行うため並列化が可能で、WaveGlow論文中ではWaveNetより高速且つ高品質と述べられています。
拝借した実装からの変更点はサンプリングレートを22050Hzにしたことくらいです。学習時には、重みの初期値としてLJ Speech Datasetで学習したものを使用しました。また、WaveGlow部分に関しては再学習はしていません。LJ Speech Datsetでの学習済モデルをそのまま使用しています。Vocoderは非話者依存であるため再学習の必要はないと考えたからです。(個人的にGlowは依然として学習が難しく沼に嵌りたくなかったのもあります)

Results

それではText-to-Speechの結果を述べていきます。適当に考えた文章を何個か入力にしてどのような音声になるかを見ていきます。

以上のように、発話内容は明瞭で声質もちゃんと綾波レイっぽくはなっていますね。ですが「友情は見返りを求めない。」や「ラブ探偵チカが解決するわ。」のように発話の様子が平坦で、アクセントに関して我々が普段耳にする発話とは異なっているものもあります。

日本語はアクセントが非常に重要な言語です。同じローマ字表記でもアクセントが異なっていれば、違う意味になることがあります(ex. 橋と箸)。また、隣接する言葉によってアクセントが変化する場合もあります。しかしこういったアクセント情報は文字には現れません。今回はTacotron2を用いてデータドリブンにそれらのアクセントを推測するようにしていますが、データ量が足りないということでしょう。
こちらの論文では、これらアクセント情報を考慮して日本語用にTacotron(こちらはTacotron2ではなくTacotron1です)を設計し直しています。

https://soundcloud.com/lento-l/jce84jtbz4dm

具体的には上図のように今までのテキスト情報から得られるphoneme embeddingだけではなく、accentual-type embeddingでアクセント情報を付与したりself-attention構造を取り入れたりしています。これらの工夫によって、評価指標であるMOSが単なるTacotronと比べて向上したことを示しています。しかし、重要なのはこれらの工夫を取り入れてなおHMMをベースにした従来手法よりMOSは低いという事です。今後の方針としては、文字に対する音への情報が少ないので、それらを取り入れていくつもりだと論文中では述べられています。私も、今回用いた実装を改良しつつこれらの問題に取り組めたらと思います。

Summary

今回は、美少女声への変換と合成ということで、CycleGAN VC2によるノンパラレルデータの声質変換と、Tacotron2によるText-to-Speechを試行しました。どちらも一定の結果は得られているものの、後一つ足りないという感触です。特にTTSに関しては、美少女声への合成ということで可愛さの顕現のためにアクセント、更に上を目指して感情を伴った声を生成したい欲があります。従って、それを可能にする手法を目指して日々邁進していく次第です。