ジョイジョイジョイ

ジョイジョイジョイジョイジョイ

ディープラーニングで櫟井唯ちゃんに喋ってもらう

この記事は ゆゆ式 Advent Calendar 2017 - Adventar 24 日目の記事です。

はじめに

joisino.hatenablog.com

前回、唯の画像を無限に生成することに(部分的に)成功した訳ですが、画像ができたら今度は声が欲しくなってきます。

そこで、 [1710.08969] Efficiently Trainable Text-to-Speech System Based on Deep Convolutional Networks with Guided Attention を chainer で実装して、唯の声で学習させてみました。

レポジトリ

github.com

レポジトリです。

結果

正直そこまでクオリティの高い声は生成できませんでした。

学習データが足りないのが一番の原因のようです。詳しい考察や解説は後回しにしてとりあえず結果を載せていきます。

ゆゆ式アドベントカレンダー

一応、唯がゆゆ式アドベントカレンダーって言ってるよーって言われればそうかもなぁというレベルです。

まんがタイムきらら

最初のよりは聞き取りやすいですがまだまだという印象。

「あらゆる現実をすべて自分のほうへねじ曲げたのだ」

原理的には長い文章も一度に生成できるのですが、ちゃんと学習できてないとこのように意味わかんない感じになります。

「ただのうすぼんやりした人だろ」

こちらは、学習データに含まれる実際の唯のセリフです。上の3つに比べてかなり精度が高いことから、過学習してしまっていることが分かります。

「ゆずこ」

「縁」

作中何度も登場するワードです(それはそう)。これも流石に精度高いですね。

実用からはまだまだ程遠いですが、とりあえず最初のプロジェクトとしては、唯が一応何か話してるっぽいところまで漕ぎ着けたので良しとしましょう。

これからまた、クオリティを大きく改善できたらどこかで発表したいと思います。

技術的詳細について

ここから先は技術的な詳細について書きます。

一応対象として考えているのは、深層学習を少し触ったことのあるくらいの人です。

さっぱり分からなかったらどうぞ下まで読み飛ばしてください。

背景

深層学習による end-to-end 音声合成はここ一年くらいで大きく発展しました。

GoogleTacotron や Baidu の DeepVoice などが有名です。最近 Tacotron2 も発表されて話題になりました。

これらは RNN をベースとしているのですが、学習が遅く、大企業の GPU で殴って初めて本領を発揮する類のモデルでした。

そこでここ数カ月くらいの間に、 CNN をベースにした、高速に学習できるモデルがいくつか提唱されました。

DeepVoice3 がその代表で、僕が今回実装した [1710.08969] Efficiently Trainable Text-to-Speech System Based on Deep Convolutional Networks with Guided Attention (モデルに名前がついてなさそうなので論文名の頭文字を取って ETTTS と呼ぶことにします)もその一つです。

CNN をベースにした音声合成といえば WaveNet を思い浮かべる方もいるかと思いますが、 WaveNet は生の波形を畳み込んで次の波形を生成するのに対し、 DeepVoice3 や ETTTS はメルスペクトログラム(音声の特徴量)を畳み込んで次のメルスペクトログラムを生成します。 DeepVoice3 や ETTTS は最終的に生成したメルスペクトログラムを使って生の波形を何らかの方法で復元します。

DeepVoice3 や ETTTS で生成したメルスペクトログラムを WaveNet にガイドとして入れて生の波形を生成したりできるので、 DeepVoice3 や ETTTS は WaveNet とはレイヤーが少し違う感じです。

話が少しそれましたが、そういう訳で、高速に学習できる深層音声合成モデルが提唱されました。これを実際に試してみたのがこの記事です。

DeepVoice3 ではなく ETTTS を試した理由は単にモデルが単純で分かりやすく、精度もそこまで変わらなさそうだったからです。また今度 DeepVoice3 も試したいと思っています。

モデル

f:id:joisino:20171220203100p:plain
ETTTS モデルの概要図(論文 [1] より抜粋)

ETTTS は大きく分けて二つのネットワークから構成されます。

ひとつは Text2Mel で、これはテキスト全体とメルスペクトログラムから次のメルスペクトログラムを予測します。これがメイン部分です。

もうひとつは Spectrogram Super-resolution Network (SSRN) で、メルスペクトログラムから振幅スペクトログラム(短時間フーリエ変換の絶対値)を復元するネットワークです。メルスペクトログラムから生波形を合成するのはいろいろな手法があるのですが、この論文では振幅スペクトログラムを復元するところまで独自のモデルで生成して、そこから生波形を復元するのは決定的なアルゴリズム (Griffin&Lim) を使用しています。

Text2Mel で扱うメルスペクトログラムは学習を簡単にするために、時間方向に 4 つおきに取ったもの(長さ 1/4)を使用し、 SSRN で元の長さの振幅スペクトログラムに復元します。これが Super-resolution という名前の由来です。

Text2Mel

まずはメインの Text2Mel です。これはさらに 4 つのパートに分かれます。

TextEnc はテキストを convolution して、特徴量  V (Value) (d x textlength 次元) と、各文字についてどのくらい着目すれば良いかを表す  K (Key) (d x textlength 次元) を出力します。 15 層あります。

AudioEnc はメルスペクトログラムを causal convolution (ある時点の計算に、その時点以前の値のみを使って畳み込む)して、特徴量  Q (d x audiolength 次元) を出力します。 13 層あります。

次に Attention を  A = {\rm softmax}(K^{T} Q  / \sqrt{d}) (textlength x audiolength 次元) により計算します(積は行列積です)。これは、音声の各時点についてどの文字を着目するかを表す量です。音声合成機械翻訳などの分野では馴染み深い概念だと思います。  A_{ij} は、音声の  j 番目の時点では、テキストの  i 文字目に  A_{ij} の強さで着目しているということを表します。

テキストの特徴量  K A を(行列積として)掛けあわせたものを  R とします。これは、テキストの各文字の特徴量を注目度で重みづけたことになります。

AudioDec は  R Q を causal convolution して、 1 ステップ後のメルスペクトログラム (F x audiolength 次元) の予測値を出力します。 11 層あります。

これらのネットワークの convolution は、受容野を広くするために dilation を大きくしたり、勾配を伝播させるために Highway にしていたりします。さらに詳細なネットワーク構成については原論文を参照してください。

SSRN

SSRN は、メルスペクトログラム (F x audiolength 次元) を convoluion して、振幅スペクトログラム (F' x (4audiolength) 次元) を出力します。 1/4 の長さになったメルスペクトログラムを元の長さに戻すために、途中 deconvolution を 2 度はさみます。全部で 16 層あります。

学習方法

Text2Mel と SSRN はそれぞれ独立に学習させます。

Text2Mel に Text[0: textlength] と Audio[0: audiolength] を入力して Y[0: audiolength] が出力されたときの誤差関数は、 Audio[1: audiolength+1] と Y[0:audiolength] の MAE とクロスエントロピー (binary divergence) の和に、次に示す Guided Attention Loss を加えたものになります。

機械翻訳の Attention は、例えば "I like yuyushiki". -> 「私はゆゆ式が好きです。」 の場合、 (1, 3, 2) の順番で注目するように、 Attention がどのような形になるか非自明です。一方、音声合成の場合、 Attention が単調になる(音声の時間が進むにつれて、読むべき文字も進む)、特にほとんど線形になるという特徴があります。

そこで、このドメイン知識を活かして、 Attention 行列  A と誤差行列  W_{ij} = 1 - exp\{-(i/textlength - j/audiolength)^{2} / 0.08)\} (textlength x audiolength 次元) について、  A \odot W (積は elementwise) の平均を Guided Attention Loss として誤差関数に加えます。 W は、対角線付近が  0 に近く、対角線から遠く離れるにしたがって大きくなるような行列です。つまり、 Attention  A が対角線から離れた位置に強い値を持つ(読む順番が線形から離れてしまった場合)に大きなペナルティを課すとことになっています。これによって Attention の学習が早く収束する効果があります。

SSRN ですが、これは単に MAE とクロスエントロピーの和を最小化するように学習するだけです。 SSRN は音声データさえあれば教師無しで学習できる上、実用的な精度まで上げるのも比較的簡単です。

実験

まずは論文と同じく、パブリックドメインの英語音声コーパスである The LJ Speech Dataset を用いて Text2Mel と SSRN を学習させました。このデータには 24 時間分の単一女性の英語音声ファイルとその原稿が含まれています。これだけデータがあればまともな音声合成モデルが学習できました。また、高速学習を謳っているだけあり、 GTX 1080Ti を使い両モデルそれぞれ 1 日程度で学習が完了しました。

"No Event Good Life"

ちゃんと聞き取れますね。

"All your base are belong to us"

データセットに含まれていない、しかも英語としてちょっとどうかと思う文もちゃんと発話してくれます。家庭の GPU 一日の学習でここまでできるのはすごい!

f:id:joisino:20171220195858p:plain
Attention  A を図示するとこの場合こんな感じになります。ちゃんと単調になっていますね。

Text2Mel を LJSpeech で学習させた loss はこんな感じでした。

f:id:joisino:20171220163012p:plainf:id:joisino:20171220163019p:plainf:id:joisino:20171220163028p:plain
順に L1 loss, binary divergence, guided attention loss

次に本番の唯のデータセットです。もちろんそんなデータセットは無いので、自分で用意します。

まずは JS で雑にアノテーションツールを自作しました。

アノテーションの付け方は IPA など音声と表記の結びつきが強い記号を用いるべきだったかもしれませんが、 LJSpeech で学習したモデルを唯のデータでファインチューニングすることも考えていたので、ローマ字表記にしました。促音とかが微妙なのでローマ字表記は避けた方が良かったかもしれません。「ゆゆ式」 -> "youyoushekey" みたいに英語っぽく表記するとかも考えていましたがこれは付けるときに大変なのと後で再利用が難しいのでボツにしました。

次に実際にアノテーションしていく訳ですが、これがなかなか大変でした。著作権的にクラウドソーシングするわけにもいかないので、自力でポチポチやってなんとか 6 話までアノテーションしたところで力尽きました。(多くの部分を手動でやりましたが、適当なモデルを使って自動で雑にくり抜いて、それを手で洗ったりするべきだったかもしれません。)

6 話まで終わった時点での発話データの長さは 12 分でした。一話あたり 2 分とは思ったより短かったです。

一応データは(全12話のうち)半分揃ったので、うまくいくかのあたりは付けられるだろうと考えて先に進むことにしました。

SSRN については、 LJSpeech で学習させたモデルを使っても wav -> mel -> (SSRN) -> STFT -> wav の変換でほとんど損失なく再現できることが分かったのでこのモデルを流用することにしました。

Text2Mel についてはもちろん流用はできないので、これの学習にとりかかることにします。

少し学習させてみたところ、やはり学習データが少ないだけあってすぐ過学習してしまいます。過学習をできるだけ避けるため、 dropout 率などハイパーパラメータを調整しました。

最終的に GTX 1080Ti を使い丸一日学習させました。結果は上のほうに貼ってあります。 loss はこんな感じでした。

f:id:joisino:20171220171531p:plainf:id:joisino:20171220171541p:plainf:id:joisino:20171220171556p:plain
順に L1 loss, binary divergence, guided attention loss

最後に、 JSUT (Japanese speech corpus of Saruwatari Lab, University of Tokyo) - Shinnosuke Takamichi (高道 慎之介) を使って学習させてみました。このデータには 24 時間分の単一女性の日本語音声ファイルとその原稿が含まれています。

「風船みたいな頭の子だな。」

「やっぱりもう少し考えて喋れ。」

抑揚は少しぎこちないですが、ほぼ完璧に発話できています。何度も言いますが GPU 1 枚の一日の学習でここまでできるのはすごい!

loss はこんな感じです。

f:id:joisino:20171223104705p:plainf:id:joisino:20171223104658p:plainf:id:joisino:20171223104648p:plain
順に L1 loss, binary divergence, guided attention loss

日本語のデータセットでも正しく学習できるということは、唯での実験がうまくいかなかったのは、やはりデータの質と量に問題がありそうです。

考察

  • 学習データが足りないのは確定的に明らかです。少なくとも 12 話全部と OVA 等利用できる音声全てにアノテーションを付ける必要はありますが、それでも実用的なものはなかなか厳しそうです。例えば船見結衣さん(ゆるゆり)や志々美かりんさん(プリティーリズム)などの声を流用するというのはアリかもしれません(それぞれ 36 話, 51 話あるのでかなりデータを増やせます)
  • DeepVoice2, 3 のように、多人数話者で学習できるモデルの一人の学習データとして唯の声を使うという手もあります。DeepVoice3 では VCTK という 108 話者・合計 44 時間のデータセットや LibriSpeech という 2484 話者・合計 820 時間のデータセットでの学習が成功し、話者一人あたりのデータが少なく済んでいるようなので、多人数の日本語音声コーパスさえ集まればこの手が良さそうです。僕の知ってる限り 声優統計コーパスJSUT くらいしか日本語音声コーパスが無いので現状では厳しいかもしれませんが試してみる価値はあると思います。もし他に良さそうなデータがあれば教えていただけると嬉しいです。
  • 僕が将来大富豪になったら青二に声優コーパス作るよう依頼します。なので神様、お金をください。

あとがき

データさえ集まればある程度のクオリティの音声合成ができるということと、現状の少ないデータ数でも最低限の発話はできるというのが分かったので良しとしましょう!

いつか manga2anime (マンガを入れるとアニメが出てくる)モデルを作るその日まで諦めずにやっていきたいと思います。

最後まで読んでいただきありがとうございました!メリークリスマス!よいお年を!!

参考文献

[1] [1710.08969] Efficiently Trainable Text-to-Speech System Based on Deep Convolutional Networks with Guided Attention

[2] Efficiently Trainable Text-to-Speech System Based on Deep Convolutional Networks with Guided Attention. [arXiv:1710.08969] - LESS IS MORE

[3] [1703.10135] Tacotron: Towards End-to-End Speech Synthesis

[4] [1712.05884] Natural TTS Synthesis by Conditioning WaveNet on Mel Spectrogram Predictions

[5] [1702.07825] Deep Voice: Real-time Neural Text-to-Speech

[6] [1705.08947] Deep Voice 2: Multi-Speaker Neural Text-to-Speech

[7] [1710.07654] Deep Voice 3: 2000-Speaker Neural Text-to-Speech

[8] WaveNet: A Generative Model for Raw Audio | DeepMind

[9] Pythonで音声信号処理 - 人工知能に関する断創録

[10] The LJ Speech Dataset

[11] 日本声優統計学会

[12] JSUT (Japanese speech corpus of Saruwatari Lab, University of Tokyo) - Shinnosuke Takamichi (高道 慎之介)