Android
C#
iOS
Azure
機械学習

#VUILT @ Google Vol.2で現金処理機を音声操作するプロジェクトのLTをしてきた話

IMG_2495 (1).jpg
撮影はYamazaki, Harukiさん

はじめに

5月31日の夜に VoiceUIライトニングトーク!/VUILT vol.2 @Google という250人が集まるイベントがあり、所属部門長およびしかるべき部門の許可を受けて現金処理機を音声操作する社内実験プロジェクトでの苦労話をしてきました。スライドスマボスさんによるYoutubeのライブ配信などが公開されていますのでよろしかったらご覧ください。当日は5分間のLTだったので、僕のスライドにしては珍しく文字多目で、スライドの詳細は説明せず、後で公開資料を読んでくださいという感じで10秒ほどですっ飛ばしたスライドが何枚もあります。そこで、僕が当日お話しした内容を補足するとともに自分の思いを加えてここでシェアしたいと思います。

グローリーの紹介

p1.jpg

まず最初に会社の紹介をさせてください。当日は時間もなかったのでしっかり紹介できませんでした。グローリーは今年(2018年)、創業100周年を迎える現金処理機のメーカーです。主要な顧客はメガバンクを筆頭とした銀行とイオンやヨーカドーなどの流通業、 最近ではローソンにも導入 されました。世界的にみても老舗のトップブランドではあるのですが、近年勢いを増して進みつつあるキャッシュレス社会においても成長を続けられるよう、新しいビジネスの芽を育てていきたいと考えています。

取り扱っている製品には、銀行に設置する大型の出納システムからレジ下に置く釣銭機のような現金処理機以外に、コインロッカー、券売機や自販機 なども作っており、物理的な決済が必要な分野やモノを扱う分野でITサービス業界と連携できないかと日々模索しています。過去には楽天とこのような連携も試していました。

プロジェクトの紹介

今回の実験テーマは、それまでのプロジェクトで若干の下地があったとはいえ、2018年1月に実質3週間程度の短期間で開発しました。ターゲットデバイスは、iPhone、Apple Watch、Android、AndroidWare。開発言語にはXamarinを使用し、プラットフォームごとの差異をできるだけ吸収するため、音声認識と自然言語理解は各々のプラットフォーム上で固有に提供されているものではなく、MicrosoftのAzure上で提供されているCognitive Serviceを利用し、同じくMicrosoftからNuGetで提供されている音声録音ライブラリやCognitive Serviceとの接続ライブラリを利用しつつ、コード量を極力抑えてUI/UXの向上に力を注ぎましたました。こちらが利用しているサービスとライブラリになります。

【利用しているCognitive Service】
Bing Speech API:音声からテキストへ変換する
LUIS:テキストを処理して意図とエンティティを抽出する

【利用しているライブラリ】
Plugin.AudioRecorder:マイクの録音制御ライブラリ
Xamarin.Cognitive.BingSpeech:音声認識サービス接続クライアント
Microsoft.Cognitive.LUIS:自然言語理解サービス接続クライアント(現在は非推奨になってます)

デモビデオ

LTでは最初にiPhone版のデモンストレーション(50秒)があったのですが本記事では割愛します。上記Youtube配信で雰囲気だけをお楽しみください^^;

社内展示会での反応

p2.jpg

このシステムは2月に社内技術展示会に出展し、来場した技術者による総選挙で69の技術展示があるなか7位を獲得し上位10%に食い込みました。メカトロニクスを中心とした技術力と製品を売りにしている弊社において、こういったソフトウェア・ソリューションが上位に食い込むのは非常に珍しいことです。来場者に記入してもらったアンケートの集計や個別の回答内容を読むと、音声による操作について社内の技術者たちもかなり興味を持っていることがうかがえました。

現金を扱う機械を作っていることからお堅いイメージを持たれるグローリーですが、社内では先進的な技術へのチャレンジを通じて技術力を高めようという実験プロジェクトがいくつか立ち上げられ、外から見るとおよそ縁のなさそうなソリューションに、こっそりと手を出し知見を仕入れたりしています。そう言った意味では、外から見えるお堅いイメージとは違う、技術者たちの柔かな発想と受容性、それを許せる幹部のおおらかさとコミットメントが機能しているなと思います。実際、何年かに一度回ってくる今回のような実験的なプロジェクトに携わると、年甲斐もなくワクワクする部分もあります。やってる最中はコレジャナイ感に打ちのめされることもあるんですけどね^^;

音声操作はありなのか

p3.jpg

実験を始める前からわかっていたことですが、正直なところ、音声で現金処理機を操作することにメリットを見出すことはできません。しかし、それでもユースケース次第で音声操作は「あり」だと思います。

これは僕の思いですが、デメリットならいくらでもあげられます。声を出すということは周りにいる人に知られるということと等しいので、いくらお金の出し入れをしたのか周りに吹聴されることをうれしく思う人は少ないでしょう。さらに、音声の認識率の問題があります。GUIで出金ボタンをクリックして実行されなければ、それは「不具合」です。同様に「出金」と声をかけても認識されなければ、それも「不具合」です。それが一般的な製造業の考え方であり品質の捉え方だと思います。

確かに、製品として音声操作を取り入れることは、少なくとも現時点では現実的ではありません。しかし、8割しか認識できなかったとしても、今までゼロだったことが8割できるようになるユースケースであれば、それを品質の向上ととらえるのは製造業であろうと同様です。音声を使うという技術そのものではなく、GUIなら100%できていたことが、音声を利用することにより80%になってしまう。そのようなユースケースで使うことに問題があると言えます。逆に100%できていたことが、あるシチュエーション、例えば両手がふさがっているなどでゼロになった時、代替手段として音声がゼロから80%の状態に引き上げてくれるのなら「あり」です。

上記は、de:code2018で、機械学習のチョークトークに参加した際にマイクロソフトの畠山大有さんから頂いたアドバイスですが至言ですね。そして機械が動いているお客様の現場には、意外とそのようなシチュエーションがあったりするかもと思っています。例えば工具をもっていて手が離せないことの多い保守員のサポートシステムとか、de:code2018でいくつもプレゼンテーションされていたHololensを使ったMixed Reality的なメンテナンスサポートのアプローチも含めて「あり」だと個人的には思います。

苦労したこと

p4.jpg

それでは実装に際して苦労した点をお話しします。

ここでなぜカラス?と思った方は和英辞書アプリへGO!ちなみにLTでは、ここは完全にスルーされました…(´;ω;`)

音声認識は思っていたより曲者

p5.jpg

今回のシステムを構築するにあたり一番ポイントになったのは音声認識の精度でした。最初は海外向け製品の実験なので英語で音声操作を行おうとしたのですが、僕のジャパニーズ・イングリッシュでは全く歯が立ちません。あれは軽く打ちのめされた瞬間でした。そこで日本語でドルを入出金するというハイブリッドな仕様にしたのですが、関西弁を話す姫路本社のメンバーはイントネーションのせいなのか滑舌の問題なのか、はたまた話し方がせっかちなのかうまく認識されないケースが目立ったようです。

ここからは私見+ネタトークですが、当時の部長(現副統括部長)が話す播州弁は認識が著しく悪かったようで、音声認識も人柄を見るとまことしやかに伝えられたとかなかったとか。Xamarinによる実装、Bing Speech APIの設定とLUISの学習などは東京勤務の僕が担当していたのですが、デバッグ中に誤認識するシーンはほとんどありませんでした。やはり人柄かもしれません。Bing Speech APIの学習データが標準語話者に偏よるというバイアスがかかっていた可能性はありますが、顔認識で年齢、性別や感情を見抜くのですから、音声から人柄くらいは見抜けるような気がしますし、その方が面白いので人柄ということにしておきます(^^;

発話と終話のタイミング

p6.jpg

実装上で最初に困ったのは、いつ話し始めてもらい、いつ話し終わったと判断すればいいかという発話と終話のタイミングでした。

ここは時間がなくて口頭での説明を10秒ですっ飛ばしたので補足させてください。例えば、システムが「ご用件をどうぞ」と言い終わらないうちに、「30ドルの出金」などとかぶせるように発話するユーザーが結構います。システムは「ご用件をどうぞ」と言い終わってからマイクをオンにして聞くモードに入りますから、かぶせられると「…ルの出金」などのように先頭の発話を聞き漏らしてしまいます。自分でVUIを設計して色々試してみて初めて、Siriが「ピコン」という音で聞くモードに入りましたよと知らせている理由が分かりました。そこで同様に「ピコン」という音で聞くモードに入ったことを知らせるようにしました。

一方で、話が終わったことをどうやってシステムに知らせようかという問題があります。例えば、「オーバー!」と言ったら終話と判断することもできますが、そうすると話はじめに「スネーク!」と言いたくなります。また、話の中でオーバーという単語が出てくるケースを考えると、話の最後でオーバーと言われたのか判断しなければなりません。それでは、話が終わったことをどうやって知るかという問題に再び戻ってきてしまい堂々巡りです。ですから、この方法はあまりいい解決策ではないようです。

そこで、無音時間が2秒経過したら話が終わったと判断するようにしました。1秒では話に詰まったとき無音判定されて途中で切られることが多くイラっとします。かといって3秒では、話が終わっているのに先に進まなくてイラっとします。ですから2秒。妥協の産物。

無音状態の定義

p7.jpg

次に困ったのは、どういう状態にあるとき無音と判断すればいいのかということでした。

ここも時間がなくて口頭説明を10秒ですっ飛ばしたので捕捉させてください。お気づきのように純粋な無音(録音レベルゼロ)というのは環境音もありますから実質的にはあり得ません。無音検知の閾値が高すぎると声が小さい人の話は途中で切られてしまいます。デバッグ中は周りの人に遠慮して小声で話してしまうのですが、話がよく途中で切られていました。一方、閾値が低すぎると周りが少し騒がしいだけで話が終わりません。デバッグ中に設定していた閾値ではざわざわした環境下では話が終わらないこともあります。ここは試行錯誤して録音レベルを30%と設定しましたが、本当は周りの環境音のレベルを一定間隔でサンプリングして、動的に無音検知の閾値を変えていくべきなのかもしれません。

マルチプラットフォーム環境下で、マイクというハードウェアを取り扱いながら、録音を開始/終了したり、録音レベルを監視したり、無音時間のタイマー監視したり、これらを自作で作り込むのはかなり面倒です。ある程度音声のデジタル化に関する知識も必要になってきます。しかしマルチプラットフォーム対応のPlugin.AudioRecorderライブラリを使用すれば、AudioRecorderServiceクラスの初期化時に以下のようなパラメーターを渡すことで簡単に無音検知の閾値、監視時間を設定し録音を開始することができます。

AudioRecorderService recorder = new AudioRecorderService
{
    SilenceThreshold = 0.3f,
    StopRecordingAfterTimeout = true,
    TotalAudioTimeout = TimeSpan.FromSeconds(15),
    AudioSilenceTimeout = TimeSpan.FromSeconds(2)
};

音声認識の意外な一面

p8.jpg

音声認識では誤認識に悩まされました。

ここも時間の都合上10秒ですっ飛ばした部分なので補足します。まず最初に漢数字に変換される件です。Bing Speech APIは、何も考えずにデフォルトの状態で使うと「さんじゅうどる」を三十ドルと漢数字に変換します。これは、書き言葉としては正しい変換ですから仕様通りです。英語でも書き言葉では「$30」ではなく「thirty dollars」です。しかし残念なことに、C#は三十をintに変換してくれるほど賢くはありません。僕はブログラマです。プログラマである以上、漢数字を数字に変換するプログラムを書くことはできます。しかし、無意味にコードを書くのが嫌いなので、なんとかコードを書かずに済むよう、誰かがすでに実装してテストも済んでいる代替策を探します。(これが品質と生産性を上げる秘訣ですよ。車輪の再発明はやめましょう。)

見つけました。

Bing Speech APIにはInteractive、Conversation、Dictationの3つのモードがありますが、Dictationモードを使えば30ドルで返ってきます。なぜなのかは分かりません。Dictationモードは長い話を認識するモードで、書き起こしなどの用途に使われやすいはずであり、いちばん三十ドルと表記しそうなモードにみえます。何かの意図があるのでしょうか?今度マイクロソフトに聞いてみたいところです^^;

続いて、「しゅっきん」を会社に出かける方の「出勤」に誤変換してしまう問題です。しかしこれはBing Speech APIに責任をかぶせるわけにはいかないと思います。単純にうちの会社の事業ドメインが悪い。「しゅっきん」と言われて「出金」を思い浮かべる人はほぼいません。銀行員かグローリーの社員だけでしょう。PCで漢字変換しても最初の候補は「出勤」です。それが世間の常識というものです。つまりグローリーの常識はこの部分において世間の常識とは違っている訳です。確認したことはありませんが、きっとうちの社員たちは「出金」をIMEに辞書登録するか、一番最初の変換候補に出るように鍛えまくっていることでしょう。ちなみに似たような用語で「在高」(ありだか)というのがありますが、これを「ありだか」と読めるのもきっと銀行員とグローリー社員だけでしょう^^;

ロケールと通貨

p9.jpg

最後に苦労したのは自然言語理解の学習でした。Azure Cognitive ServiceのLUIS (Language Understanding Intelligent Service)という自然言語理解のサービスを利用していますが、通貨がロケールに1対1で紐付けられているため、Built-inで用意されているmoney型のエンティティが使えません。日本語ロケールでは「30円」というテキストはmoney型のエンティティとして抽出できますが、30ドルはmoney型として扱うことができません。money型のエンティティは、テキスト内の30円という文字列を自国通貨として抽出し、30という値部分をエンティティ内にセットするだけで、通貨記号についてはそのLUISインスタンスに設定されているロケールに準じます。

この仕様自体は、WindowsやLinuxにおけるロケールの設定と同様であり受け入れられないものではないのですが、あまりプログラマブルではないLUISインスタンス上で、多数の通貨を扱おうとした場合かなり残念な仕様になってしまいます。

日本、ユーロ加盟国やアメリカは基本的に自国通貨が主要な流通通貨ですから、このような問題が露見する可能性は少ないのですが、ペルーやトルコなどは、自国通貨+ドル、ユーロ、ポンドなど他の基軸通貨が、街中の個人商店のようなところでも普通に使用できます。もしグローリーが今後自然言語処理を使った何らかのソリューションを作っても、現金処理機の会社ですから多数の国で多数の通貨をその中で扱う必要があります。

色々と悩んだ末に出した結論は、LUISに備わっているコンポジット・エンティティという機能を使って、number型のエンティティとドルや円といった通貨文字列の二つを持つコンポジット・エンティティを自作しnumber部分と通貨部分をLUISインスタンスの持つロケールに関係なく扱えるようにしました。このやり方が正解かどうかは定かではないのですが、今のところ多通貨を金額という名称のコンポジット・エンティティで抽出できています。

再び、音声操作はあり?

p10.jpg

音声操作には述べてきたような苦労はありますが、最初に述べたように基本的には「あり」だと思っています。そのもう一つの理由がこの数字です。何の数字か分かるでしょうか?

難聴は75歳から、老眼は50歳から

p11.jpg

75というのは難聴を自覚し始める年齢で、50は老眼を感じ始める年齢です。耳よりも先に目が衰えるのです。つまりこの25年の間に徐々に人は目から耳に頼るようになります。日本も中国も少子高齢化街道まっしぐらで、GDP2位と3位の国が高齢化社会に突入するのです。音声操作の前には巨大なマーケットがひらけていると思います。

さて、ここからは自分の体験です。実際に自分がアラ還になって分かることですが、小さな画面の字は読むのも打つのもツライのです。以前、カエルコールはLINEだったのですが最近はもっぱら通話です。しかもSiriに向かって「カミさんに電話」でかけさせるという…

これが楽なんです。欅坂46が流れるイヤホンスイッチを長押ししてSiriを呼び出すだけ。GUIはユーザーが自ら操作して目的にたどり着くUI、VUIはユーザーの意図をコンピューターが推測して目的に案内するUI。どちらが楽か一目瞭然ですよね。

今回の実験プロジェクトでは、ここで説明しきれなかったいろいろな細かな技術的な苦労がありましたし、UI/UX設計というデザイン面からもいろいろな困難や葛藤がありました。LUISの学習においては、今思えば過学習だったなと反省することもあり、かといって認識の品質面からは追い込まざるを得ずというジレンマもあり。その辺りの話はまた別途機会があったらどこかで発表したいと思います。

音声の前に開けている大きなマーケット、それが僕が音声操作を実験テーマに推薦した理由の一つです。もう一つの理由は、AIをやってみたかったけど、そのほかのAIは敷居が高そうだったから。おかげさまで、この自然言語処理を通じて機械学習への興味が増し、58歳の文系エンジニアがCourseraのMachine Learningを苦労して完走した話 というトピックにつながります。3月末に講座を終えてから2ヶ月、業務では機械学習と関係のない二百数十ページに及ぶ英文仕様書をコツコツと書いていましたが、業後の社外勉強会やde:code2018などのイベント参加を通じて、すごく色々なことを色々な方々に教えてもらいワクワクしてます。

Microsoft AzureのCognitive Serviceも、CustomizableなCognitive Serviceが追加されたということをde:code2018でお聞きししました。時間を見つけてSpeech APIやLUISがどのように変わり、ここで苦労した課題を解決できるのかどうか調べてみたいと思います。

そういえば、このイベントと同じ時期にけやき坂46 『期待していない自分』 がリリースされましたね。でも、この春に ひらひらひらら というのを聞いてClariSもいいなと思い始めました。ClariSヘビロテ中の僕からは以上です。