見返すかもしれないメモスマートフォン用の表示で見る見返すかもしれないメモ2017-12-17音響モデルから音素間の距離を求めるPythonしばらく前に、「"工藤"を誤魔化すための単語」みたいなツイートをしたら、予想外に伸びた。服部の「工藤の人」としての知名度ってすごいんやな。指摘をもらったんだけど、その中でも「Juliusで提供されている音響モデル(たくさんの人の声を統計的に学習したもの)で音素間の距離を定義できるとPanPhonよりもよくなるかもしれない」っていうアドバイスをめっちゃ試したいと思ったので、やってみることにした。知らないことばかりだったので、やったことをメモする。kitに入ってるhmmdefsって拡張子のやつが、モデルの定義ファイル。monophone用とtriphone用がある。"a-n+a"みたいに3つ並んでる音素に対してモデルを定義したやつたぶんtriphoneの方がちゃんと音素環境を考慮してるからいいと思うし、アドバイスしてくれた方もtriphone勧めてくださってたけど、とりあえずわかりやすそうなmonophoneを使った。HMM「音響モデル」って聞いて、何となく音声ファイルみたいなのを想像してたんだけど、めちゃくちゃ見当外れだった。(HMM)として定義されていた。HMMっていうのは、stateがある確率で変わっていって、変わるごとにある確率に基づいた何かを出力するってやつらしい。音響モデルは後戻りしないので、HMMの中でもleft-to-rightのものとして分類される。確かに遷移確率見たら、リピートするか次に進むかの二択しかなかった。Bookの7章読んだら何となくわかった。stateの数×stateの数の行列<ENDHMM>って感じで定義されている。stateは5個、mixtureは16個、meanやvarianceは25個だった。HMM同士の距離どうやってHMM間の距離測るんやろって思っていろいろ読んだけど、mixtureを含んでいるためそんな単純に計算できない(たぶん)。Measuresによると、片方のHMMから出したサンプルがもう片方のHMMから出力される確率がどれくらいかを測って、それを二つのHMMの近さと見なしたらいいっぽい。どれくらいばらつきがあるかわからんけど、一つの組み合わせにつき1000回やって、その平均を取ることにした。そのためには、HMMからサンプルを出す機能と、尤度を計算する機能が必要。hmmlearnがそういうことをやってくれるので、そのhmm.GMMHMMっていうモデルを使った。GMM→GaussianMixtureGMMHMMのプロパティのgmms_には、scikit-learnのGMMっていうオブジェクトが入っている。それがもう古いらしくて、GMMの代わりに新しいGaussianMixtureを使えってwarningが出る。github.comhmmlearnのissueで話し合ってくれてはいるけど、途中で終わってる。自分で勝手にhmm.py内のGMMを全部GaussianMixtureに書き換えてしまった。それに伴って、sample()の引数とかscore()の戻り値の形式など変更があったところに対応できるようにちょっと直した。個々のMixtureの分のパラメータ(weights_とかmeans_)をGMMHMMから設定する方法がわからんかったので、gmms_に入ってるGaussianMixtureオブジェクトに対して直接_set_parameters()してしまった。そのときにprecisions_choleskyというものが欲しいみたいなんだけど、それが何なのか理解すらできなかったので、GaussianMixture._compute_precision_cholesky()を使って出してもらった。調節とかleft-to-rightのモデルだから、最後のstateから行くとこがないので、遷移確率の行列の最後の行は全て0になる。遷移確率の行ごとの合計が全て1にならないとscore()でエラーが出る。したらいいかわからんけど、とりあえずリピートするところを1にした。遷移確率や分散に0があるとエラーになるので、めちゃくちゃ小さい値に置き換えた。普通のHMMは延々と続くので、sample()するときには何回繰り返すかを指定するんだけど、音響モデルはleft-to-rightだから最後のstateに辿り着いたら止めるようにしてほしい。NotFittedErrorパラメータをセットして、やっとsample()できる!と思ったら、NotFittedErrorとかいうものが出た。fitした後じゃないとsample出してくれへんらしい。Mixtureの数じゃないと無理だけど)。適当にfitする→ちゃんとしたパラメータをセットする→sample()するっていう流れになった。GMMHMMとGaussianMixtureでの引数名が指すものなんかcomponentとか微妙に意味が違うからややこしい。n_featuresそれぞれの音素がHMMとして定義されてて、そのHMMの中にstateがいくつかあって、それぞれのstateの出力確率がいくつかのmixtureから成ってて、それぞれのmixtureにfeatureが決められている。likelihoodの行列(左がサンプルを出したもとのHMM、上がそのサンプルを出す尤度を測ったHMM)を可視化すると、以下のようになった。対角線は見えてるけど、それより行ごとの違いが大きすぎる。likelihood)としたグラフを描いてみた。すごいあからさまに影響されてる。濃い青色のところは、行列では対角線上に当たる部分、つまり同じ音素同士を比べたときのスコア。これがだいたい横一直線になってもらわないといけないと思う。めちゃくちゃな方法で値を操作した結果、次のような行列になった。さっきに比べたらわりと納得できる感じになったと思う(適当)。距離の可視化ツイートに書いたのと同じ方法で、音素間の距離を可視化した。何となく同じような属性を持つ音素同士で固まってるようなので満足!あの意味わからん数字の羅列だったHMM定義ファイルの中身が、処理してみたらちゃんと人間の知覚に沿った感じになってるの、何かすごいな。やりたいことがあった気がするけど、期末テストやってるうちに自分が何してたのか忘れてしまったので、終わる。(1)Searchはてなブログをはじめよう!YaaMaaさんは、はてなブログを使っています。ブログを報告するスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。