ケーブルカーで行こう!
前の記事で「音声認識やってみよう」と勇ましくいったものの、調べれば調べるほどニュービー君には山頂が高すぎることが身に染みてきました。
さながら、全くの初心者がいきなりエベレストに登頂しようとしているようなものでしょう。
でも幸い多くの方々が、いわば「ケーブルカー」とも言える各種ツール類を用意してくれているので、自力登山は今度にして、まずはケーブルカーで山頂の景色を眺めに行きます(もちろん勉強は続けますって。ホントだよ)。
では出発!
来た、見た、勝った
さて、どのケーブルカーに乗るか選ばなければ・・・
もちろん乗り心地がいいものがいいし、乗りやすいものがいい。
値段もあまりかからないほうが嬉しい。
クラウドで音声認識サービスが色々出回っているし、性能面では問題ないのですが、無料では一日50発話しか使えない(もちろん有料にすればいいのですが、今回はお試しだし)とか、面倒なユーザ登録が必要(可能な限り私は自分のデータをネットに出したくない人なので)だったりとか、ちょっと悩んじゃいました。
で、githubでなんかないかなとgithub 音声認識
で検索したところ、Juliusにヒットしたわけです。
おお!日本語大語彙連続音声認識エンジンですと?
コの業界ってどうしても洋物が多いのですが、音声認識って英語と日本語ではだいぶ勝手が違いますよね?
人間だって三歳位までに、耳の機能が英語に特化したり日本語に特化したりとカスタマイズされるそうですし。
【言語別周波数】
人間が聞き分けられる周波数は20Hz~20KHzですが、言語にも周波数範囲があります。
日本語:0.13KHz~1.5KHz
英語:2KHz~12KHz
英語って日本語よりもかなり周波数が高いのです。
日本語と銘打ってるエンジンは重要ですよ、奥さん。
【日本語音声認識】
Juliusが日本語音声認識と謳っているのは、日本語専用の認識方法をとっている訳でなく、
日本語で学習済みということです。
エンジンはそのままに英語で学習させれば、英語音声認識となるはずです(多分)。
いずれは自分で一から学習させたいですけど、また今度ということで。
という訳で、Juliusを使ってみることにしました。ところで、これの読み方って「ユリウス」でいいんですよね?
インストール
先ほどの検索で上位にでてきたサイトにアクセスして、一通り眺めてみると、どうやらJuliusディクテーション実行キットというのがよさそう。
素直にそれをダウンロードして、zipファイルを早速展開。
伝統的にReadMeを読んでみれば、使い方はとっても簡単。
さっそくGMM(混合ガウスモデル)版を試したところ、「おー認識する!」。
でも、ちょっと誤認識が多いかも・・・軽くていいんだけどね(自分では何もしてないのに偉そうに)。
よ~し、続けてDNN(ディープニューラルネットワーク)版もやってみよう。
何々、Python環境が必要なのか。
機械学習といえばPython
Win7を使ってた時は、Pythonも一通り入れてたのですが、この度Win10にアップグレードするにあたり、クリーンインストールを行ったので、ディスクはスッキリきれいになっていたのでした。
色々ライブラリを入れるのも面倒なので、Anacondaで一気に入れちゃいましょう。
バージョンはどうしよう?やっぱり新しいほうがいいよね?よ~し3.5にしちゃうぞ!
Juliusは2.7と言ってるけど、少しぐらいなら3.5に直しちゃうもんね。
わかる人にはわかると思いますが、2.7と3.5の間には深くて大きな溝があるのでした。
初めてのDNN
ここのサイトから、Python3.5のWin-64bit版をダウンロード。
落としてきたexeを実行して、ウィザードにポチポチと答えてインストール。
特に問題もなくインストールが完了したので、run-win-dnn.batを実行。
3つのコマンドが実行され、DOS窓(コマンドプロンプトのことね)が3つ表示されるはずが…
- julius.exeの窓が開き「Stat: vecin_net: waiting connection...」と表示されて待機し、
- 2つ目の窓は一瞬で閉じられ、
- 3つ目の窓はいくらかの出力を行ったあと、retryを繰り返して閉じる。
- 最初の窓は虚しく何かを待ち続けている
となってしまった。
まあ、予想はしていたことですので、冷静にrun-win-dnn.batをエディタで開いて、2つ目のコマンドを確認すると、
start python .\bin\common\dnnclient.py dnnclient.conf
やっぱりPythonですか。
エラーを確認するため、DOS窓を開いて手動実行。
> python .\bin\common\dnnclient.py dnnclient.conf
common\dnnclient.py dnnclient.conf
File ".\bin\common\dnnclient.py", line 46
print "unkown switch"
^
SyntaxError: Missing parentheses in call to 'print'
print文でこけてる…
parenthesesとはカッコのこと。 どうやらprint文の文法が変わったよう。
printなんて楽勝
Python3でprint文は関数に変わって、その結果、
print "abc"
↓
print("abc")
となったみたいです。
dnnclient.pyの中にprint文は2ヶ所しかなかったので、とりあえず関数に変更して再度手動実行。
「Waiting for connections...」と表示されて待機状態となった。よしよし。
バッチ再実行
再度run-win-dnn.batを実行。
無事3つの窓が開き、3つ目の窓に「<<< please speak >>>」と表示される。
そこで「こんにちは」と発話したところ、大量のエラーを表示して窓3が、続いて窓2が消える。
やはりPython2でなければならないのか?
デバッグ
往生際悪く、Python3で動くようにしてみようと決意。
DOS窓を3つ開いてそれぞれでコマンドを手動実行。
案の定Pythonが
TypeError: Can't convert 'bytes' object to str implicitly
とエラーを出している。
buffer += tmpdata
が問題のロジックだが、バイト列を文字列に暗黙変換できませんというエラー。
バイト列は文字コードの配列と思えるのだが、文字列に変換できないのだろうか?
嫌な予測だけど、文字コード関連のエラーか?
調べたら、案の定文字列とバイト列が明確に区別されるようになっていた。
バイト列を文字列(unicode)にするなら、エンコード処理を差し込む必要があるけど、これはちょっと、チョチョイと直すという訳にはいかないので、あきらめてPython2を入れなおしましょう(問題個所が分かれば直すこと自体は簡単だけど、問題個所が検索だけでは特定できず、ロジックを追う必要があるので)。
Python2環境構築
Python3をアンインストールしてPython2を入れることも考えたのですが、Anacondaは別バージョンの仮想環境を作れたはずなので、せっかくだからトライ。
C:\>conda create -n py2 python=2.7
py2の名前で仮想環境ができたか確認。
C:\>conda env list
py2 C:\Users\****\Anaconda3\envs\py2
root * C:\Users\****\Anaconda3
仮想環境py2に切り替える。
C:\>activate py2
(py2) C:\>python --version
Python 2.7.12 :: Continuum Analytics, Inc.
仮想環境から抜ける
(py2) C:\>deactivate
C:\>
Yeah!できたぜ。
念のため、仮想環境の削除のやり方も書いておきましょう(もちらん実行はしてないので、未検証)。
> conda remove -n py2 --all
おぉっと忘れてた。numpyも入れなきゃいけなかったんだ。
C:\>activate py2
(py2) C:\>pip install numpy
Collecting numpy
Using cached numpy-1.11.1-cp27-none-win_amd64.whl
Installing collected packages: numpy
Successfully installed numpy-1.11.1
本当は最初に仮想環境を作るときに、numpyも入れとけばよかったのだけど・・・
C:\>conda create -n py2 python=2.7 numpy
改めてJulius-DNNを実行
起動バッチに仮想環境への切り替えを仕込み、
activate py2 ←これを挿入
start .\bin\windows\julius.exe -C main.jconf -C am-dnn.jconf -demo -charconv utf-8 sjis
timeout 10
start python .\bin\common\dnnclient.py dnnclient.conf
timeout 2
start .\bin\windows\adintool -in mic -out vecnet -server 127.0.0.1 -paramtype FBANK_D_A_Z -veclen 120 -htkconf model\dnn\config.lmfb.40ch.jnas -port 5532 -cvn -cmnload model\dnn\norm.jnas
で、起動バッチを実行。
ムム。何も起きない?
どうやらactivate py2
で環境を変えると、その時点でバッチ実行が停止してしまうみたい。
仕方ないので、DOS窓を開いてpy2に切り替えた後、そこから起動バッチを実行。この辺りは、あとでもっとうまい手を考えよう。
恐る恐る、小声(別に小声だからうまくいくわけではないのですが)で「こんにちは」と発話したら、しばらくして「こんにちは」と表示されました。
Oh yeah!大成功!!
色々試してみたけれど、確かにGMM版より認識率が高いみたい。
但し、それ相応の処理時間がかかるのが否めないのは仕方ないか(ちょっと一拍置くくらいだけど)。
とりあえず、ここまででJuliusの動作確認は完了。
以上、ten@蓼科情報でした。