この記事は古いので、新しい解説記事を参照してください
1. 導入
Hiho氏のブログ・ニコニコ動画で紹介されている「ディープラーニングの力で結月ゆかりの声になってみた」のプログラムの実行手順を説明します。
簡単に動作確認ができるよう、結月ゆかりボイスを用意したレポジトリも用意しておりますが、デモ動画同様の精度にするためには少なくてもより多くのデータを収集する必用です。
ここでは手順のみを紹介して、より精度の高い学習を行うための「音声データの作り方」や「パラメータ調整」については触れません。(詳しい方教えて!)
筆者は音声変換については素人です。コマンド解説に関しては動作確認をしておりますが、理論面の説明に誤りがある可能性があります。
また、この記事では、 オリジナルのbecome-yukarinリポジトリではなく、筆者の解説用の改変become-yukairnの使用を前提に解説します。
「ディープラーニングの力で結月ゆかりの声になってみた」の情報
動画 : http://www.nicovideo.jp/watch/sm32724409
コード : https://github.com/Hiroshiba/become-yukarin
Blog: https://hiroshiba.github.io/blog/became-yuduki-yukari-with-deep-learning-power/
レポジトリ名の変更(2019/06)
レポジトリ名が変更されたようです。
便宜上、本記事では旧名のまま解説します。
- become-yukarin : 『ディープラーニングの力で結月ゆかりの声になるリポジトリ』-> 『誰でも好きなキャラの声になれるリポジトリ』
- yukarin『誰でもで結月ゆかりの声になるリポジトリ』 -> 『誰でも好きなキャラの声になれるリポジトリ』
本記事で使用するレポジトリ
説明を簡便化するため、データ配置場所などを勝手に決めました。
動作確認用リポジトリ : https://github.com/YoshikazuOota/become-yukarin
オリジナル become-yukarin を使用する場合は、config.json, config_sr.json などを編集する必要があります。
※注意1: 改変become-yukairn は最新のコミットが反映されていません
2018年 6月頃に作成したものなので、それ以降のコミットは反映されていません。
※注意2: 2019年 6月現在、become-yukarin リポジトリは旧式となっております。、「誰でも結月ゆかりの声になれるリポジトリ」 になります。本記事は旧コード版の解説になります。
環境構築方法
・ Ubuntu v19.04 (RTX対応)
・ Ubuntu v18.10 LTS : @sakamotothogo 様
・ Ubuntu v17.10 LTS
※注意3: GPUは 4GB以上のメモリがあるものを推奨します。第2弾の学習で、学習パラメータを調整すれば、GPUメモリ 3Gでも動きますが、自分自身は試しておりません(@BURI55 様は パラメータ調整でGTX 1060(3Gメモリ))で学習させております。
※注意4: RTX系のGPUを使う場合は Ubuntu v19の記事の方法で環境構築してください。記事では、v19(非LTS)を使用しておりますが、v18でも同様の方法で問題ないと思います(お好きな方を)。
※注意5: Voiceroid2 とは音声エンジンが異なっており、データを追加する場合はどちらかに統一したほうが良いかと思います。
筆者が調べた限りでは音声特徴量の分解した場合 Voiceroid+ EX と Voiceroid2 とで傾向が異なるようです。
※注意6: chainerui のバージョンについて(2018/08/06)
コメントでご指摘うけましたが、下記の2つのライブラリはバージョン依存するとのことです。
下記コマンドでバージョン指定をしてください。
pip install numpy==1.16.2
補足: コミット よりpip install chainerui==0.3
は必要なくなりました。
GPUがない or Linux PC がなくても諦めるのは早い!
Google Colaboratory でも学習できました!
GPUがなくても、Google Colaboratory で結月ゆかりの声になりたい
参考学習データ(第2段階)
音声: 柚月ゆかり
サンプリング:22050Hz
Voiceroidの利用規約に違反している可能性があるので削除しました
https://github.com/YoshikazuOota/become-yukarin_rt/blob/master/dat/model/yukari_2nd_22050/predictor_255000.npz
2. そもそも「ディープラーニングの力で結月ゆかりの声になってみた」って何やってんの?
うまく動かなければ
コメントもらえれば、一緒に調べさせてもらいますので、お声掛けください。
また、過去のエラーをまとめた記事も作りましたので、合わせてご参照ください。
『誰でも好きなキャラの声に』 become-yukarin, yukarin のトラブルシューティング
2.1 第1段階 : 音響特徴量の変換
音声を「基本周波数」・「スペクトル包絡」・「非周期性指標」の3つに分解して、話者・変換対象(ゆかり)の「それぞれの値の対応の法則性」に基づき、音声変換をします。
音声合成・音声変換の分野で一般的なアプローチのようですが、「それぞれの値の対応の法則性」を数式化するのが難しいようです。
そこをディープラーニングで「それぞれの値の対応の法則性」を機械学習させたのが今回の手法です。
ただし、この方法では高音質化には限界があるようです。
詳細は下記記事が参考になります。
https://qiita.com/ohtaman/items/84426cee09c2ba4abc22
2.2 第2段階 : スペクトログラムの変換
スペクトログラムを画像に見立てて、「第一変換後のスペクトログラム」を元に「オリジナルゆかり音声で作ったスペクトログラム」に変換することで高音質化をしているようです。
詳しくわかっていないため、下記の開発者ブログを参照願います。
https://hiroshiba.github.io/blog/became-yuduki-yukari-with-deep-learning-power/
3. 詳細手順
6.4 まで実行すれば、精度はともかく自分の声を結月ゆかり化できます。
目安作業時間は、6.1 の 自分の音声録音に 1時間 と 6.3の学習で(CPU: 10時間, GPU: 1時間)ほどです。
6. 第1段階の学習
- 6.1 音声データを用意する
- 6.2 音響特徴量切り出しをする
- 6.3 学習を回す
- 6.4 実際に使用する
7. 第2段階の学習
- 7.1 音声データを用意する
- 7.2 スペクトラムデータ化
- 7.3 学習を回す
- 7.4 実際に使用する
4. 音声データ・学習済みデータの配置について
音声データや学習データの配置は任意で問題ありませんが、説明の簡略化のために下記のように配置するとします。
開発者Hiho氏のコードにサンプルデータ追加・各種設定をした、お手軽お試しレポジトリも参考にしてください。下記レポジトリを使用した場合は、dat/in_1st_my_wav に自分音声(22050Hz, 16bit)を格納するだけでお試しできます。
test_data : 第1段学習 テスト変換用データ置き場
test_data_sr : 第2段学習 テスト変換用データ置き場
dat
├── config.json : 第1段学習 設定ファイル
├── config_sr.json : 第2段学習 設定ファイル
├── in_1st_my_wav : 第1段学習 自分の音声ファイル
├── in_1st_yukari_wav : 第1段学習 ゆかり音声ファイル
├── in_2nd_yukari_many_wav : 第2段学習 ゆかり音声ファイル
├── out_1st_my_npy : 第1段学習 自分の音声の学習用データ
├── out_1st_yukari_npy : 第1段学習 ゆかり音声の学習用データ
├── out_2nd_yukari_many_npy : 第2段学習 ゆかり音声の学習用データ
└── wav_text : 読み上げ文章のテキストファイル(著作権切れの小説文)
in_1st_yukari_wav, 2nd_yukari_many_wav のサンプルゆかりボイスは利用規約に違反している可能性があるので削除しました(ディレクトリは残してあります)
5. 最初に決めること
5.1 収録機材の決定
学習用の音声データを収録する機材は後で変更することができません。
機材を変更した場合、話者の音声特性が変わって精度が低下する可能性があります。
5.2 音声ファイルのサンプリング・ビットレート決定
become-yukarin のデフォルトである 24000Hz に合わせるのがいいかと思います。
声の特徴量は 10000Hz 以下に集中しているので、無理にサンプリングレートを上げる必要は無いようです。
※10000Hz の信号を扱うためには 20000Hz 以上のサンプリングが必要(シャノンのサンプリング定理より)
ただ、音声の録音は 44100Hz で保存して、あとで 24000Hzにリサンプリングする方がいいと思います。
リサンプリングツール
sox
手持ちの Voiceroid等 の出力フォーマットに合わせるのが、合理的だと思います。
- Voiceroid+ EX : 22050Hz, 16bit, モノラル
- Voiceroid2 : 44100Hz, 16bit, モノラル
- CeVIO : 48000Hz, 16bit, モノラル
サンプルリポジトリのデフォルト設定は Voiceroid+ EX に合わせてあります。
収録等でサンプリング間違いやすいのでご注意ください。
5.3 作業パスを固定
readmeに書いてあることですが、環境変数 PYTHONPATH に作業ディレクトリに追記する必用があります。
作業ディレクトリで下記を実行するか、環境変数の設定をしてください。
PYTHONPATH=`pwd`
5.4 サンプリング値を設定
become_yukarin/param.py の 5行目にサンプリングレードを記入してください
デフォルトは 24000 ですので、自分の環境に合わせて設定してください
この設定を行わないと、音声変換でエラーになります。*0
sample_rate: int = 24000 -> 22050, 44100 等
6. 第1段階の学習
6.1 音声データを用意する
Voiceroidで結月ゆかりボイスの生成をして、その音声を真似るようにして自分の声を収録してください。 *1
自分音声とゆかり音声は別ディレクトリに同じファイル名で設置してください。
当方のサンプルを利用されている方は、ゆかり音声(dat/in_1st_yukari_wav/v_*.wav)に対応する自分の音声ファイルを dat/in_1st_my_wav に設置してください。
サンプルは30文ほど用意してあります。
精度を気にしなければ会話内容は適当で構いません。細かく区切ったほうが読みやすくなります。また、一息で文章を読むよりも、音の判定のミスが減るかと思います。
例えば「今日は 東京へ 本を 買いに 行った」と言った文章でいいようです。 *2
読み上げテキストは下記あたりがオススメです
高精度化を狙う場合は @BURI55 様にコメントでいただいたように、 ATR503 コーパス(発音音声のバランスが取れている文章)などを使用してください *7
音声データ作成で気をつけることは?
音声データの作成についてはHiho氏は、下記のようにコメントしております。*3
-
音声ファイルの頭位置やタイミング
- 無音部分はトリミングするため、開始位置は気にしなくていい
- 文章を区切るタイミングは合わせたほうがいい
-
各音声ファイルの1ファイルの長さはどれくらいがよいか
-
長さは特にこだわっていない
-
読みやすさのために、5秒ぐらいの文章が良い
いくつぐらいデータを作ればいいの?
動作確認程度であれば、30文程度で良いかと思います。
高精度を期待するのであれば、500文以上必用のようです。*3
6.2 音響特徴量切り出しをする(scripts/extract_acoustic_feature.py)
音声ファイルから学習に使うデータを生成します。
オプションに下記の4つを指定してください。
- 自分の音声の配置ディレクトリ(-i1 in_1st_my_wav)
- ゆかり音声の配置ディレクトリ(-i2 in_1st_yukari_wav)
- 自分の音声の学習データ配置ディレクトリ(-o1 out_1st_my_npy)
- ゆかり音声の学習データ配置ディレクトリ(-o2 out_1st_yukari_npy)
python scripts/extract_acoustic_feature.py -i1 dat/in_1st_my_wav -i2 dat/in_1st_yukari_wav -o1 dat/out_1st_my_npy -o2 dat/out_1st_yukari_npy
実行できない場合は下記をチェックしてください。
- PYTHONPATH が設定されているか?(上記)
- ライブラリ等がインストールされているか?
- Linux, Mac環境で実行しているか(Windows不可)
- Python3.6.3 以上を使用しているか?
- Mac環境の場合 .DS_Storeファイルが意図せず処理対象になる場合があります。ソースの glob('')) となっている箇所を glob('.wav')) など適宜、拡張子をつけるようにしてください。(お試しレポジトリでは修正済みなので、ご参照ください)
6.3 学習を回す (train.py)
6.2 のデータから学習を行います。
学習の設定(初回)
recipe/config.json をコピーして、1.2 で生成したデータのパスを指定します。
下記の6行を適宜設定してください。
input_* は変換元(自分の声)を意味しており、target_* はゆかり声を意味します。
"input_glob": "dat/out_1st_my_npy/v_*.npy",
"input_mean_path": "dat/out_1st_my_npy/mean.npy",
"input_var_path": "dat/out_1st_my_npy/var.npy",
"target_glob": "dat/out_1st_yukari_npy/v_*.npy",
"target_mean_path": "dat/out_1st_yukari_npy/mean.npy",
"target_var_path": "dat/out_1st_yukari_npy/var.npy",
また、GPUが使える方は下記の -1 を 0 に変更してください
"gpu": -1, // cpu -1, gpu 0
学習実行
引数に下記の2つを指定する
- 学習 config.json ファイルパス(dat/config.json)
- 学習結果(モデル)の出力パス(dat/model/yukari_1st)
python train.py dat/config.json dat/model/yukari_1st
問題がなければ、 dat/model/yukari_1st に predictor_.npz が順次出力されます。
predictor_.npz の * にはイタレーション数が入り、デフォルトでは 5000回毎に出力されます。
GTX 970で実行した場合は 5000回あたり 9分程度かかりました。
動作確認用に、predictor_15000.npz 程度が出力されるまで待ってください
学習の進捗を確認する
dat/model/yukari_1st/log に学習の進捗が表示されます。
進みが気になるとき場合は、下記コマンド等で確認できます
watch -n 10 tail -50 dat/model/yukari_1st/log
6.4 実際に使用する(scripts/voice_conversion_test.py)
6.3 の学習データから、自分の音声をゆかり音声に変換します。
テスト用に自分の音声データを作成する
テスト用に自分の音声データを3つほど作成して、test_data に格納します。
この音声は、学習用の音声データとは違うものを用意してください。
6.3の学習結果の評価はこのテストデータに対して行います。*4
変換実行
引数に モデル名(dat/model/yukari_1st の yukari_1st の部分)を指定。
オプションに下記の3つを指定してください。
- 自分の音声ファイル配置ディレクトリ(-iwd dat/in_1st_yukari_wav)
- モデル配置ディレクトリ( -md dat/model)
- 使用する predictor_*.npz のイタレーション数( -it 15000)
python scripts/voice_conversion_test.py yukari_1st -iwd dat/in_1st_yukari_wav -md dat/model -it 15000
無事実行できると、 output/yukari_1st にゆかり変換したボイスが入ります。
この変換ボイスは test_data に格納されている自分の音声と 学習データから2つの音声になります。*5
同様の条件で自分の声を変換したサンプル
https://github.com/YoshikazuOota/become-yukarin/blob/master/change_sample/1st/test01.wav
学習データが30文ほどの場合、ゆかり変換ボイスはゆかりっぽい程度のノイズ混じりの声になっているかと思います。
一応、学習データ数を増やせば精度は改善するはずですが、筆者の場合それほど簡単に精度が上がりませんでした。
7. 第2段階の学習
6 で得たゆかりボイスを更に高音質化します。
よければ、筆者の作成した第2段データも参考にしてください。(もしこれより高精度化できたかたいらっしゃいましたら教えて!)
参考学習データ(第2段階)
音声: 柚月ゆかり
サンプリング:22050Hz
https://github.com/YoshikazuOota/become-yukarin_rt/blob/master/dat/model/yukari_2nd_22050/predictor_255000.npz
7.1 音声データを用意する
より多いゆかりボイスを用意することで、高精度化が望めます。
ヒホ氏は 10000文 作成下とのことで、一文 5秒とすると14時間ほどになります。
サンプルでは、160文程度ですが、効果は確認できると思います。
7.2 音響特徴量切り出しをする(scripts/extract_spectrogram_pair.py)
オプションに下記の2つを指定してください。
- ゆかりボイス格納ディレクトリ( -i dat/in_2nd_yukari_many_wav)
- 学習用データ出力ディレクトリ( -o dat/out_2nd_yukari_many_npy)
python scripts/extract_spectrogram_pair.py -i dat/in_2nd_yukari_many_wav -o dat/out_2nd_yukari_many_npy
7.3 学習を回す(train_sr.py)
学習の設定(初回)
recipe/config_sr.json をコピーして、下記の変数に2.2の出力ディレクトリをしていしてください。
"input_glob": "dat/out_2nd_yukari_many_npy/*.npy",
第1段階同様に、GPUが使える方は下記の -1 を 0 に変更してください。
更に、"batchsize" は 1としてください。1 にすると学習時にアラートが発生しますが、おそらく問題ないと思います。*6
これは処理単位を表すようですが、デフォルトの8だとメモリを大量消費してスワップが発生しやすくなります。
学習用PCのメモリが16Gですが、"batchsize"を2にするとメモリ不足でクラッシュします。
"batchsize": 1,
"gpu": -1,
学習実行
第1段階同様に、下記の2つを指定して実行する
- 学習 config.json ファイルパス(dat/config_sr.json)
- 学習結果(モデル)の出力パス(dat/model/yukari_2nd)
python train_sr.py dat/config_sr.json dat/model/yukari_2nd
こちらも動作確認であれば、イタレーション 15000 程度までの学習をすればいいかと思います。こちらの学習にはGPUを使っても 2時間ほどかかると思います。
7.4 実際に使用する
テスト用にデータを用意する
6.4の第1段階の出力音声をコピーして test_data_sr に格納します。
変換実行
引数に モデル名(dat/model/yukari_2st の yukari_2st の部分)を指定。
オプションに下記の2つを指定してください。
- 自分の音声ファイル配置ディレクトリ(-iwd dat/in_1st_yukari_wav)
- モデル配置ディレクトリ( -md dat/model)
Hiho氏のオリジナルレポジトリ版では、 -it オプションでイタレーション番号は指定できません。最も大きいイタレーション番号の学習データが使用されます。
お試しレポジトリ版では -it オプションが使用できます。
python scripts/super_resolution_test.py yukari_2nd -md dat/model -iwd dat/in_2nd_yukari_many_wav
または
python scripts/super_resolution_test.py yukari_2nd -md dat/model -iwd dat/in_2nd_yukari_many_wav -it 15000
無事実行できると、 output/yukari_2nd にゆかり変換したボイスが入ります。
この変換ボイスは test_data_sr においてある元音声よりも、微妙にゆかりさんっぽくなっているいるかと思います。
もっとデータ数を増やすと、わかりやすく声がキレイになります。
同様の条件での変換サンプル
https://github.com/YoshikazuOota/become-yukarin/blob/master/change_sample/2nd/test01.wav
8. より精度を上げるには?
基本的な使い方は以上になります。
あとは学習用の音声ファイルを増やしていけば、順当に精度が向上が期待できるはずですが、私の場合はそれだけでは精度向上しませんでした。
次回は高精度化の手法を紹介したいと思います。
また、説明の不足・ご不明点ありましたらご指摘よろしくおねがいします。コメントなどあれば、嬉しいです。
注記
*0: 映像業界は 48000Hzが基本で、その半分の 24000Hz をデフォルトにしているっぽいです。また、@BURI55 さんのコメントにある経緯も考えられます。
*1: やり方は自由ですが、筆者はこの方法が一番安定しました。もっと具体的な説明いりますか?
*2: 「ATR音素バランス503文」を使うのが良いようですが、大抵は有償で研究目的のみに利用可能となっているようです。Hiho氏は JNAS を使用しているとのことです(http://research.nii.ac.jp/src/JNAS.html)
*3: 参照: https://github.com/Hiroshiba/become-yukarin/issues/28)
*4: ここで学習データを使用してしまうと、汎用性がある学習ができたのか判定することができません
*5: 学習データから選ばれる2つの音声の 1つは学習に使われていた音声で、 もう1つ は学習中の評価に使われていた音声になります
*6: /usr/local/lib/python3.6/dist-packages/chainer/functions/normalization/batch_normalization.py:67: UserWarning: A batch with no more than one sample has been given to F.batch_normalization. F.batch_normalization will always output a zero tensor for such batches. This could be caused by incorrect configuration in your code (such as running evaluation while chainer.config.train=True), but could also happen in the last batch of training if non-repeating iterator is used.
*7 : @BURI55 様のコメントより
・音素バランス文とは2音節(ダイフォン)や3音節(トライフォン)の言葉をバランスよく含む文のことを言います。その有名なのがATR音声データベースBセットに含まれる俗にいう「ATR503文」ですが、文章はATRに著作権があるため(元ネタはあるらしい。)一般に流布している割には研究以外の使用はグレーです。
・JNASには新聞記事データベースとATR503文が含まれ研究目的なら有償で使え、ATRの音声データベースより安いです。(ATRは1セット35万、JNASは2万弱)
・最近フリーな音素バランス文としては日本声優統計協会(https://voice-statistics.github.io/)
の声優統計コーパスのものがあり、サブセットとして東大猿渡研JSUT(https://sites.google.com/site/shinnosuketakamichi/publication/jsut)や
・ドワンゴメディアビレッジのもの(https://dmv.nico/ja/articles/2stack_voice_conversion_article/)
があります。
・100文だけですがwikipediaの文章をもとにダイフォンをバランスよく配置した文となっています。
・声優統計コーパスの音素バランス文はこちら。(https://github.com/voicestatistics/voicestatistics.github.com/blob/master/assets/doc/balance_sentences.txt)
・その構築方法等はこちらです。(https://github.com/voicestatistics/voicestatistics.github.com/blob/master/assets/doc/method.pdf)
・青空文庫で同じくフリーな音素バランス文を構築した論文もあります。こちらです。(http://www.ias.sci.waseda.ac.jp/GraduationThesis/2015_summary/1W120506_s.pdf)
(https://www.ai-gakkai.or.jp/jsai2016/webprogram/2016/pdf/1079.pdf)
・フリーではありませんが、新聞記事から音素バランス文を構築した論文
(https://library.naist.jp/mylimedio/dllimedio/showpdf2.cgi/DLPDFR001778_PH1-36)
利用素材
-
いらすとや風 結月ゆかりの立ち絵です
http://seiga.nicovideo.jp/seiga/im7100012