音声認識メモ(Kaldi)その5(学習 その2)
前回の続き。
学習用グラフを作成したら、アライメントを作成する。
初期モデルに対しては「bin/align-equal-compiled」コマンドを使用する。
bin/align-equal-compiled ark:fsts.0 ark:mosimosi.ark ark:equal.align.0
均等分割アライメントの出力結果は以下のとおり。
インプットとして渡したMFCCファイルの198フレームがtransition-idに置き換わる。
尚、右側のコロン以降は説明用に付加したもの。
均等分割アライメント(加工)
utterance_id_001 2 1 1 1 1 1 :sil(state0) 8 5 5 5 5 5 :sil(state1) 18 17 17 17 17 17 :sil(state4) 206 205 205 205 205 205 :M_B(state0) 208 207 207 207 207 207 :M_B(state1) 210 209 209 209 209 209 :M_B(state2) 242 241 241 241 241 241 :O_I(state0) 244 243 243 243 243 243 :O_I(state1) 246 245 245 245 245 245 :O_I(state2) 266 265 265 265 265 265 :S_I(state0) 268 267 267 267 267 267 :S_I(state1) 270 269 269 269 269 269 :S_I(state2) 194 193 193 193 193 193 :I_I(state0) 196 195 195 195 195 :I_I(state1) 198 197 197 197 197 :I_I(state2) 218 217 217 217 217 :M_I(state0) 220 219 219 219 219 :M_I(state1) 222 221 221 221 221 :M_I(state2) 242 241 241 241 241 :O_I(state0) 244 243 243 243 243 :O_I(state1) 246 245 245 245 245 :O_I(state2) 266 265 265 265 265 :S_I(state0) 268 267 267 267 267 :S_I(state1) 270 269 269 269 269 :S_I(state2) 188 187 187 187 187 :I_E(state0) 190 189 189 189 189 :I_E(state1) 192 191 191 191 191 :I_E(state2) 2 1 1 1 1 :sil(state0) 6 5 5 5 5 :sil(state1) 11 10 10 10 10 :sil(state2) 13 15 15 15 15 :sil(state3) 7 5 5 5 5 :sil(state1) 14 15 15 15 15 :sil(state3) 11 10 10 10 10 :sil(state2) 14 15 15 15 15 :sil(state3) 12 10 10 10 10 :sil(state2) 18 17 17 17 17 :sil(state4)
状態遷移(PATH)は、学習用グラフをもとに生成される。
(gdb) p path $25 = std::vector of length 49, capacity 64 = {0, 35, 1, 40, 33, 34, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 47, 28, 50, 29, 54, 30, 56, 28, 51, 30, 57, 29, 54, 30, 57, 29, 55, 31, 32}
数値はFSTにおけるState-Id
// First select path through ifst. vector<StateId> path;
結果はランダムになると思ったが、10回やっても同じ。
ソースを見たら、kaldi::RandIntの呼び出しで第3引数を渡していない。
fstext/fstext-utils-inl.h
size_t arc_offset = static_cast<size_t>(kaldi::RandInt(0, num_arcs_tot-1));
省略時のデフォルトはNULLだから、Rand()のインプットは同じ値(初期値)が使われ、実行結果は同じになる。
base/kaldi-math.h
// Returns a random integer between first and last inclusive. int32 RandInt(int32 first, int32 last, struct RandomState* state = NULL);
base/kaldi-math.cc
int32 RandInt(int32 min_val, int32 max_val, struct RandomState* state) {
均等分割アライメントができたら、これを元に統計量を求める。
gmmbin/gmm-acc-stats-ali 0.mdl ark:mosimosi.ark ark:equal.align.0 0.acc
統計量の出力フォーマットは以下の通り。
最初のカッコ内は、transition-idごとのカウント、その後ろはpdf-id(phone、HMM-stateで識別できるようにしたもの)に関するもので、専有数(OCCUPANCY)などが分かる。
[ 0 9 2 0 0 13 1 1 1 0 12 2 1 1 2 12 0 9 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4 1 4 1 4 1 5 1 4 1 4 1 0 0 0 0 0 0 5 1 5 1 5 1 0 0 0 0 0 0 4 1 4 1 4 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 9 2 9 2 9 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 9 2 9 2 9 2 0 0 0 0 0 0 ] <NUMPDFS> 98 <GMMACCS> <VECSIZE> 13 <NUMCOMPONENTS> 1 <FLAGS> 15 <OCCUPANCY> [ 11 ] <MEANACCS> [ 583.025 -77.64178 -50.17585 77.67705 1.827717 -98.23819 141.6106 68.02332 -25.67511 138.0809 -28.37501 51.49424 -60.51704 ] <DIAGVARACCS> [ 31450.12 980.6454 1569.188 971.1459 888.6505 4001.74 2254.043 769.4111 1730.576 2365.113 1063.856 679.8729 789.1522 ] </GMMACCS> (途中省略、残りのPDF-ID 97個分が続く) <total_like> -678789.2 <total_frames> 198
続けて学習を行う。
gmmbin/gmm-est --min-gaussian-occupancy=3 0.mdl 0.acc 1.mdl
学習用サンプルが少ないので、オプションを追加している。
これを付けないと、出現数の少ないpdf-idに関するモデルが更新されない。
一部のモデルが初期値のままだと、後続のアライメントに失敗する。
--min-gaussian-occupancy : MleDiagGmmOptions: Minimum occupancy to update a Gaussian.(float, default = 10)
続けてアライメントを行う。
gmmbin/gmm-align-compiled 1.mdl ark:fsts.0 ark:mosimosi.ark ark:1.ali
続けて統計量を作成し、学習する。これはインプットが変わっただけで、前項でやっていることと同じ。
gmmbin/gmm-acc-stats-ali 1.mdl ark:mosimosi.ark ark:1.ali 1.acc gmmbin/gmm-est --min-gaussian-occupancy=3 1.mdl 1.acc 2.mdl
(参考)1.acc
[ 0 8 2 0 0 8 1 0 1 0 24 1 1 0 1 12 0 5 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4 1 4 1 6 1 5 1 4 1 5 1 0 0 0 0 0 0 3 1 7 1 5 1 0 0 0 0 0 0 3 1 4 1 4 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 10 2 6 2 14 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 2 4 2 17 2 0 0 0 0 0 0 ] <NUMPDFS> 98 <GMMACCS> <VECSIZE> 13 <NUMCOMPONENTS> 1 <FLAGS> 15 <OCCUPANCY> [ 10 ] <MEANACCS> [ -115.1633 37.34524 52.23244 40.05222 16.03667 8.719225 85.01067 68.30832 11.52509 34.59558 62.21133 -23.4759 -52.60085 ] <DIAGVARACCS> [ 1822.415 538.1805 1578.469 610.5429 804.1371 3180.515 1147.177 790.0551 1260.287 790.6093 1341.816 235.106 707.7091 ] </GMMACCS> (途中省略、残りのPDF-ID 97個分が続く) <total_like> -8444.121 <total_frames> 198
最下部に着目するとスコアが更新されていることが分かる。