スマートスピーカーを実装する
この記事はおうちハックアドベントカレンダー2017 22日目の記事です
TL;DR
- Voice Kitをベースにオリジナルのスマートスピーカーを作ったよ
- snowboy(オリジナルの検知ワードを設定可能にするライブラリ)とdialogflowのv2のライブラリをVoice Kitから使えるようにしたよ
- dialogflow経由で外部のAPI叩けるし、Raspberry Pi内部に仕込んだスクリプトも叩けるからTPO分けて使えるよ
- 『ダンボー』のサンプルボイス増やして誤検知率を下げるのに協力してくれると嬉しいな。

【国内代理店版】Google AIY Voice Kit & Raspberry Pi 3 入門セット - 日本語「組み立てガイド」付属
- 出版社/メーカー: ケイエスワイ
- メディア: エレクトロニクス
- この商品を含むブログを見る
デモと簡単な解説
senyoltwです。
最近のおすすめのネット小説は「お前が神を殺したいなら、とあなたは言った」
頭脳戦好きな人は、最高にしゅきなシチュで脳汁ドバドバ出るのでおすすめ。
それはそうと、本題。まずは今回の成果物とその簡単な解説です。
ということで、動画のデモのようなオリジナルのスマートスピーカーを自作してみました。
オリジナルの検知ワードから音声をクラウドに送って、設定した条件の通りに命令を処理してくれて返してくれます。音声の内容に従って正規表現的なパターンマッチをしているのではなく、NLU(自然言語理解)を通しているので、ファジーなおしゃべりでも意図した命令が実行できます。
具体的な実装は、検知(snowboy)→音声をテキスト化(Cloud Speech API )→NLU(Dialogflow)→コード実行( い ろ いろ )→音声化(Open JTalk)でやっています。
作ったプログラムはgithubに公開しています。
DANBOARD(ダンボー)という名前。もともとダンボールのスマートスピーカーキットだし。
DANBOARDを動かすには、事前にVoice Kitが動くようにしてあることが必須です。音声取得などの低レベルAPIはそちらを流用しています。
このブログの最後に簡単な構築手順を記載してるので参考にしてください。
特長として、自分で書いたスクリプトを実行できる機能があるので、家電を操作したり、お天気をネットから取得したり、部屋の温度計を読んだりいろいろできます。
色々なライブラリやスクリプトを加えて、君だけのオリジナルスマートスピーカーを作り上げよう! 最強の組み合わせを見つけて、ライバルに差を付けろ!
スマートスピーカーの仕組みとDANBOARDの実装内容
スマートスピーカー、売ってる製品、どんな実装してるかわからないのですけど、だいたいこんなんじゃないかなーと思ってます。
検知ワード待機(OK Googleとか) ↓検知! 音声をテキスト化(Speech to TextやCloud Speech API ) ↓テキスト化! 言語の曖昧さをNLU(自然言語理解)で分類 ↓NLUで分類 条件に応じてコード実行 ↓コード実行 結果をテキストで回答 ↓回答した テキストを音声化
それぞれ、一旦スマートスピーカーに返しているのではホップ数がガンガン増えて遅くなるので、市場に出ているスマートスピーカーは音声データをクラウドに送って、音声データが返ってきてそう。乗っているのは検知ワード判断とその後の音声をクラウドに送る機能だけというのがだいたいのスマートスピーカーの実装なのではないのでしょうか。
それはそれとして、各機能(検知、テキスト化、NLU、処理、音声化)を実装すればオリジナルのスマートスピーカーが自作できるってことだな??と思いたち、ちょうどGoogle AIY Voice Kitが届いたのでそれにモジュールとして機能を追加してみることにしました。
DANBOARDの使い方と各機能の実装についての解説
使用方法は簡単で、Google AIY Voice Kit が動く環境で、次のコマンドを実行するだけ。
# git clone https://github.com/senyoltw/DANBOARD # cd DANBOARD # sh install.sh
install.shを実行することで必要なライブラリやソフトウェアが自動でインストールされ、 その後、「~/AIY-projects-python」(もしくは、~/voice-recognizer-raspi)に各機能を実装したライブラリがコピーされます。 コピーされるのは、
- サンプルとしての実装プログラム(~~_demo.pyという名前)
- スマートスピーカー実装に必要な各機能を追加したライブラリ群(mod以下)
- スマートスピーカーから実行できるサンプルのローカルスクリプト(skill以下)
となります。
次に、各機能の実装について説明。
検知
snowboyという検知ワード生成サービスを使用しています。
Githubにも各言語での検知ワード認識の実装があるのでPython3のものをいい感じに移植してみました。テキスト化
Google Speechを使用しました。これはVoice Kitにデフォルトで実装されていたので、特に何もしていません。NLU(自然言語理解)
Dialogflowを使用しました。これ、2つ実装していて、
1つはテキストを入力したら、その解析を返してくれるもの。
もう一つは音声を直接送ったらその解析を返してくれるもの。の2つです。
後者のほうがサーバとの通信が少なくなるのでおすすめなのですが、まだAPIがベータ版なせいか、空間にノイズ(BGMをスピーカーで流していたり)が入っているといつまでたっても処理が終わらずにタイムアウトしてしまいます。なので、今のところは音声をテキスト化する部分と解析は分けたほうが良さそう。コード実行
Dialogflowで処理した時の分類名と同じPythonスクリプトがローカルのskillディレクトリにあったら実行するような処理を実装しました。 つまり、Dialogflowでエアコンつけてという言葉に反応するIntentを作成し、そのIntentと同じ名前でエアコンをONにするスクリプトをskillディレクトリに置いておけば、それだけで家電に命令ができるスマートスピーカーが作れます。
もちろん、Dialogflow自体でwebhookを使って外部処理を任せたほうがスマートだったりします。お好きな方を選んでください。ローカルで実行するのはあまり外部に処理を任せたくないもの(赤外線のコマンドとか)を想定しています。テキストを音声化
Open JTalkを使えるようにしました。 ただ、デフォルトの音声でIPアドレスを喋らせるとめっちゃ怖い音声になるバグがあって、だれか助けてください。
う、ううーん、自分ではどうしようもないとこでバグ踏んで怖いことになった…… pic.twitter.com/fjkOncI5DP
— せにょ (@senyoltw) 2017年12月20日
プログラムの使用方法。
だいたいは~~~_demo.pyのソースコードをみてもらえればわかると思います。
各デモについて簡単に説明します。
snowboy_demo.py
snowboyとGoogle Speechの組み合わせのデモ。引数に音響モデル(ダンボーとかアレクサとか)が必要です。umdlやpmdlというのがそれなので好きなものを指定してください。dialogflow_audio_demo.py
snowboyとdialogflowに直接音声を送る実装の組み合わせです。引数に音響モデルが必要です。それなりにレスポンスは早いですが、まだノイズに弱いので注意dialogflow_text_demo.py snowboyとGoogle Speechとdialogflow(text処理)の組み合わせです。ちょっと反応は遅いですが安定性は強い。
danboard.py
自分が運用しているスマートスピーカーのプログラムです。内部で音響モデルを指定しているので、python3 src/danboard.py
で動く。
所感
作って思ったこととしては、ウエイクワードの誤検知率が高いってことです。
まあ、録音した音声が自分の音声のみなのでそれはしょうがないのかな。もうちょっと複数の人間が音声を登録してくれたら誤検知率は下がると思います。なので、githubのアカウント持ってる各位につきましては、ぜひあなたの音声を音響モデルに登録してください。
あしたはsho7650さんです!
おまけ
DANBOARDインストール手順
自分の備忘録も兼ねてインストール手順を書いておきます。
これに沿ってインストールできなかったとしても責任はもちません。
エラー内容ググってがんばってください。
下準備
スクリーンショットをエクセルに貼り付けるよりは、コマンド一覧をテキストファイルに貼り付けたほうが有意義だと思うのでできるだけコマンドでやっていきます。
raspbian-stretch-liteをダウンロードして焼く。
/boot以下にsshというファイルを作って、有線LAN接続して起動すればsshでログインできるようになります。
$ ssh pi@raspberrypi.local (パスワードはraspberry)
現状だとセキュリティに対して弱々しいので基本設定変更
# sudo raspi-config 1 Change User Passwordでパスワード変更 2 Network OptionsでWi-Fiのパスワードを設定 4 Localisation OptionsでLocaleをjaのutf-8にTimezoneをAsia/Tokyoに 8 Updateでアップデート # sudo apt-get update # sudo apt-get upgrade # sudo reboot
これで下準備は終わりです。LANケーブル引っこ抜いてUSB電源接続だけで起動できます。
(ただし、パッケージのインストール等あるのでもうしばらく有線でインストール作業を進めたほうが楽です)
参考 raspi-config - Raspberry Pi公式ドキュメントを日本語訳
Voice kit APIインストール
基本的にここをみてインストールすればOKです。
aiyprojects-raspbian/HACKING.md at aiyprojects · google/aiyprojects-raspbian · GitHub
注意点として、事前にWEBからgoogle-cloud-platformの認証ファイルをダウンロードしておく必要があります。
ここでは必要ないですが、クラウドスピーチのアクティベーションもしておきましょ。
それらのファイルは次のディレクトリにおいてください。
/home/pi/assistant.json (google-cloud-platformの認証) /home/pi/cloud_speech.json (Cloud Speech APIが認証されたProjectの情報)
動きましたか?
下のコマンドを実行して英語のgoogle assistantが起動すれば問題ないです。
「OK Google. What time is it?」と聞けばお返事が返ってきます。
# cd ~/AIY-projects-python # source env/bin/activate # python3 src/assistant_library_demo.py googleアシスタントに英語で話かけられるか確認 # python3 src/cloudspeech_demo.py ボタンを押して、英語が認識できるか確認
DANBOARDインストール
本題。
でも、その前にDialogflowの記事をいくつか読んで使ってみてください。
わからずに使い始めると死ねる。
あと、cloudspeechと同じGCPのプロジェクトIDでDialogflowを有効化してください。Dialogflowを使う関数はcloud_speech.jsonからGoogleの認証情報を取得しています。
# deactivate (もし、google assistantの環境の中にいるのであれば抜けておく) # cd # git clone https://github.com/senyoltw/DANBOARD # cd DANBOARD # sh install.sh
簡単ですね。途中でこのソフトウェアインストールするか?とかOpen JTalkをインストールしますかと聞かれるのでそれだけy/nで返事してくだい。yで基本問題ありません。
インストールが終わったら、AIY-projects-pythonに移動して、ダンボープログラムを起動。
「ダンボー」って話かければ反応します。
cd ~/AIY-projects-python source env/bin/activate python3 src/danboard.py
カスタマイズ
もし、音声の命令で何か特定のコマンドを実行したいときはdialogflowに次のようにintentを作ってみてください。
intent nameがifttt_remo_onになっているので、~/AIY-projects-python/sec/skill/ifttt_remo_on.py
が動いてくれます。
このように、intent nameでskillディレクトリ以下を調べて、同名のPythonスクリプトがあるならば、実行してくれるようにしています。
ifttt_remo_on.pyは編集して自分のIFTTTの設定に書き換えましょう。
https://github.com/senyoltw/DANBOARD/blob/master/skill/ifttt_remo_on.py
サービス化
もし、問題なく動くようであればサービス化してください
# cd ~/AIY-projects-python # cp -ip src/danboard.py src/main.py # sudo systemctl enable voice-recognizer.service
それではよきおうちハックライフを!