Juliusで認識文法とN-gramを併用する

こんばんは、お久しぶりです。

今回は他研究室の卒論生のお手伝いということで、Juliusにおいて認識文法とN-gramによる認識を併用する、という方法を扱うことになったので、ここにまとめておきます。

まず、Juliusとは京大河原研で開発されたフリーウェアの大語彙連続音声認識デコーダです。音声認識技術は音響モデル、言語モデル、そしてデコーダから構成されるのが一般的ですが、Juliusはデコーダに加えてデフォルトで音響モデルと言語モデルが付属しており、高い汎用性を備えています。

音声認識にはおおまかに分けて、孤立単語認識、認識文法による認識、大語彙連続音声認識の3種類があります。

孤立単語認識とは、個々の単語を対象として認識を行うものです。最近ではGoogle音声認識などが一番イメージに近いと思います。ちなみに、Google音声認識はかなり広範な語彙を扱う上にディクテーションに近いような認識も行うので、ここに分類するわけではないです。こんな認識もできますよ。


認識文法とは、予め文章のパターンを指定しておき、そのパターン通りの認識を行うようなものです。語彙が決まっているロボットの操作などには、これが適していると言われていますね。例えばロボットの動作を音声で制御する場合

右に回れ
前に進め
止まれ

のような限られた語彙しかないわけです。そうすると、あらかじめ登録した語彙だけ認識できればそれでいいわけですね。


大語彙の認識とは、普通の読み上げ文や講演の音声などを認識するようなものですね。日本の国会の議事録作成にも利用されています。

衆議院の新会議録作成システムにおける京都大学の音声認識技術の導入 — 京都大学


さて、Juliusではこれらのいずれもサポートしているわけですが、2007年にVersion 4にアップデートされるまで、認識文法を扱うバイナリであったJulianと、N-gram(大語彙)を扱うJuliusが存在していました。それがVersion 4で統合され、これらの機能を同時に利用できるようになりました。そこで、同じ音声に対してこれらのモデルを同時に利用する方法を紹介します。


まず、先程のJuliusのページからJuliusのディクテーションキットを落としてきます。そうして適当な場所に保存したディクテーションキットのフォルダを見ると、fast.jconfなるものがあります。これがJuliusの設定ファイルですね。

先頭の行が#の行はコメントアウトされており、実際にJuliusを動かすのに反映されるのは#がついていない行だけです。これを見ながら、Juliusの設定ファイルを作ります。

-input mic
-AM tri -h model/phone_m/hmmdefs_ptm_gid.binhmm -hlist model/phone_m/logicalTri
-LM grammar -gram /model/fruit
-LM ngram -C web.jconf
-SR fruit tri grammar -looktrellis
-SR web tri ngram -separatescore -b 800 -b2 50

まずテキストエディタを開き、こんな感じのjulius.jconfを作ります。普通のjconfの書き方だと、-h, -hlistなどは別々に指定するのですが、今回の方法では-AMの後にまとめて指定します。この記法では、「AMのtriという設定は-h(音響モデル)と-hlist(トライフォン)はこれを使いますよ」ということを指定するわけですね。例はJuliusのディクテーションキットデフォルトのモデルを指定してあります。

\-LM grammar と書いてあるのは、言語モデルで認識文法を利用しますよ、という指定です。-LM ngram はN-gramの大語彙モデルを使いますという指定ですね。

ここで、-LM grammar の下に書いてあるfruitというのは、果物の認識文法サンプルを
GitHub - julius-speech/julius: Open-Source Large Vocabulary Continuous Speech Recognition Engine
から落としてきたものです。例のように試すには、グラマーキットの中にある、SampleGrammarsの中の、fruitのフォルダをディクテーションキットのmodelフォルダの中にコピーすれば良いです。

\-LM ngram に書いてある web.jconf という設定ファイルは、また別に用意してやる必要があります。別のファイルをエディタで開いて、

-d model/lang_m/web.60k.8-8.bingramv4.gz
-v ../../model/BASEBALL_s.htkdic
-charconv euc sjis

と書いて保存します。-dは言語モデル、-vはその辞書の指定ですね。-charconv は文字化けがおこらないようにするものです(Julius付属のデフォルトモデルはEUC-JPの文字コードで作成されています)


先ほどのjulius.confの解説に戻ります。-SR fruit tri grammar というところで、fruitタスクではtriのAM設定を利用し、grammarのLM設定を利用する、ということを宣言します。
\-SR web tri ngram も同様で、webタスクでは、triのAM設定を利用し、ngramのLM設定を利用するということを宣言します。その他の細かい項目については、とりあえず使ってみる場合はこれで良いと思います。


さて、準備が整いました。コマンドプロンプトを立ち上げ、ディクテーションキットのディレクトリまで移動します。そこで、

bin\julius -C julius.jconf

と打ってみると認識ができるはずです。認識結果はこんな感じになります。

[#1 fruit]
sentence1: <s> ぶどう 2 個 を ください </s>
wseq1: 7 0 1 2 3 4 8
phseq1: silB | b u d o: | n i: | k o | o | k u d a s a i | silE
cmscore1: 1.000 1.000 0.885 0.997 0.997 1.000 1.000
score1: -4693.717773
[#2 web]
sentence1:  冒頭 に ここ なさい 。
wseq1: <s> 冒頭:ボートー:冒頭:507 に:ニ:に:63 ここ:ココ:ここ:528 なさい:ナサイ:
なさる:490 。:。:。:8 </s>
phseq1: silB | b o: t o: | n i | k o k o | n a s a i | sp | silE
cmscore1: 0.528 0.159 0.140 0.170 0.146 0.084 1.000
score1: -4792.539551 (AM: -4649.427246  LM: -143.112228)

この例では「ぶどう2個をください」と発話しました。

[#1 fruit]
sentence1: <s> リンゴ を ください </s>
wseq1: 7 0 3 4 8
phseq1: silB | r i N g o | o | k u d a s a i | silE
cmscore1: 1.000 0.624 0.997 0.656 1.000
score1: -5947.270020
[#2 web]
sentence1:  阪神 が 書き まし た 。
wseq1: <s> 阪神:ハンシン:阪神:514 が:ガ:が:63 書き:カキ:書く:264 まし:マシ:ます:
151 た:タ:た:100 。:。:。:8 </s>
phseq1: silB | h a N sh i N | g a | k a k i | m a sh i | t a | sp | silE
cmscore1: 0.618 0.260 0.299 0.340 0.430 0.245 0.622 1.000
score1: -5802.119141 (AM: -5688.392578  LM: -113.726639)

この例では「阪神が勝ちました」と発話しました。

これをどう使うかというと、認識文法はどんな発話であれ、それを認識文法に記載されている範囲の発話に強制的にマッピングしてしまうという弱点があります。2番目の例だと、全く違う「リンゴをください」という認識結果になっているわけですね。

そこで、これらの尤度を使います。score1という項目を見てみると、1番目が文法:-4693.717773, n-gram:-4792.539551 となり文法の方が値が高いのに対し、2番目では文法:-5947.270020, n-gram:-5802.119141 となりn-gramの方が値が高くなっています。これはモデルが、「その文がどれくらい正しいと思っているかのスコア」だと思えばよいです。

つまり、タスクでどうしても認識したいものは文法で書き、文法の方がスコアが高くなればその認識結果を採用すれば、認識文法がうまく働いているときだけ認識文法を利用できるわけですね。


Juliusはサーバとして上げ、そこから認識結果をXMLで取得することも可能です。他のプログラムやロボットなどで利用する場合はこのモードを使い、上記の方法を利用するとよいと思います。

第10章 モジュールモード

にモジュールモードの詳しい用法が記載されています。