狠狠撸

狠狠撸Share a Scribd company logo
Common Lispで音声合成
Satoshi Imai / 今井 悟士
Twitter: @masatoi0 Github: masatoi
これまでの発表
● #29: 線形分類器cl-online-learningの実装
– http://www.slideshare.net/masatoi0/lispmeetup29-c
lonlinelearning
● #39: ディープラーニング用ライブラリMGLの紹介
– http://www.slideshare.net/masatoi0/lispmeetup-39
-mgl
今回の目標
●
ディープラーニングの応用として音声合成(テキスト読
み上げ)を試みる → 未完!
– ここまでの成果物: https://github.com/masatoi/cljtalk
● DNN音声合成の全体の流れを把握する
– Common Lispで実装するために必要な道具を揃える
● 音素アライメント → Julius、segmentation-kit
●
音声分析合成 → WORLD、cl-libworld
● メル周波数ケプストラム(MFCC) → libfftw3
色々なTTSシステム
●
波形接続型音声合成 (VOICEROID (結月ゆかり etc))
– 小さい音声の素片を連結して合成する
●
統計的音声合成
– HMM (CeVIO (さとうささら etc)、 Open JTalk)
● HMM(隠れマルコフモデル)を使うもの
– DNN
● 単純なFFNNを音声に適用 (簡単!)
– LSTM-RNN (Googleテキスト読み上げ)
●
再帰型ニューラルネット
– Wavenet (DeepMind) ← new!
色々なTTSシステム
●
統計的音声合成
– HMM
– DNN
– LSTM-RNN
– Wavenet
●
ボコーダーを介さず直接音声を予測する
●
畳み込みニューラルネットで自己回帰(自分の予測を入力の一
部として与える)
●
ボコーダーを使う
生の音声ではなく、音声を少数のパラメータ
に変換してそれを予測する
再合成時に劣化する
ボコーダー(音声分析合成)
●
生の音声からパラメータを取り出したり再合成したりする
● WORLD
– C++の音声分析合成ライブラリ
● cl-libworld
– https://github.com/masatoi/cl-libworld
– Common Lisp用のラッパーをCFFIで実装した
– WORLDのコードを丸抱えして、require時にLakeでビルドする
基本周波数(F0)
音の高さ
パワースペクトル
周波数毎の強さ
声道(口の形)を表す
非周期性指標
声のかすれ具合
メル周波数ケプストラム
●
まだパラメータ数が多いのでもっと圧縮したい
●
メルフィルタバンク
– 人間の耳にとって重要な周波数帯のスペクトルを重点的に
取るためのフィルタ
メル周波数ケプストラム
●
まだパラメータ数が多いのでもっと圧縮したい
●
メルフィルタバンク
●
スペクトルにメルフィルタバンクを掛けて対数変換する
かけてから
対数変換
メル周波数ケプストラム
● 離散コサイン変換(DCT)する
– 低周波帯に情報が集まる
● 上の方は切ってもいい! → 13次元でカット
● ここまでやったもの: メル周波数ケプストラム係数(MFCC)
– DCTはCのライブラリFFTWを使う(CFFIでラップ)
DCT
DCT
の逆変換
MFCCから音声まで戻す
● DCTの逆変換は無劣化でできる (上を切らなければ)
● それからexpをかける
●
元のスケールに戻して、スプライン補間をかける
スケール変換
スプライン補間
exp
MFCCから音声まで戻す
●
スプライン補間
– データ点の間を三次曲線で滑らかに繋ぐ
– データ数のサイズの逆行列を計算する必要があるが、三重対角行
列なのでO(N)でできる
DNNの出力データを作る
● 非周期性指標はDCTで5次元まで圧縮する
● F0が1次元、スペクトルが13次元、非周期性指標が5次元で1フレーム当たり19
次元の特徴量になる
入力データを作る
●
音素アライメント
– テキストデータと音声から音素の開始時間と終了時間を
推定する
– Juliusのsegmentation-kitが使える
0.0000000 0.0925000 silB
0.0925000 0.2625000 a
0.2625000 0.4125000 i
0.4125000 0.5225000 u
0.5225000 0.5825000 e
0.5825000 0.7525000 o
0.7525000 0.7825000 silE
あいうえお
入力データを作る
●
音素アライメント
– テキストデータと音声から音素の開始時間と終了時間を
推定する
0.0000000 0.0925000 silB
0.0925000 0.2625000 a
0.2625000 0.4125000 i
0.4125000 0.5225000 u
0.5225000 0.5825000 e
0.5825000 0.7525000 o
0.7525000 0.7825000 silE
入力データを作る
●
音素をフレームに割り当てる
– 一つのフレーム毎の特徴量
● どの音素に属しているか? → 38次元のバイナリ特徴
● その音素の継続時間(duration) 1→ 次元の実数
●
その音素が割り当てられているフレームの中で何番目か
→ 1次元の整数
DNNの構造
“Deep Learning in Speech Synthesis” [H.Zen, 2013]
T個のフレームの特徴量を一列に並べてDNNの入出力とする
MGLとは
● Common Lisp用の機械学習ライブラリ
●
ディープラーニングの割と最近の手法までカバー
● MGL-MATという行列演算ライブラリを使う
– cl-cuda、LLA(Lisp Linear Algebra)によって高速化
● cl-cudaがQuicklispに入ったことによりMGL-MATもQuicklispから入
るようになった!
MGLで回帰問題を解く
● 回帰のやり方はドキュメントが無いのでMGLのソースと格闘する
● まず簡単な2次元→1次元の関数を近似する
元の関数 近似結果
(defun?rastrigin?(x?list)
??(let?((n?(length?x?list)))
????(+?(*?10?n)
???????(loop?for?xi?in?x?list?summing
?(??(*?xi?xi)?(*?10?(cos?(*?2?pi?xi))))))))
MGLで回帰問題を解く
● build-fnnマクロでネットワークの構造を指定してオブジェクトを生成
– 入力層2次元、1200次元の隠れ層が3層、出力層1次元
– 隠れ層の活性化関数はReLU、出力層の活性化関数は恒等写像、誤差関数は
二乗誤差
(defparameter?fnn?regression
??(build?fnn?(:class?'regression?fnn?:max?n?stripes?100)?;?バッチサイズ100
????;;?Input?Layer?2次元
????(inputs?(?>input?:size?2))
????(f1?activations?(?>activation?inputs?:name?'f1?:size?1200))
????(f1?(?>relu?f1?activations))
????(f2?activations?(?>activation?f1?:name?'f2?:size?1200))
????(f2?(?>relu?f2?activations))
????(f3?activations?(?>activation?f2?:name?'f3?:size?1200))
????(f3?(?>relu?f3?activations))
????(prediction?activations?(?>activation?f3?:name?'prediction?:size?1))
????;;?Output?Lump:? squared?difference?1→ 次元
????(prediction?(?>loss?(?>squared?difference?(activations?output?prediction?activations)
??????????????????????????????????????????????(?>input?:name?'targets?:size?1))
????????????????????????:name?'prediction))))
DNN音声合成のためのモデルを作る
● 一度にDNNに与えるフレーム数Tを20とする
● 入力40*20=800次元、出力19*20=380次元
●
しかしこれで学習してみると数値計算エラー!
(defparameter?fnn
??(build?fnn?(:class?'regression?fnn?:max?n?stripes?100)
????;;?Input?Layer
????(inputs?(?>input?:size?800))
????(f1?activations?(?>activation?inputs?:name?'f1?:size?512))
????(f1?(?>relu?f1?activations))
????(f2?activations?(?>activation?f1?:name?'f2?:size?512))
????(f2?(?>relu?f2?activations))
????(f3?activations?(?>activation?f2?:name?'f3?:size?512))
????(f3?(?>relu?f3?activations))
????(prediction?activations?(?>activation?f3?:name?'prediction?:size?380))
????;;?Output?Lump:??>squared?difference
????(prediction?(?>loss?(?>squared?difference?(activations?output?prediction?activations)
??????????????????????????????????????????????(?>input?:name?'targets?:size?380))
????????????????????????:name?'prediction))))
まとめ
● 音声合成のための特徴量を揃えたが肝心のDNNの学習に失敗
– 出力が多次元のより単純な回帰問題で学習の進行を観察する
●
入力の特徴量もアクセントやイントネーションを無視しているので、テキ
ストを分析してこれらの情報を付与するようにしたい
– さらにユーザが簡単にアクセントなどを調整するためのGUIを用意
● CFFIでCのライブラリが簡単に呼べるのでライブラリ不足は感じない
– 今回はWORLDとFFTWのラッパーを書いた

More Related Content

Lispmeetup #45 Common Lispで音声合成