音声認識による赤外線機器の操作 その 4【文法辞書作成編】
どうも,筆者です.
以前,辞書を作成したが,決まった単語のみの組み合わせだけだった.今回は,もう少し柔軟に対応できるように辞書を作成する.
関連ページ
workspacememory.hatenablog.com
文法認識の考え方
復習となるが,以前は,以下のような単語のパターンを入力していた.
電気つけて 電気オフ 明るくして 暗くして こだまにして テレビオン テレビ切って
この場合,「電気オフ」と「テレビ切って」や「電気つけて」と「テレビオン」等を使い分ける必要があった.この場合,命令をすべて覚える必要があるが,以下のように認識できれば多少の揺れにも対応できる.
# 電気をつけたい場合 電気つけて 電気をつけて 電気オン # テレビを付けたい場合 テレビつけて テレビをつけて テレビオン
上のパターンは「[家電の名前][操作方法]」という形式で置き換えられる. ここから,家電の名前と操作方法を定義し,これらに対応する文法を定義することで,上記のパターンに対応できることになる.
# 家電の名前 電気 テレビ # 操作方法 つけて オン # 文法 [家電の名前][操作方法]
Julius では,この考え方を用いて音声認識が行える.
記述文法認識キット
今回は,記述文法認識キット(grammar kit)を利用して,文法認識を行う.
語彙の作成
「~/juliusKit/grammarKit」以下に「controller」というディレクトリを作成し,この中で作業を行う.まずは,単語とその読みを「yomiWord.list」というファイルに定義する.この時,上記で用いる単語の組み合わせを考え,定義する.
~ $ pushd ~/juliusKit/grammarKit ~/juliusKit/grammarKit $ mkdir controller ~/juliusKit/grammarKit $ pushd controller ~/juliusKit/grammarKit/controller $ touch yomiWord.list ~/juliusKit/grammarKit/controller $ vim yomiWord.list # エディタは自分の使いやすいものを利用する # === ここから === 電気 でんき テレビ テレビ つけて つけて オン おん オフ おふ 切って きって 明るくして あかるくして 暗くして くらくして こだまにして こだまにして # === ここまで ===
そして,以下のコマンドで,読み方をローマ字形式に変換し,結果を「utf8_controller.voca」に格納する.
~/juliusKit/grammarKit/controller $ cat yomiWord.list | iconv -f utf8 -t eucjp | perl ../bin/linux/yomi2voca.pl | nkf -wLu > utf8_controller.voca ### 出力結果 ### # 電気 d e N k i # テレビ t e r e b i # つけて ts u k e t e # オン o N # オフ o f u # 切って k i q t e # 明るくして a k a r u k u sh i t e # 暗くして k u r a k u sh i t e # こだまにして k o d a m a n i sh i t e
ここから,出力した「utf8_controller.voca」を編集していく.やることとしては,先程「家電の名前」や「操作方法」という呼び名をつけたように,出力データにも名前を付ける.名前を付ける際は「% [名称]」という形式にする.今回は,以下のようにした.
# この行はコメント扱いとなる # 家電データ % KADEN 電気 d e N k i テレビ t e r e b i # 追加の助詞 を w o # 家電の操作 % MODE_KADEN つけて ts u k e t e オン o N オフ o f u 切って k i q t e # 電気に対する操作 % MODE_LIGHT 明るくして a k a r u k u sh i t e 暗くして k u r a k u sh i t e こだまにして k o d a m a n i sh i t e # 文頭と文末を表すデータ % NS_B silB silB % NS_E silE silE
ここで,必ず必要なのが末尾の「文頭と文末を表すデータ」である.これは,Julius で入力の無音区間と休止区間を表すために必要となる.
文法ファイルの作成
先程作成した語彙ファイルを利用して,文法ファイルを作成する.辞書ファイルの形式を以下に示す.
# 辞書ファイルの形式 # 文法は複数定義できる S : NS_B [文法1] NS_E # 文法1 S : NS_B [文法2] NS_E # 文法2 S : NS_B [文法3] NS_E # 文法3
今回は,家電の操作と電気に対する操作を定義することを考える.この場合,以下のような文法を作成すればよい.
S : NS_B [家電の名前] [操作方法] NS_E S : NS_B [電気に対する操作] NS_E
これを上に挙げた名称で置き換えれば,文法を作成したことになる.
S : NS_B KADEN MODE_KADEN NS_E S : NS_B MODE_LIGHT NS_E
これでも良いが,「テレビつけて」と「テレビをつけて」の両方に対応するため,上の文法を少し弄る.
S : NS_B KADEN_ MODE_KADEN NS_E
S : NS_B MODE_LIGHT NS_E
# KADEN_ の定義(「_」が付いていることに注意)
KADEN_ : KADEN
KADEN_ : KADEN WO
これを,「utf8_controller.grammar」として保存する.ここまでのディレクトリ構成を以下に示す.
~/juliusKit |--dictationKit_v4.3.1 |--word.dic |--word.jconf |--grammarKit | |--controller | |--utf8_controller.grammar | |--utf8_controller.voca |--outYomi.sh |--word.yomi # utf8_controller.grammar の中身 # === ここから === S : NS_B KADEN_ MODE_KADEN NS_E S : NS_B MODE_LIGHT NS_E # KADEN_ の定義(「_」が付いていることに注意) KADEN_ : KADEN KADEN_ : KADEN WO # === ここまで ===
語彙ファイルと文法ファイルから Julius で利用するデータを作成
語彙ファイルと文法ファイルから Julius で利用するデータを作成する.そのために,Julius をインストールした際のディレクトリから以下の 2 つをコピーしてくる.
~/juliusKit/grammarKit/controller $ cp -f ~/julius/gramtools/mkdfa/mkfa-1.44-flex/mkfa ./ ~/juliusKit/grammarKit/controller $ cp -f ~/julius/gramtools/mkdfa/mkdfa.pl ./
そして,データ生成用の Shell Script を作成する.ここでは,「compile.sh」という名前で保存する.
~/juliusKit/grammarKit/controller $ touch compile.sh ~/juliusKit/grammarKit/controller $ vim compile.sh # エディタは自分の使いやすいものを利用する # === ここから === #!/bin/bash # compile.sh controller="controller" grammarFile=utf8_${controller}.grammar vocaFile=utf8_${controller}.voca nkf -sLw ${grammarFile} > ${controller}.grammar nkf -sLw ${vocaFile} > ${controller}.voca perl mkdfa.pl ${controller} rm -f ${controller}.grammar ${controller}.voca # === ここまで ===
ここまでのディレクトリ構成を以下に示す.
~/juliusKit |--dictationKit_v4.3.1 |--word.dic |--word.jconf |--grammarKit | |--controller | |--compile.sh | |--mkdfa.pl | |--mkfa | |--utf8_controller.grammar | |--utf8_controller.voca |--outYomi.sh |--word.yomi
後は,Shell Script に実行権限をつけ,以下のように実行すると,メッセージが出力され,「controller.dfa」,「controller.term」,「controller.dict」が生成される.
~/juliusKit/grammarKit/controller $ chmod +x compile.sh ~/juliusKit/grammarKit/controller $ ./compile.sh ### 出力結果 # controller.grammar has xx rules # controller.voca has xx categories and yy words # --- # Now parsing grammar file # Now modifying grammar to minimize states[ww] # Now parsing vocabulary file # Now making nondeterministic finite automaton[zz/zz] # Now making deterministic finite automaton[zz/zz] # Now making triplet list[zz/zz] # xx categories, zz nodes, bb arcs # -> minimized: aa nodes, cc arcs # --- # generated: controller.dfa controller.term controller.dict
設定ファイルの作成
ひとつ上のディレクトリに戻り,以下に示す設定ファイルを作成する.ここでは,「controller.jconf」として保存した.
~/juliusKit/grammarKit/controller $ popd ~/juliusKit/grammarKit $ touch controller.jconf ~/juliusKit/grammarKit $ vim controller.jconf # エディタは自分の使いやすいものを利用する # === ここから === ###################################################################### #### 入出力指定 ###################################################################### -charconv SJIS UTF8 ###################################################################### #### ファイル指定 ###################################################################### ## ## DFA ファイル:文法から生成 ## これは別途指定のこと(ヘッダの例を参照) ## -dfa controller/controller.dfa ## ## 単語辞書ファイル ## これは別途指定のこと(ヘッダの例を参照) ## -v controller/controller.dict ## ## gram の指定 ## -gram controller/controller ## ## 音響HMM定義ファイル ## ## triphoneモデル # asciiフォーマット,もしくは "mkbinhmmで" 作成したバイナリ形式 # (自動判別される) -h model/phone_m/hmmdefs_ptm_gid.binhmm # PTM triphone -hlist model/phone_m/logicalTri ###################################################################### #### 言語モデル詳細設定 ###################################################################### ## ## 単語挿入ペナルティを指定 ## #-penalty1 0.0 # 第1パス #-penalty2 0.0 # 第2パス ###################################################################### #### 単語辞書詳細設定 ###################################################################### ## ## エラー単語を無視して続行する ## -forcedict ###################################################################### #### 音響モデル詳細設定 ###################################################################### ## ## Julius が triphone/monophone の自動判別に失敗する場合, ## 以下を試してみてください. ## #-no_ccd # 音素環境依存性を(強制的に)考慮しない #-force_ccd # 〃 (強制的に)考慮する ## ## 特徴パラメータの型チェックをスキップしたい場合は, ## 以下を試してみてください. ## #-notypecheck # ## ## PTM/triphone 使用時,第1パスの単語間triphoneの音響尤度計算方法を指定する. ## #-iwcd1 best N # 同コンテキストtriphoneの上位N個の平均値 #-iwcd1 max # 同コンテキストtriphoneの最大値 -iwcd1 avg # 同コンテキストtriphoneの平均値 (default) ###################################################################### #### Gaussian Pruning パラメータ(tied-mixture, PTMでのみ有効) ###################################################################### ## コードブックあたり計算するガウス分布計算数(上位N個) ## 以下のデフォルト値は IPA99 の PTM モデル(1コードブックあたり64混合) ## に合わせた値 -tmix 2 ## Gaussian pruning 法の選択 ## 高速版ではbeam,それ以外ではsafeがデフォルトです -gprune safe # safe pruning 上位N個が確実に求まる.正確. #-gprune heuristic # heuristic pruning #-gprune beam # beam pruning 次元ごとに足切り.高速. #-gprune none # pruning を行わない ###################################################################### #### Gaussian Mixture Selection パラメータ ###################################################################### #-gshmm hmmdefs # GMS 用モノフォン音響モデルを指定 # 指定なし = GMS OFF #-gsnum 24 # GMS使用時の選択状態数 ###################################################################### #### 探索パラメータ ###################################################################### #-b 400 # 第1パスのビーム幅(ノード数) monophone -b 800 # 第1パスのビーム幅(ノード数) triphone,PTM #-b 1000 # 第1パスのビーム幅(ノード数) triphone,PTM,engine=v2.1 -b2 30 # 第2パスの仮説数ビームの幅(仮説数) -sb 80.0 # score beam envelope threshold -s 5000 # 第2パスの最大スタック数 (仮説数) -m 2000 # 第2パスの仮説オーバフローのしきい値 -lookuprange 5 # 第2パスで単語展開時のトレリス制約緩和幅(フレーム数) -n 5 # 第2パスで見つける文の数(文数) #-n 10 # ('standard' 設定時のデフォルト) -output 1 # 第2パスで見つかった文のうち出力する数 (文数) #-looktrellis # 単語仮説を完全にトレリス内の単語だけに絞る ###################################################################### #### 単語間ショートポーズ ###################################################################### ## ## (マルチパス版のみ) ## #-iwsp # コンテキスト独立な単語間ショートポーズを付与 #-iwsppenalty 0.0 # ショートポーズへの遷移ペナルティ #-spmodel "sp" # ショートポーズ音響モデルの名前 ###################################################################### #### 音声入力ソース ###################################################################### ## どれかを選んでください(デフォルト:mfcfile) #-input mfcfile # HTK形式のパラメータファイル(MFCC) #-input rawfile # 音声波形データファイル(フォーマット自動判別) # 形式:WAV(16bit) または # RAW(16bit(signed short),mono,big-endian) # 16kHz以外のファイルは -smpFreq で周波数指定 -input mic # マイクから直接入力 #-input netaudio -NA host:0 # host上のDatLink(NetAudio)から入力 #-input adinnet -adport portnum # adinnet クライアントからの入力 #-input stdin # 標準入力からの入力 #-filelist filename # 認識対象ファイルのリスト -nostrip # ゼロ続きの無効な入力部の除去をOFFにする # (default: 無効な入力部分は除去される) -zmean # DC成分の除去を行う (-input mfcfile時無効) ###################################################################### #### 音声録音 ###################################################################### #-record directory # 認識した音声データを連続したファイルに自動保存 ###################################################################### #### 入力の棄却 ###################################################################### -rejectshort 800 # 指定ミリ秒以下の長さの入力を棄却する ###################################################################### #### 音声区間検出 ###################################################################### #-pausesegment # レベル・零交差による音声区間検出の強制ON #-nopausesegment # レベル・零交差による音声区間検出の強制OFF # (default: mic または adinnet は ON, file は OFF) -lv 3000 # レベルのしきい値 (0-32767) #-headmargin 300 # 音声区間開始部のマージン(単位: msec) #-tailmargin 400 # 音声区間終了部のマージン(単位: msec) #-zc 60 # 1秒あたりの零交差数のしきい値 ###################################################################### #### 音響分析 ###################################################################### #-smpFreq 16000 # サンプリング周波数(Hz) #-smpPeriod 625 # サンプリング周期(ns) (= 10000000 / smpFreq) #-fsize 400 # 窓サイズ(サンプル数) #-fshift 160 # フレームシフト幅(サンプル数) #-delwin 2 # デルタウィンドウ幅 (フレーム数) #-hifreq -1 # 高域カットオフの周波数(Hz) (-1: disable) #-lofreq -1 # 低域カットオフの周波数(Hz) (-1: disable) #-cmnsave filename # CMNパラメータをファイルに保存(1入力毎に上書き) #-cmnload filename # 初期CMNパラメータを起動時ファイルから読み込む ###################################################################### #### スペクトルサブトラクション (SS) ###################################################################### #-sscalc # 先頭の無音部を利用して SS を行う(ファイル入力のみ) #-sscalclen 300 # SSに用いる先頭の無音部の長さ (msec) #-ssload filename # ファイルからノイズスペクトルを読み込む #-ssalpha 2.0 # アルファ係数 #-ssfloor 0.5 # フロアリング係数 ###################################################################### #### Forced alignment ###################################################################### #-walign # 認識結果の単語ごとのアラインメント結果を出力 #-palign # 認識結果の音素ごとのアラインメント結果を出力 #-salign # 認識結果のHMM状態ごとのアラインメント結果を出力 ###################################################################### #### 単語信頼度計算 ###################################################################### #-cmalpha 0.05 # スムージング係数を指定 ###################################################################### #### 出力スタイル ###################################################################### #-separatescore # 言語スコアと音響スコアを分けて出力する #-progout # 第1パスで解析途中から漸次的に結果を出力 #-proginterval 300 # -progout 時の出力のインターバル(単位:msec) -quiet # 第1パス・第2パスの認識結果のみ出力 #-demo # "-progout -quiet" と同じ #-debug # 探索中の内部状態を出力させる(デバッグ用) ###################################################################### #### サーバーモジュールモード ###################################################################### #-module # サーバーモジュールモードで起動 #-module 5530 # (ポート番号を指定する場合) #-outcode WLPSC # モジュールに出力する情報を選択 (WLPSCwlps) # === ここまで ===
動作確認
以下のディレクトリでコマンドを実行したい際に,「<<< please speak >>>」が出力され,音声が認識されていれば成功である.
~/juliusKit/grammarKit $ ALSADEV="plughw:0,0" julius -C controller.jconf -demo