目次
Julius は,与えられた入力音声(特徴量系列)に対して,音響モデルと言語モデルのもとで確率が最大となる単語列を見つけ出す.本章では Julius がいかに音声認識処理を実行するか,その認識アルゴリズムについて概要を述べる. また,パフォーマンスチューニングのための種々の探索用パラメータ設定について解説する.
Julius の音声認識アルゴリズムは,ツリートレリス探索方式を基礎とするアルゴリズムである.全体は2パス構成となっており,2段階に分けて認識処理を行う.まず,第1パスでは入力全体に対して荒い認識処理を行い,有望な候補の集合をある程度絞り込む.このとき,簡便なモデルや近似計算を用いることで高速に処理を行う.第2パスでは詳細な認識処理を行うが,その際に第1 パスの結果を参照しながら探索を行うことで,必要な部分にだけ精密な再計算を行って,最終的な最尤解を求める.このように複数回の照合によって段階的に候補を絞り込むことで,大語彙においても精度を落とさずに効率の良い認識を行うことを目標としている.
アルゴリズムの詳細を述べる.まず第1パスでは,音声入力と並行して,入力の始端から終端に向かってleft-to-right にフレーム同期ビーム探索を行う. 探索アルゴリズムは木構造化辞書に基づくものである.Julius では第1パスは第2パスのための前段処理であり,通常の1パス音声認識よりも強い近似を用いて高速性をある程度優先している.具体的には,単語履歴の 1-best近似, N-gram における 1-gram factoring, 部分線形化辞書,単語間トライフォン近似を用いている.
第1パスで用いられる言語制約は言語モデルごとに異なる.単語N-gram の場合は,そのN-gram中の前向き2-gramが適用される.記述文法の場合は,文法から単語間の接続制約のみを抽出したカテゴリ対制約が用いられる.なお,このカテゴリ対制約は文法読み込み時にJulius 内部で自動生成される.
第1パスの結果として「単語トレリス」と呼ばれる単語候補集合が算出される.これは,第1パスの認識処理中の各フレームにおいて,ビーム内に終端状態が残った単語候補をインデックス化して保存したものである.それぞれの単語候補は, その始終端フレームと入力始端から単語末尾までの累積スコアを保持している. 第2パスではこの単語トレリスを参照しながらもう一度探索が行われる.
第2パスは,第1パスとは逆に,入力の終端から始端に向かって後ろ向き (right-to-left)に探索を行う.アルゴリズムはいわゆるスタックデコーディングであり,仮説を保持するスタックにおいて最もスコアの高い仮説から順次単語単位で仮説を展開する.探索中の部分文仮説の評価スコアは,その時点までの(後ろ向きの)スコアに,未探索部分のヒューリスティックとして第1パスで生成された単語トレリスを接続した値となる.このスコアに従って best-firstに探索を行い,最終的な認識結果を出力する.第2パスでは, 第1パスの結果単語トレリス上に残った単語についてのみ計算を行うため, 探索空間はあらかじめ絞り込まれており,詳細な計算を行うことができる. 言語制約は全制約を用い,単語間や履歴近似も行わない.
一般に,パス間の中間表現としては上位 N 個の文候補や単語グラフがよく用いられる.これに対して,Julius の単語トレリスは候補を上位のみに絞り込まず,下位を含めて登場した候補全てを残す.このため,第1パスで強い近似によって計算誤差が増大しても,中間結果の中に最尤仮説系列が含まれ,そのため第2パスで誤差を回復できる可能性が高い.この単語トレリスの性質により,Julius の第1パスでは,Viterbi経路の単語履歴依存性を考慮しない 1-best 近似や,1-gram factoring, 単語間の接続部における音素環境依存性の近似など,高速化のための様々な強い近似が用いられている.
なお,孤立単語認識の場合,単語間や単語履歴,言語モデルにかかる近似は必要なく,第1パスのみで正確な認識結果を出すことができる.このため,孤立単語認識では第2パスは実行されず,第1パスの結果が最終結果となる.
また,音声認識の計算の大部分は音響尤度計算が占めるが,Julius ではこの音響尤度計算について,混合ガウス分布の尤度を上位コンポーネントのみ求めるGaussian pruning を用いており,さらに尤度下位のトライフォンの尤度をモノフォンの尤度で代用する Gaussian mixture selection も利用可能である.
認識アルゴリズムで調整可能なパラメータを以下に示す.これらは認識処理オプション("-SR
")であり,モデルごとではなく認識処理インスタンスごとに設定する.
これらの探索パラメータは,認識精度を数%左右することもある重要なパラメー タである.Julius のデフォルト値は,一緒に配布されている日本語標準モデル用の値であり,あくまで参考値である.与えられた言語モデル・音響モデルの組み合わせでの最大性能を求めるにはチューニングが必須である.たとえばモデルおよびその組み合わせによって最適な重みは異なるし,たとえば,計算時間よりも精度を重視する場合はビーム幅を広く取る必要がある.性能評価実験等を行う場合は特に注意されたい.
統計言語モデルを用いた音声認識では,通常,言語モデルが与える尤度より, 音響モデルの尤度のほうがダイナミックレンジが対数尤度で数倍程度大きく, 扱う仮説が音響モデルに大きく引っ張られる.これを防いで言語制約を強調する目的で,言語モデルの尤度に一定の係数を乗じる言語重みが用いられる.
また,単語間の遷移に一定のペナルティを課すこともしばしば行われる.これは単語挿入ペナルティと呼ばれる.単語挿入ペナルティを大きく課すことで, 単語間の遷移を抑制することができる.これは,例えば「派手に」という発話が助詞の「は で に」と認識されるといったように,短い単語仮説が連続して生成されてしまい湧き出し誤りを起こす場合に,このペナルティを設定することで長い単語を優先させるといった効果が期待できる.
N-gram では,-lmp
weight
penalty
で第1パスの,-lmp2
weight
penalty
で第2パスの(最終の)言語スコア重みと挿入ペナルティを指定できる.ペナルティは負であれば単語挿入を抑制し,正であれば単語挿入を促進する.以下は重みをそれぞれ 8.0, 挿入ペナルティをそれぞれ -1.0, 0.0 とする場合の例である.
%
julius ... -lmp1 8.0 -1.0 -lmp2 8.0 0.0
文法では,-penalty1
penalty
, -penalty2
penalty
でそれぞれ第1パス,第2パスの単語挿入ペナルティを指定できる.
%
julius ... -penalty1 -10.0 -penalty2 -10.0
言語重みと挿入ペナルティの設定は,認識精度に直接的に影響を与える. Julius では,使用するモデルの種類によって適当なデフォルト値が用いられるが,最適な認識精度を得るには,モデルの組み合わせごとに適切な重みを与える必要がある.
第1パス,第2パスとも,解探索を行う際の仮説の足切り幅,すなわちビーム幅を設定できる.
ビーム幅の設定は,Juliusの認識精度および処理時間に最も大きく影響する. 小さいビーム幅を設定すると,計算する仮説の範囲が狭くなり,その結果処理は高速化される.ただし,小さくしすぎると最終的に一位になる解のパスが途中で足切りされる危険性が高まり,探索誤りによる認識エラーを生じる恐れが大きくなる.逆に,大きいビーム幅を指定すると,広い範囲を探索するため探索エラーが生じる可能性は低くなるが,そのぶん処理時間は長くなる.
第1パスのビーム幅は-b
で指定できる.単位は木構造化辞書上のノード数(HMM状態数)である.0 を指定すると全探索(ビーム幅=木構造化辞書の全ノード数)となり,足切りを行わずに全てのノードを計算するようにすることもできる.
第2パスのビーム幅は,スタックデコーディングにおける単語単位の展開制限幅であり,-b2
で指定できる.ある長さの単語展開回数がこの指定した上限値に達したら,それより単語数が短い仮説の展開を行わないようになる.これによって,スタックデコーディングが同じ場所で似た単語を展開しつづけて前に進まない状況を回避する.小さすぎる値は最尤仮説の発見を妨げ精度の低下を招くが,大きすぎると探索が終わりにくくなり,処理時間がかかるようになる.
-b
は第1パスのビーム幅を指定する.単位は木構造化辞書上のノード数(HMM状態数)である.0 を指定すると全探索(ビーム幅=木構造化辞書の全ノード数)となり,足切りを行わずに全てのノードを計算する.
-b2
で第2パスのビーム幅を指定する.これはスタックデコーディングにおける単語単位の展開制限幅であり,ある長さの単語展開回数がこの指定した上限値に達したら,それより単語数が短い仮説の展開を行わないようになる.小さすぎる値は最尤仮説の発見を妨げ精度の低下を招くが,大きすぎると探索が終わりにくくなり,処理時間がかかるようになる.
-sb
で第2パスの仮説尤度計算時のスコア幅を指定できる.
仮説展開時に仮説ごとの音響尤度を更新するが,その際にフレームごとのそれまでの仮説の最大値から一定幅より下のパスを計算から除外することで音響モデル照合のコストを下げる効果が有る.小さい値にするほど第2パスの音響尤度計算量が少なくなるが計算誤りにより仮説のスコアが得られなくなる可能性が高くなる.最適値は音響モデルの対数尤度のレンジによる.
-s
で仮説のスタックサイズを指定する.スタックサイズは,
スタックデコーダが保持する仮説スタックのサイズである.小さすぎると探索誤りが起こりやすくなるため,大きい値を与えるとよいが,大きすぎるとメモリを多く消費する.
-m
で第2パスの探索打ち切りのための仮説展開回数のしきい値を指定する.Julius は,指定した数の文仮説が見付かる前に仮説展開回数がこのしきい値に達したとき,探索を強制終了する.探索終了時に一つも文仮説が得られていない場合は,探索失敗(解なし)となる.大きい値を与えるほど,あきらめずに探索を続けるようになるが,計算時間がかかる.
-lookuprange
は,第2パスの単語展開時に単語トレリス内から次単語候補を抽出する際のフレーム範囲を指定する.値を大きくするほど,
周辺の多くの単語仮説を次単語候補として仮説展開するが,広くしすぎると余分な仮説を展開するため探索が前に進みにくくなる.
-looktrellis
は,文法を用いた認識において,単語仮説を単語トレリス内に残った単語に限定するオプションである.Julius は文法ベー
スの認識の場合,次に文法上接続しうる仮説をすべて展開する.このとき,大語彙の文法,あるいは1音素からなるような短い単語が多い文法の場合,似た場所で大量の仮説が生成されて探索が進みにくくなり,第2パスの速度が通常よりも極端に遅く,認識精度も低くなることがたまにある.この場合,
-looktrellis
を指定することで展開仮説が絞られ,探索が安定化・高速化することがある.ただし,副作用として短い単語が削除される誤りが増大することがある.
その他の探索に関するオプションを以下に列挙する.
-1pass
: 第1パスのみを実行する.
-no_ccd
, -force_ccd
: 単語間トライフォンの近似計算を行うかどうかを明示的に指定する.デフォルトは,音響モデルがトライフォンであれば自動的にオンとなる.
-iwsp
: 任意の単語間における短時間ポー
ズの挿入を許す認識を行う.このオプションを指定すると,Julius内部で全単語間にスキップ可能なショートポーズモデルを挟み込んだ認識が行われる.このオプションはマルチパスモード時のみ有効である.
挟み込まれるショートポーズモデルの名前はオプション
-spmodel
で指定できる.このモデルは,前後の音素コンテキストを考慮されず,また前後の音素のコンテキストとしてもスキップされる.
-transp
: 通常の単語挿入ペナルティに加え,
透過語の挿入ペナルティを指定することができる.デフォルトは 0 である.
Julius は通常,認識結果として最尤の候補一つを出力する.この結果出力を設定によって変更することが可能である.以下に出力可能な形式と結果の見方を解説する.
-n
で,指定された数の文仮説数が見付かるまで探索を行う.
また -output
で,その見つかった仮説のうち,実際に出力する上位仮説数を指定する.
N-gramを用いた認識では,ヒューリスティックの非適格性から最初に見つかる仮説が最尤でないことがしばしばある.このため,-n
の値を 3 から 5 程度にしておくことで,最尤解を正しく得られる可能性が高くなる.大きい値を与えるほど第2パスの探索時間が長くなる.また,最上位以外の候補を出力したい場合は -output
を指定する.
以下に "-n 3 -output 3
" としたときの出力例を示す.
"sentence
" で始まる行が第2パスの認識結果の出力文字列,"wseq1
" は言語モデルのエントリ列(N-gram ではN-gramエントリ名,文法ではカテゴリ番号)である.
"phseq
" は音素並びであり,"|
"
は単語区切りを表す.また,"cmscore
" は認識結果の各単語の単語信頼度を表す."score
" はその仮説の尤度であり,音響モデルの出力確率と重みづけられた言語モデルの出力確率の対数尤度の和である.別々にスコアを出力したい場合は,オプション
"-separatescore
" を指定する.それぞれにおいて,後ろの数字が順位を表す.
sentence1: 個人技 が 、 随所 で 光っ た 。 wseq1: <s> 個人技+コジンギ+2 が+ガ+58 、+、+75 随所+ズイショ+2 で+デ+58 光っ+ヒカッ+光る+44/17/8 た+タ+70/47/2 。+。+74 </s> phseq1: silB | k o j i N g i | g a | sp | z u i sh o | d e | h i k a q | t a | sp | silE cmscore1: 0.441 0.312 0.286 0.162 0.233 0.406 0.339 0.419 0.813 1.000 score1: -5333.988281 sentence2: 個人技 が 随所 で 光っ た 。 wseq2: <s> 個人技+コジンギ+2 が+ガ+58 随所+ズイショ+2 で+デ+58 光っ+ヒカッ+光る+44/17/8 た+タ+70/47/2 。+。+74 </s> phseq2: silB | k o j i N g i | g a | z u i sh o | d e | h i k a q | t a | sp | silE cmscore2: 0.441 0.327 0.648 0.233 0.406 0.339 0.419 0.813 1.000 score2: -5342.767578 sentence3: 個人技 が 、 随所 で 勝っ た 。 wseq3: <s> 個人技+コジンギ+2 が+ガ+58 、+、+75 随所+ズイショ+2 で+デ+58 勝っ+カッ+勝つ+44/13/7 た+タ+70/47/2 。+。+74 </s> phseq3: silB | k o j i N g i | g a | sp | z u i sh o | d e | k a q | t a | sp | silE cmscore3: 0.441 0.312 0.286 0.162 0.231 0.408 0.075 0.419 0.813 1.000 score3: -5343.241211
なお,第2パスの再探索は第1パスで残った仮説集合に対して行われるため,多くのバリエーションの仮説を残すには,第1パスのビーム幅も大きくしておくほうがよい.
認識結果の上位仮説集合を,単語グラフ(ラティス)形式で出力できる. Julius の単語ラティス生成アルゴリズムは,第2パスのスタックデコーディング中に有望な単語仮説を逐次保存するものである.
オプション -lattice
で単語ラティスの出力が行える.ただし,このオプション指定時,第2パスの探索アルゴリズムの一部が,グラフ出力を考慮したものに変更される.このため,同時に出てくるN-best文候補は,
グラフ出力を行わない通常の N-best とは異なることがある点に注意されたい.
十分な大きさのグラフを得るには,第1パスで多くの候補を残し,かつ第2パスでもある程度以上長く行う必要がある.-b
,
-b2
に大きい値を指定し,-n
も小さすぎるとグラフが生成されないので 5 以上程度の値を指定する方がよい.
グラフの生成に関するパラメータがいくつか設定できる.オプション
-graphrange
は,同一単語をマージするオプションである.
"-1" を指定すると仮説のマージを行わない(たとえ同一位置に同一単語があっても,左右のコンテキストが異なれば異なる仮説として扱う).0 以上の値を指定すると,始終端フレームのずれがそれぞれ指定値以内である同一の単語について,尤度の高い方にマージする.値を大きくするほど小さいグラフが生成されるが,コンテキストの情報が失われる.また-graphcut
はグラフの深さのカットオフ値である.
-graphboundloop
はマージにおける dead loop 回避のための繰り返し上限数,-graphsearchdelay
は単語候補生成タイミングに関するオプションである.この2つは通常は変更する必要はない.
出力例を以下に示す.[9]1単語ごとに以下のような情報が出力される. なお,実際には1単語あたり一行で出力されるが,ここでは説明のために適当に改行している.
24: [96..129] left=21 right=31,29 left_lscore=-13.968800 right_lscore=-37.530403,-36.043201 wid=11615 name="受賞" lname="受賞+ジュショー+17" f=-5320.787109 f_prev=-5327.085449 g_head=-2937.868652 g_prev=-2078.347656 forward_score=-102.234932 backward_score=-120.460266 AMavg=-25.326530 cmscore=0.072092 graphcm=0.119256 headphone=a-j+u tailphone=sh-o:+d
最初はこの単語の通し番号 (ID) であり,続く括弧内はマッチしたフレーム区間である.left
, right
は左右に接続する単語のリスト,left_lscore
, right_lscore
はそれぞれの言語スコアを表す.wid
は辞書上の単語番号,name
は出力文字列,lname
は言語モデルのエントリである.
Julius は第2パスの探索中にグラフを生成する.f
,
f_prev
, g_head
,
g_prev
はその探索中にこの単語が得られた際の仮説スコアを表している.n をこの単語としたとき,それぞれ左端での仮説スコア
(g(n) + h(n+1)), 右端での仮説スコア(g(n-1) + h(n)),左端での累積
Viterbiスコア g(n), 右端での累積Viterbi スコア g(n-1) + LM(n) をそれぞれ表す.ただし g(n) は単語 n の第2パスでのright-to-leftスコア,h(n) は第1パスでのleft-to-rightスコア,LM(n) は言語確率を表す.
julius はラティスが生成されたあとに再び forward / backward algorithm
を適用して,各単語ごとのグラフ上の事後確率に基づく信頼度を算出する.
forward_score
, backward_score
および graphcm
がそれにあたる.また,
cmscore
は本来の Julius の計算で求められる信頼度である.
headphone
, tailphone
は左コンテキストと右コンテキストを考慮した左端音素と右端音素である.
仮説がマージされたときは,最もスコアの高かった単語の情報が格納される.
オプション -confnet
で,認識結果を confusion network
の形で出力できるようになった.Julius の内部では,まず単語グラフを生成してから,仮説をマージしながら confusion networkを生成する.
十分な大きさのグラフを得るには,単語グラフと同様,第1パスで多くの候補を残し,かつ第2パスでもある程度以上長く行う必要がある.
-b
, -b2
に大きい値を指定し,
-n
も小さすぎるとグラフが生成されないので 5 以上程度の値を指定する方がよい.
第1パスの計算中に,その時点での最尤パスを漸次的に出力することができる.
-progout
を指定すると,一定時間おきに,その時点での最尤候補を出力する.インターバルはオプション
-proginterval
でミリ秒単位で指定できる.
バージョン 4 で変更された重要な仕様の一つに,探索失敗時の結果出力がある.バージョン 3.x では,第2パスの探索が失敗したとき,第1パスの最尤仮説をそのまま最終的な認識結果として代用して出力していた.これに対して, バージョン 4 以降では,第2パスの探索失敗時には,「認識誤り」として結果が出力されないようになった.
バージョン 3.x と同じように第1パスの結果を代用出力したい場合は,オプション "-fallback1pass
" を指定する.これにより,このオプションを指定することで,第2パスの失敗時に,第1パスの最尤仮説を最終結果として出力することができる.
Julius は認識結果の候補文を入力に対して再照合し,単語や音素ごとの対応区間を求めるアラインメント(forced alignment)が行える.結果として,単語や音素などの単位ごとに,マッチする区間の始終端フレームとその区間内の平均音響尤度が出力される.
単語単位のアラインメントは "-walign
", 音素単位は
"-palign
", HMM の状態単位は"-salign
"
を指定する.複数を同時に選択することもできる.N-best 出力の場合,候補ごとにアラインメントが行われる.
以下は "-walign
" の出力例である.最初のカッコ内がマッチした区間(フレーム単位),次が区間内の音響尤度のフレーム平均,
言語エントリ文字列,出力文字列となる.
=== begin forced alignment === id: from to n_score unit ---------------------------------------- [ 0 23] -21.430922 <s> [] [ 24 65] -24.608768 個人技+コジンギ+2 [個人技] [ 66 91] -25.395161 が+ガ+58 [が] [ 92 97] -29.494751 、+、+75 [、] [ 98 131] -25.065617 随所+ズイショ+2 [随所] [ 132 139] -25.297760 で+デ+58 [で] [ 140 170] -25.976215 光っ+ヒカッ+光る+44/17/8 [光っ] [ 171 185] -26.640495 た+タ+70/47/2 [た] [ 186 195] -23.992529 。+。+74 [。] [ 196 208] -22.155687 </s> [] re-computed AM score: -5172.585449 === end forced alignment ===
認識結果の各単語について,信頼度と呼ばれる指標を出力することができる. 単語信頼度は事後確率に基づいて算出され,0から 1 の値を取る.1 に近いほど,競合候補に比べて尤度の差が大きかったことを表し,認識結果として「信頼度が高い」と言える.また,0 に近い場合,似た確率を持つ多くの競合候補が存在したことを表し,認識結果として「信頼が低い」と見なせる.この信頼度を用いて,例えば低信頼度部分の除外や,高信頼度語のみから頑健な意図理解をする,といった応用が考えられる.ただし,環境や語彙の影響を受けやすく, 特に大語彙環境では信頼性が低い傾向にある.
信頼度は認識結果の出力で "cmscore
" で始まる行に,
1単語ずつ出力される.
Julius は,認識中の仮説情報に基づいて入力を区切って認識することができる. 息継ぎなどの短時間無音で入力を細かく区切りながら逐次認識する 「ショートポーズセグメンテーション」,さらにそれを無音区間をスキップするよう拡張した「デコーダベース VAD」を実装している. 以下にそれぞれについて説明する.
なお,Juliusでは「無音単語」の尤度を基準に区間判定を行う.この無音単語とは,無音音響モデルのみを読みとする辞書上の単語である.無音音響モデルは名前で指定でき,デフォルトは "sp
" である(オプション -spmodel
で変更可能).また,N-gram を用いた認識では文頭・文末の無音モデル(デフォルト:"silB
",
"silE
",-silhead
および
-siltail
で指定可能)も無音音響モデルとして扱われる.
また,上記で指定できる以外の無音音響モデル名は
-pausemodels
で列挙指定できる.
オプション "-spsegment
" を指定すると,
ある1入力を認識する際に,短時間の無音区間が現れるたびに細かく区切って順次確定させていくことができる.Julius のこの機能は「ショートポーズセグメンテーション」と呼ばれる.これによって,長時間の音声入力を自動的に区切りながら逐次的に認識を可能にする.
ショートポーズセグメンテーション有効時,Julius は辞書中の無音単語の仮説尤度から短時間無音区間の判定を行う.Juliusは第1パスにおいてフレームごとの最尤仮説をチェックし,無音単語が一位仮説となるフレームが一定時間以上続くとそれを無音区間と判定し,入力をそこで区切る.そして,区切られた区間について第2パスを実行し,仮説を確定した後,区切った部分から(のりしろ分少し遡って)認識を再開する.これによって,短い無音区間で認識処理を区切って確定しながら漸次的に認識を進めていくことができる.
ショートポーズセグメンテーションは,Julius を
configure
に--enable-decoder-vad
をつけてコンパイルすることで,さらにデコーダベースVADに拡張される.
上記オプションをつけてコンパイルしたJuliusを -spsegment
をつけて起動すると,Julius はデコーダベースVADを行う.
デコーダベースVADでは,ショートポーズセグメンテーションと同じ方法で無音区間の検出を行うが,その検出した無音区間が長い場合,認識処理は行われるがその間仮説の生成は抑制される.無音単語以外の単語が一位仮説になった瞬間,仮説の生成が再開され,その場から次の区間認識が始まる.
関連オプションとして -spdur
, -spmargin
,
-spdelay
がある.詳しくはマニュアルを参照のこと.