新しく説明を書きました(メモ的なもの・・・)
【Macでpython3でGoogle Cloud Speech gRPC API を使ってストリーム音声認識をする!】
http://qiita.com/sayonari/items/4656212b4d34714ab98f
やりたいこと
2016年7月20日に公開された,Google Cloud Speech APIを使ってみたい!
使ってみた結果の動画です↓
Qiitaに貼り付けるようの動画.googleの音声認識(ストリーミング版)のテスト●GoogleCloudSpeechAPI streaming demo (Japanese) https://t.co/K6yfWE6M5M
— さよなりω/西村良太博士(工学) (@sayonari) 2016年9月23日
実際に使ってみると,以下の点で優れていると感じました.
- 日本語の音声認識が良くできる
- 日本語語彙がとても多い(競合他社サービスより)
- マイクの違いや環境雑音なんかにも強い感じ
Google Cloud Speech APIには,以下の2つのモードがあります.
- non-streaming mode
- streaming mode
streamingの方は,音声入力が開始されると同時に,その音声を順番にgoogleに送信し,喋りながら音声が認識されていくというものです.
streamingでない場合(発話が終了したあと,音声を送信して音声認識するもの)は,音声認識終了までに以下の時間がかかります.
- 発話開始-終了 → googleに接続 → 音声送信 → 認識処理 → 認識結果受信
これでは,発話終了から認識結果が得られるまでに,時間がかかり,音声対話などでは使い物になりません.
streamingの場合(入力された音声を逐次googleに送信するもの)は,以下のような時間経過を辿ります.
- 発話開始 ----------------------------- 発話終了
- googleに接続 → 逐次音声送信&認識処理 → 認識結果受信
ですから,うまく行けば,発話終了とほぼ同時に,認識結果を得られるわけです.
これは絶対に使いたい!!!
ということで,以下にそのためのプログラムを載せておきます.
stream認識の問題点
Google Cloud Speech APIで音声認識する場合には,音声の始まりの検出も自動で行ってくれるので,基本的には,googleに繋いで,音声を逐次送信していればよいです.音声区間が始まると,そこから認識結果が逐次送信され,音声が終了すると,認識処理もそこで終了し,接続が切れます(接続を切らずに連続認識するモードもある)
しかし!!!!!!
Google Cloud Speech APIのstreamモードには連続接続時間に制限があり,1分間しか連続して接続できません.
これは,音声認識を開始して,58秒たった後で5秒間の発話をすると,最後の3秒間分の音声は認識できないということになります.
また,連続音声認識モードにしても,1分で切れてしまうため,再接続を行っている間の時間分は,音声認識ができない事になってしまいます.
これは大問題なので,以下のように対処することにしました.
- 簡易的な音声開始検出を実装し,音声が開始するまではPC側で監視
- 音声開始を検出してから,googleに接続開始
- 接続中の音声もバッファしておき,googleに繋がったらバッファから順に送信
こうすることで,接続制限1分問題+接続時の音声ロスト問題を解決してあります.
参考文献
・ 本家本元
https://cloud.google.com/speech/
・ サンプルプログラム
https://github.com/GoogleCloudPlatform/python-docs-samples/tree/master/speech/grpc
・ Google Speech APIを使えるようになるまで(API利用登録などの詳細)
http://qiita.com/lethe2211/items/7c9b1b82c7eda40dafa9
・Google Speech API をストリームで利用してみた(情報少なすぎ!)
http://qiita.com/voluntas/items/fb9fc621947272928df4
実行結果を先に見せちゃう
Ryota-no-MacBook-Pro:forGithub nishimura$ python GoogleSpeechAPI_stream.py
Start Rec!
2016-09-23 15:08:55.784 Python[1667:116715] 15:08:55.784 WARNING: 140: This application, or a library it uses, is using the deprecated Carbon Component Manager for hosting Audio Units. Support for this will be removed in a future release. Also, this makes the host incompatible with version 3 audio units. Please transition to the API's in AudioComponent.h.
rms 652 decibel 56.2849525
connecting ....
success to connect.
conf:0.0 stab:0.00999999977648
trans:足
conf:0.0 stab:0.00999999977648
trans:明日
conf:0.0 stab:0.00999999977648
trans:明日の
conf:0.0 stab:0.00999999977648
trans:明日のよ
conf:0.0 stab:0.00999999977648
trans:明日の横
conf:0.0 stab:0.00999999977648
trans:明日の
conf:0.0 stab:0.00999999977648
trans:明日の横浜
conf:0.0 stab:0.00999999977648
trans:明日の横浜の
conf:0.0 stab:0.00999999977648
trans:明日の横浜のて
conf:0.0 stab:0.00999999977648
trans:明日の横浜の
conf:0.0 stab:0.00999999977648
trans:明日の横浜の天気
conf:0.0 stab:0.00999999977648
trans:明日の横浜の天気を
conf:0.0 stab:0.00999999977648
trans:明日の横浜の天気を押し
conf:0.0 stab:0.00999999977648
trans:明日の横浜の天気を教え
conf:0.0 stab:0.00999999977648
trans:明日の横浜の天気を教えて
conf:0.0 stab:0.00999999977648
trans:明日の横浜の天気を教えてく
conf:0.0 stab:0.00999999977648
trans:明日の横浜の天気を教えてくだ
conf:0.0 stab:0.00999999977648
trans:明日の横浜の天気を教えて
conf:0.0 stab:0.00999999977648
trans:明日の横浜の天気を教えてください
is_final: True
conf:1.0 stab:0.0
trans:明日の横浜の天気を教えてください
Start Rec!の直後に,WARNINGが出てますが,これはElCapitanでportaudioを使うと出るWARNINGなようです.portaudioのバージョンアップで解決されるのを待つしかないようです.そのままでも動くので,そのままにしてあります.
さて,音声認識の動作ですが,1フレーム(ここでは100ms)ごとにデータを送信していますが,そのデータ送信ごとに,googleから認識の途中結果が返ってきます.実際に動かすと,感動する挙動です.
環境
- MacBook Pro (Retina, 13-inch, Late 2013)
- OS X El Capitan バージョン 10.11.6
準備
Google Cloud APIを使うためには,GoogleにAPI利用の登録したり,クレジットカードを登録したり,API利用キーをダウンロードしたり,色々しないといけません.
API利用登録などの詳細は,以下のページを見ましょう.
Google Speech APIを使えるようになるまで
基本的には,以下のREADME.md通りに進めればOKです.
https://github.com/GoogleCloudPlatform/python-docs-samples/tree/master/speech/grpc
必要なものは,pipでインストールしてみよう
pip install grpc-google-cloud-speech-v1beta1
その他,portaudioなどもインストールしてください.
Mac OS X El Capitan モジュールインポートエラーが出たら
ライブラリのパスを見直してみて!
.bash_profile に,以下を追記したら治るかも.
export PYTHONPATH="/Library/Python/2.7/site-packages:$PYTHONPATH"
プログラム
プログラムの特徴
上にも書きましたが,以下の特徴があります.
- 簡易的な音声開始検出を実装し,音声が開始するまではPC側で監視
- 音声開始を検出してから,googleに接続開始
- 接続中の音声もバッファしておき,googleに繋がったらバッファから順に送信
ソース
以下にあります.
https://github.com/sayonari/GoogleSpeechAPI_stream
設定解説
# 各種設定 #########################
flag_recogRepeat = True # 音声認識を繰り返し行う場合 Trueにする
EXIT_WORD = u"(音声認識を終了します|ちちんぷいぷい|さようなら)" # 音声認識を終了させる合言葉
LANG_CODE = 'ja-JP' # a BCP-47 language tag
RATE = 16000 # サンプリングレート
CHANNELS = 1 # 録音チャンネル数
RECORD_SEC = 5 # 録音時間(sec)
DEV_INDEX = 0 # デバイスを指定
FRAME_SEC = 0.1 # 1フレームの時間(秒) (0.1sec = 100ms)
CHUNK = int(RATE * FRAME_SEC) # 1フレーム内のサンプルデータ数
SLEEP_SEC = FRAME_SEC / 4 # メインループ内でのスリープタイム(秒)
BUF_SIZE = CHUNK * 2 # 音声のバッファ・サイズ(byte)
DECIBEL_THRESHOLD = 50 # 録音開始のための閾値(dB)
START_FRAME_LEN = 4 # 録音開始のために,何フレーム連続で閾値を超えたらいいか
START_BUF_LEN = 5 # 録音データに加える,閾値を超える前のフレーム数
RECORD_SEC = 5 # 録音時間(sec)
を消すのを忘れてました.これは効力がありません.
設定をいじるとすれば,最初の2つと,最後の3つです.
flag_recogRepeat = True # 音声認識を繰り返し行う場合 Trueにする
EXIT_WORD = u"(音声認識を終了します|ちちんぷいぷい|さようなら)" # 音声認識を終了させる合言葉
DECIBEL_THRESHOLD = 50 # 録音開始のための閾値(dB)
START_FRAME_LEN = 4 # 録音開始のために,何フレーム連続で閾値を超えたらいいか
START_BUF_LEN = 5 # 録音データに加える,閾値を超える前のフレーム数
googleに送信された音声は,wavファイルに吐き出されます.
ただ,連続して音声認識した場合には,その全てがつながって1つのwaveファイルとして
出力されます.
分けたい人は,ソースをいじってください.