Slide 1

Slide 1 text

Androidで音声認識を使いこなす DroidKaigi 2017 2017/03/10 14:20 - 14:50 KAKKA

Slide 2

Slide 2 text

対象者 ○ Androidアプリ開発者 ○ 音声認識に興味がある方

Slide 3

Slide 3 text

目次 AndroidのSpeech Recognizerについての詳細 ● Androidで音声認識といえばこれという王道パターンを詳しく解説 ● SpeechRecognizerのいろいろな使い方を解説 Androidで連続音声認識を使ってOK Googleみたいなものを作る方法 ● 連続音声認識について解説 ● AndroidでどうやってGoogle home, Alexa, Siriのような実装するか

Slide 4

Slide 4 text

自己紹介

Slide 5

Slide 5 text

KAKKA Company: Community: Twitter: Qiita: Github: Drivemode, Inc. ScrumMastersNight! KAKKA_Blog KAKKA KAKKA

Slide 6

Slide 6 text

音声認識とは 人間の声を機械に認識させること こんにちは こんにちは!

Slide 7

Slide 7 text

音声認識使ってるアプリ

Slide 8

Slide 8 text

Drivemode 車運転者向けNo-Look UI 音声認識 目的地や連絡先の音声検索 LINEなどのメッセージに声だけ で返信 “Yo Drivemode”の声でボイス コマンド認識開始(英語)

Slide 9

Slide 9 text

Androidで音声認識 といえば?

Slide 10

Slide 10 text

android.speech.SpeechRecognizer

Slide 11

Slide 11 text

コンテキスト渡してインスタンス作成

Slide 12

Slide 12 text

リスナー登録して

Slide 13

Slide 13 text

成功した場合、結果はここに返ってきます

Slide 14

Slide 14 text

エラーだった場合はこちら

Slide 15

Slide 15 text

このIntentにいろんなオプション付与出来ます

Slide 16

Slide 16 text

音声認識スタート!

Slide 17

Slide 17 text

SpeechRecognizer List recResult = results.getStringArrayList( SpeechRecognizer.RESULTS_RECOGNITION ) 認識結果はlistで返ってくる 信頼度が高い順

Slide 18

Slide 18 text

SpeechRecognizer float[] confidenceScores = results.getFloatArray( SpeechRecognizer.CONFIDENCE_SCORES ); 認識結果の信頼度も取得可能

Slide 19

Slide 19 text

Error? ERROR_NETWORK_TIMEOUT(1) ERROR_NETWORK(2) ERROR_AUDIO(3) ERROR_SERVER(4) ERROR_CLIENT(5) ERROR_SPEECH_TIMEOUT(6) ERROR_NO_MATCH(7) ERROR_RECOGNIZER_BUSY(8) ERROR_INSUFFICIENT_PERMISSIONS(9) エラーの種類

Slide 20

Slide 20 text

Error? ERROR_NETWORK_TIMEOUT(1) ネットワークタイムアウトエラー ERROR_AUDIO(3) オーディオレコーディングエラー ERROR_CLIENT(5) 何かしらのクライアント側エラー ERROR_INSUFFICIENT_PERMISSIONS(9) パーミッションエラー ほとんどみかけない

Slide 21

Slide 21 text

Error? ERROR_NETWORK(2) ネットワークエラー。電波悪かったりとか ERROR_SERVER(4) 何かしらのサーバーエラー。モデルなしでオフラインで認識させようと したときにも。 ERROR_RECOGNIZER_BUSY(8) インスタンス複数生成してるなど設計に問題あり たまに見かける

Slide 22

Slide 22 text

Error? ERROR_SPEECH_TIMEOUT(6) 認識スタートしてから無言で終わったとき ERROR_NO_MATCH(7) 意味不明な言葉を喋ったとき 一番多い

Slide 23

Slide 23 text

Error? ERROR_SPEECH_TIMEOUT(6) 認識スタートしてから無言で終わったとき ERROR_NO_MATCH(7) 意味不明な言葉を喋ったとき 一番多いが 実環境に様々な雑音があるため、 SPEECH_TIMEOUTだからといってユーザーが何 も喋っていないと判断してはいけない

Slide 24

Slide 24 text

SpeechRecognizer他のやり方

Slide 25

Slide 25 text

StartActivityForResult()でも

Slide 26

Slide 26 text

StartActivityForResult()でも この場合このExtraは必須

Slide 27

Slide 27 text

StartActivityForResult()でも LANGUAGE_MODEL_WEB_SEARCH でgoogle検索結果画面に

Slide 28

Slide 28 text

StartActivityForResult()でも おなじみのstartActivityで認識開始

Slide 29

Slide 29 text

Googleアプリ

Slide 30

Slide 30 text

Googleアプリ依存 認識処理の実態はGoogleア プリ MIUIに注意 Googleアプリのアップデート によって挙動が変わることが ある com.google.android.googlequicksearchbox/ com.google.android.voicesearch.serviceapi.GoogleRecognitionService

Slide 31

Slide 31 text

Googleアプリ依存 例: Googleアプリが5から6になったとき

Slide 32

Slide 32 text

Googleアプリ依存 例: Googleアプリが5から6になったとき 音声認識開始から終了までの時間がかなり長く なった。 →現在はもとに戻ってる

Slide 33

Slide 33 text

Googleアプリ依存 例: Googleアプリが5から6になったとき start! complete! こんにちは

Slide 34

Slide 34 text

Googleアプリ依存 例: Googleアプリが5から6になったとき start! complete! こんにちは こんにちは

Slide 35

Slide 35 text

Googleアプリ依存 例: Googleアプリが5から6になったとき start! complete! こんにちは こんにちは こんにちは

Slide 36

Slide 36 text

Googleアプリ依存 例: Googleアプリが5から6になったとき start! complete! こんにちは こんにちは こんにちは こんにちは

Slide 37

Slide 37 text

Googleアプリ依存 例: Googleアプリが5から6になったとき start! complete! こんにちは こんにちは こんにちは こんにちは こんにちは

Slide 38

Slide 38 text

Googleアプリ依存 例: Googleアプリが5から6になったとき start! complete! こんにちは こんにちは こんにちは こんにちは こんにちは (もういいや)

Slide 39

Slide 39 text

Googleアプリ依存 例: Googleアプリが5から6になったとき start! complete! こんにちは こんにちは こんにちは こんにちは こんにちは (もういいや) こんにちはこんにちはこんにちはこんにちはこんにちは

Slide 40

Slide 40 text

Googleアプリ依存 例: Googleアプリが5から6になったとき partialResultを使わないと使いものにならない

Slide 41

Slide 41 text

Googleアプリ依存 partialResults ? start! complete! こんにちは イェエエイ こんにちは ジャスティス onPartialResult こんにちは イェ エエイ onPartialResult こんにちは イェ エエイ ジャス ティス onPartialResult onResult

Slide 42

Slide 42 text

Googleアプリ依存 例: 現在の最新版Googleアプリ デバイスがオフラインのとき、

Slide 43

Slide 43 text

Googleアプリ依存 例: 現在の最新版Googleアプリ デバイスがオフラインなどのとき、onError返って 来ない!!

Slide 44

Slide 44 text

Googleアプリ依存 例: 現在の最新版Googleアプリ start! 以降死ぬまで続く... ・・・ 10分 20分 30分 40分 50分 60分

Slide 45

Slide 45 text

Googleアプリ依存 例: 現在の最新版Googleアプリ start! 以降死ぬまで続く... ・・・ 10分 20分 30分 40分 50分 60分 Timeoutを設定しよう!

Slide 46

Slide 46 text

SpeechRecognizerの応用

Slide 47

Slide 47 text

オフライン音声認識

Slide 48

Slide 48 text

オフライン音声認識 Android Speech Recognizerは通常オンラインでgoogleのサーバー と通信して音声認識を行う Google 音声raw 認識結果

Slide 49

Slide 49 text

オフライン音声認識 実はオフラインでの音声認識も同様に対応されている デフォルトの設定 オンラインで認識するか、オフラインで認識するかが自動的に切り替えら れて認識される

Slide 50

Slide 50 text

オフライン音声認識 実はオフラインでの音声認識も同様に対応されている デフォルトの設定 オンラインで認識するか、オフラインで認識するかが自動的に切り替えら れて認識される インターネット繋がってるけど、速度めっちゃ遅い ↓ 認識精度めっちゃ悪い

Slide 51

Slide 51 text

オフライン音声認識 強制的にオフラインで認識させよう intent.putExtra( RecognizerIntent.EXTRA_PREFER_OFFLINE, true ) API level 23より

Slide 52

Slide 52 text

オフライン音声認識 オフラインで音声認識するためには当然デバイスにモデルデータが必要 Google 音声raw 認識結果 言語モデル 音響モデル 音声raw 認識結果

Slide 53

Slide 53 text

オフライン音声認識 Marshmallow 設定→言語と入力→Google音声入力→オフラインの音声認識 Nougat 設定→Google→検索→音声→オフラインの音声認識 音響・言語モデルのダウンロード可能 言語モデル 音響モデル

Slide 54

Slide 54 text

オフライン音声認識 このモデルなしで強制的にオフライン音声認識させた場合 かならず onError()でERROR_SERVERが返ってきて認識に失敗 コールバック何も返ってこない 言語モデル 音響モデル 最新のGoogleアプリ

Slide 55

Slide 55 text

多言語音声認識

Slide 56

Slide 56 text

多言語音声認識 intentにputExtraするだけ Language String is defined by BCP 47.

Slide 57

Slide 57 text

多言語音声認識 英語を設定して日本語を喋ると・・・ Drivemodeは超安全、超便利! Drivemod is really safe and really useful! Driving mode Auto and then to Bandy ドラえもんエイジリアリゼーションリアルユース4 日本語を設定して英語を喋ると・・・

Slide 58

Slide 58 text

Listen時間の延長

Slide 59

Slide 59 text

Listen時間は長くできる? EXTRA_SPEECH_INPUT_COMPLETE_SILENCE_LENGTH_MILLIS EXTRA_SPEECH_INPUT_MINIMUM_LENGTH_MILLIS EXTRA_SPEECH_INPUT_POSSIBLY_COMPLETE_SILENCE_LENGTH_MILLIS 今は動いていない!!

Slide 60

Slide 60 text

ボイスコマンド音声認識

Slide 61

Slide 61 text

ボイスコマンドとして利用 メッセージ届きました。読 み上げる? listen! 「DroidKaigiってなんな の?」from 槇原敬之 音声認識

Slide 62

Slide 62 text

ボイスコマンドとして利用 listen! 音声認識 辞書 listen message play

Slide 63

Slide 63 text

ボイスコマンドとして利用 雑音 result = [ risk, list, less, less than, list of, risk of, list for, is ] listen 雑音環境下では短い1つの単語は認識しづらい

Slide 64

Slide 64 text

ボイスコマンドとして利用 listen listen to message reply reply to message send send message navigation start navigation 不自然ではない程度に認識させる文章を長くする。 結局人間が解釈しやすいレベルであればOK

Slide 65

Slide 65 text

連続音声認識

Slide 66

Slide 66 text

SpeechRecognizer Android Speech Recognizerは認識スタートと認識完了が短いライフ サイクル イェエエエエエエエ イ!!!!! 認識スタート マイクON 認識完了 マイクOFF 認識中

Slide 67

Slide 67 text

SpeechRecognizer 認識スタート マイクON 認識完了 マイクOFF 認識中 ユーザーがボタンをタップするなど、なにかしらのイベントによりスタートする

Slide 68

Slide 68 text

連続音声認識 認識スタート マイクON listening...

Slide 69

Slide 69 text

連続音声認識 listening...

Slide 70

Slide 70 text

連続音声認識 やっほー やっほー トイレ行きたいなー トイレ行きたい な― listening...

Slide 71

Slide 71 text

連続音声認識 10分後... すっきりしたよー! すっきりしたよー listening...

Slide 72

Slide 72 text

連続音声認識 マイクOFF listening...

Slide 73

Slide 73 text

連続音声認識が日常に OK, Google Hey Siri Hey Alexa Hey Google

Slide 74

Slide 74 text

連続音声認識と通常の音声認識 “OK, Google”を拾う 連続音声認識 “OK, Google”を拾う 連続音声認識 通常の音声認識 OK, Google Play music OK, play music with Spotify

Slide 75

Slide 75 text

Drivemodeの連続音声認識 “Yo Drivemode”を拾う 連続音声認識 SpeechRecognizer startListening() Yo, Drivemode Navigate to Gas Station Starting navigation... “Yo Drivemode”を拾う 連続音声認識 認識結果から諸々の処理

Slide 76

Slide 76 text

Drivemodeの連続音声認識 “Yo Drivemode”を拾う 連続音声認識 “Yo Drivemode”を拾う 連続音声認識 How to implement?

Slide 77

Slide 77 text

Pocketsphinx

Slide 78

Slide 78 text

What is Pocketsphinx? オフラインで認識可能 音響モデル・言語モデルは限られている(日本語はない) キーワード定義が可能 実環境で利用可能 http://cmusphinx.sourceforge.net/

Slide 79

Slide 79 text

What is Pocketsphinx? オフラインで認識可能 音響モデル・言語モデルは限られている(日本語はない) キーワード定義が可能 実環境で利用可能 http://cmusphinx.sourceforge.net/ 連続音声認識とオンライン認識処理は相性が悪い

Slide 80

Slide 80 text

What is Pocketsphinx? オフラインで認識可能 音響モデル・言語モデルは限られている(日本語はない) キーワード定義が可能 実環境で利用可能 http://cmusphinx.sourceforge.net/ 日本語を使いたい場合は自分でモデルを作成する必要がある 英語でもwordと読み方を定義することは可能

Slide 81

Slide 81 text

What is Pocketsphinx? オフラインで認識可能 音響モデル・言語モデルは限られている(日本語はない) キーワード定義が可能 実環境で利用可能 http://cmusphinx.sourceforge.net/ OK, Googleのような使い方ができる 造語も使える

Slide 82

Slide 82 text

What is Pocketsphinx? オフラインで認識可能 音響モデル・言語モデルは限られている(日本語はない) キーワード定義が可能 実環境で利用可能 http://cmusphinx.sourceforge.net/ 環境雑音の抑圧性能が優秀 (Juliusは自前で雑音抑圧しなければならない)

Slide 83

Slide 83 text

How to use Pocketsphinx? 連続音声認識でインコアプリを作ろう http://qiita.com/KAKKA/items/1cbaa4adaf06b6439f2c

Slide 84

Slide 84 text

How to use Pocketsphinx? 公式デモアプリ https://github.com/cmusphinx/pocketsphinx-android-demo PocketSphinxActivity.java

Slide 85

Slide 85 text

How to use Pocketsphinx? 公式デモアプリ https://github.com/cmusphinx/pocketsphinx-android-demo PocketSphinxActivity.java

Slide 86

Slide 86 text

How to use Pocketsphinx? 公式デモアプリ https://github.com/cmusphinx/pocketsphinx-android-de mo PocketSphinxActivity.java setAcousticModel()では音響モデルを指定 このデモアプリでは英語の音響モデルがデフォルトで入っている

Slide 87

Slide 87 text

How to use Pocketsphinx? 公式デモアプリ https://github.com/cmusphinx/pocketsphinx-android-de mo PocketSphinxActivity.java 辞書をセット Cmudict-en-us.dictをみると英語の巨大な辞書ファイルが見られる 要件次第でここを削って必要な分だけ定義し、容量を減らす

Slide 88

Slide 88 text

How to use Pocketsphinx? 公式デモアプリ https://github.com/cmusphinx/pocketsphinx-android-de mo PocketSphinxActivity.java 人間の声を検出したらそれをファイルとしてガンガン保存していくようになる。 ほぼデバッグ用?

Slide 89

Slide 89 text

How to use Pocketsphinx? 公式デモアプリ https://github.com/cmusphinx/pocketsphinx-android-de mo PocketSphinxActivity.java KeyPhraseSearchモード(後述)における検出閾値をセット 小さいほどよく検出するが、誤検出が多くなる。 1e+60から1e-60くらいまでセット可能

Slide 90

Slide 90 text

How to use Pocketsphinx? 公式デモアプリ https://github.com/cmusphinx/pocketsphinx-android-de mo OK Googleのような特定のwordの音声認識モードを追加 setKeywordThresholdが適用される KEYPHRASEに好きなワードを設定すると、そのワードを検出できるようになる ただし、ワードは一つのみ

Slide 91

Slide 91 text

How to use Pocketsphinx? 公式デモアプリ https://github.com/cmusphinx/pocketsphinx-android-de mo menuGrammarで定義された複数ワードの検出を行う しかしmenuGrammarで定義されたワードを必ず一つ検出して返す 例: menu.gram public = digits | forecast | phones; 「でぃ」といえば digitsが返る

Slide 92

Slide 92 text

How to use Pocketsphinx? 公式デモアプリ https://github.com/cmusphinx/pocketsphinx-android-demo menuGrammarと同じ digits.gram = oh | zero | one | two | three | four | five | six | seven | eight | nine;

Slide 93

Slide 93 text

How to use Pocketsphinx? 公式デモアプリ https://github.com/cmusphinx/pocketsphinx-android-de mo keyPhraseSearchの複数wordバージョン menu.gram yo drivemode/1e-25/ ok google/1e-15/ hey siri/1e-10/ awesome droidkaigi/1e-60/

Slide 94

Slide 94 text

How to use Pocketsphinx? 公式デモアプリ https://github.com/cmusphinx/pocketsphinx-android-demo 単語辞書ファイルに造語の追記もできる

Slide 95

Slide 95 text

How to use Pocketsphinx? 公式デモアプリ https://github.com/cmusphinx/pocketsphinx-android-demo 結果はpocketsphinxのRecognitionListerで受け取る

Slide 96

Slide 96 text

Drivemodeの連続音声認識 “Yo Drivemode”を拾う 連続音声認識 SpeechRecognizer startListening() Yo, Drivemode Navigate to Gas Station Starting navigation... “Yo Drivemode”を拾う 連続音声認識 認識結果から諸々の処理 Pocketsphinx Googleアプリ

Slide 97

Slide 97 text

Drivemodeの連続音声認識

Slide 98

Slide 98 text

問題点

Slide 99

Slide 99 text

マイクは一人しか使えない Pocketsphinx SpeechRecognizer OK, Google Googleマップの SpeechRecognizer

Slide 100

Slide 100 text

マイクは一人しか使えない SpeechRecognizer Pocketsphinx OK, Google Googleマップの SpeechRecognizer

Slide 101

Slide 101 text

マイクは一人しか使えない Pocketsphinx SpeechRecognizer Pocketsphinx stop listening start listening

Slide 102

Slide 102 text

マイクは一人しか使えない Pocketsphinx SpeechRecognizer stop listeningを 呼ばないといけない OK, Google OK, Google OK, Google OK, Google 5秒ごとにstartをtry

Slide 103

Slide 103 text

マイクは一人しか使えない OK Google SpeechRecognizer OK Google OK Google OK Google Priorityが低いので勝手に stopしてくれる 5秒ごとにstartをtry

Slide 104

Slide 104 text

自分の声を拾っちゃう Pocketsphinx

Slide 105

Slide 105 text

自分の声を拾っちゃう Pocketsphinx Yo Drivemodeと言えば、ボイス コマンド認識がスタートします。 TTS

Slide 106

Slide 106 text

自分の声を拾っちゃう Pocketsphinx Yo Drivemodeと言えば、ボイス コマンド認識がスタートします。 TTS Yo Drivemodeを検出!

Slide 107

Slide 107 text

プロセスがkillされちゃう Pocketsphinx On Service Service kill!!

Slide 108

Slide 108 text

プロセスがkillされちゃう Pocketsphinx On Service App process プロセス分けて プロセス間通信で

Slide 109

Slide 109 text

最後に

Slide 110

Slide 110 text

We are hiring! Android Engineer Data Scientist kakka@drivemode.com