ラズベリーパイ3でJuliusを使って音声認識をする方法2017 RasPi 3B + Raspbian Jessieで確認

2018年3月8日

こんにちは!

最近なにかと話題の音声アシスタント技術。

Alexa(Amazon)はどんどん組み込まれ始めていますね!

以前の記事で、ラズパイ3が「日本語」を話せるところまでできていましたが、今回はUSBマイクが手に入ったので、日本語の音声認識をやってみました!

音声認識エンジンは国産の「Julius」を使用します。

用意したモノ

  • Raspberry Pi 3B、Raspbian Jessie
  • マイク(サンワサプライ、USBマイクロホン MM-MCU02BK) 2,780円@Amazon

マイクの確認

サンワサプライのUSBマイクロホン MM-MCU02BKを使用しました。

マイクをUSBポートに接続します。私の環境ではこのような感じで自動的に認識されました。

dmesg
...
[42732.775211] usb 1-1.2: new full-speed USB device number 8 using dwc_otg
[42732.914298] usb 1-1.2: New USB device found, idVendor=0d8c, idProduct=0016
[42732.914311] usb 1-1.2: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[42732.914319] usb 1-1.2: Product: USB Micophone
[42732.914326] usb 1-1.2: Manufacturer: FongLun
[42732.914334] usb 1-1.2: SerialNumber: 201607
[42732.920321] input: FongLun USB Micophone as /devices/platform/soc/3f980000.usb/usb1/1-1/1-1.2/1-1.2:1.2/0003:0D8C:0016.0007/input/input7
[42732.920826] hid-generic 0003:0D8C:0016.0007: input,hidraw2: USB HID v1.11 Device [FongLun USB Micophone] on usb-3f980000.usb-1.2/input2
[42733.000021] usbcore: registered new interface driver snd-usb-audio

念のため、サウンドデバイスとして認識されているか確認します。

cat /proc/asound/modules
 0 snd_bcm2835
 1 snd_usb_audio

USBマイクの優先度を上げる

よく「/etc/modprobe.d/alsa-base.conf」を編集する情報が出てきますが、私の環境では見つからなかったのでGoogle先生に尋ねてみます。

海外の掲示板(How to make Raspberry Pi use an external USB sound card as a default)に「/lib/modprobe.d/aliases.conf」を編集すると良い!という情報があったのでこちらで試します。

sudo vim /lib/modprobe.d/aliases.conf 

options snd-usb-audio index=-2 の数字を 0に変えて保存し、再起動します。
options snd-usb-audio index=0

再起動したら、優先順位が変わっているか確認します。

$ cat /proc/asound/modules
 0 snd_usb_audio
 1 snd_bcm2835

無事に優先順位が変わっていました!

マイクの感度設定

サウンド入力デバイスのカード番号を確認します。

$ arecord -l
**** ハードウェアデバイス CAPTURE のリスト ****
カード 0: Micophone [USB Micophone], デバイス 0: USB Audio [USB Audio]
  サブデバイス: 1/1
  サブデバイス #0: subdevice #0

カード0という事がわかったので、カード番号を指定(-c 0)してマイクの感度(0〜62)を設定します。

$ amixer sset Mic 54 -c 0
Simple mixer control 'Mic',0
  Capabilities: cvolume cvolume-joined cswitch cswitch-joined
  Capture channels: Mono
  Limits: Capture 0 - 62
  Mono: Capture 54 [87%] [18.56dB] [on]

/dev/dspを使えるようにします。

sudo modprobe snd-pcm-oss
sudo sh -c "echo snd-pcm-oss >> /etc/modules"

録音テスト

$ arecord -D plughw:0,0 -f cd test.wav

※Ctrl+cを押すまで録音され続けるので注意してください。

再生してみます。無事に録音されていたらセットアップは完了です。

$ aplay test.wav

 

Juliusのインストール

本体のインストール

githubで最新版を確認します。 https://github.com/julius-speech/julius/releases

記事執筆時点で「v4.4.2.1」が最新でした。
ソースをwgetで入手して、解凍した後にmake&インストールします。

cd ~/src/
wget https://github.com/julius-speech/julius/archive/v4.4.2.1.tar.gz
tar zxvf v4.4.2.1.tar.gz
cd julius-4.4.2.1
./configure
make
sudo make install

Juliusディクテーション実行キットのインストール

サイトから最新版(Ver. 4.4)をDL。

2GBと巨大なため、Raspberry Piの空き領域に注意!
また、git cloneする場合はgit-lfsが必要とのこと。

シンプルに、zipファイル(約400MB)を落としてきます。

wget https://github.com/julius-speech/grammar-kit/archive/v4.3.1.zip
unzip v4.3.1.zip

Julius記述文法音声認識実行キットのインストール

サイトから最新リリースパッケージをDL。

wget https://github.com/julius-speech/grammar-kit/archive/v4.3.1.zip
unzip v4.3.1.zip

認識テスト(自由な言葉の認識)

dictation-kitの中にサンプルファイルがあるので、それらを用いてテストします。

cd dictation-kit-v4.4/
julius -C main.jconf -C am-gmm.jconf -demo

ちょっともっさりした感じがありますが(^^ゞ、うまく認識してくれているようです。

認識テスト(単語の認識)

自然言語の認識は少しレスポンスが遅いので、単語だけを高速に認識できるよう自作の辞書を用意します。

辞書ファイル用の単語リスト作成

juliusのディレクトリに移動して、単語のリスト(word.yomi)を用意します。

vim word.yomi

以下のように、「(単語)(タブ区切り)(読み)」の形で、記述していきます。

ミカン	みかん
オレンジ	おれんじ
リンゴ	りんご
...

辞書ファイルへの変換

辞書ファイルに変換します。内部ではeuc-jpで処理をしている(らしい※)ので、最初にiconvで変換しています。※おまけ参照

iconv -f utf8 -t eucjp word.yomi | yomi2voca.pl > word.dic

設定ファイルの作成

設定ファイルを作成して以下のように記載します。

vim word.jconf

-w word.dic       #単語辞書ファイル。今回作成した「word.dic」を指定
-v model/lang_m/bccwj.60k.htkdic  #N-gram、または文法用の単語辞書ファイルを指定
-h model/phone_m/jnas-tri-3k16-gid.binhmm #使用するHMM定義ファイル
-hlist model/phone_m/logicalTri   #HMMlistファイルを指定する
-n 3        #n個の文仮説数が見つかるまで検索を行う。リファレンスに3〜5とあったので、3にしてみた。
-output 1     #見つかったN-best候補のうち、結果として出力する個数
-input mic      #マイク使用
-input oss      #オープンサウンドシステム使用
-rejectshort 600  #検出された入力が閾値以下なら棄却
-charconv euc-jp utf8 #入出力エンコード指定(内部euc-jp, 出力utf-8)
-lv 1000    #入力の振幅レベルの閾値(0~32767)

単語認識させてみる!

できあがったら実行してみましょう!

julius -C word.jconf

動作の様子はコチラ(音が出ます)

まとめ

JuliusをインストールしたRaspberry Pi 3にUSBマイクを接続して音声認識をすることができ、自作日本語音声アシスタントの道も見えてきました。

次は、他のプログラムからJuliusを呼び出して、認識結果に応じて何かさせてみたいと思います。

 

おまけ。ひっかかったところ

InternalError: codeconv: invalid multibyte sequence in the input

参考サイトに従って実行したところ、見出しのようなエラーががでました。

julius -C grammar-kit-4.3.1/testmic.jconf -charconv EUC-JP UTF-8

こいつは怪しいぜ!と思って文字コードをSJISにしたらいけました。

julius -C grammar-kit-4.3.1/testmic.jconf -charconv SJIS UTF8

文字コードがSJISだったようです。

何を話しても判定結果が同じになる。

孤立単語認識では最も近しいと思われる単語を候補として出力するので、登録した辞書の単語数が少ないと何を話しても同じ結果になってしまいます。単語数を増やしましょう!

文字コード

juliusってShift_JISなんです(^^ゞ

文字コードのせいで色々トラブルが起きたので、nkfを入れておきました。

sudo apt-get install nkf

$ nkf -g main.jconf
Shift_JIS

参考

以下のサイトを大変参考にさせていただきました。ありがとうございました!