数時間でボット、またはマシンでビールについて話す

機械と人間の相互作用を改善するというトピックは、これまで以上に重要になっています。 「100クリック」モデルから「言いたいことを言う」パラダイムに移行するための技術的な機会があります。 はい、数年前から誰もが開発したさまざまなボットを意味します。 たとえば、多くの大企業は、技術だけでなく小売、物流も含め、現在この分野で活発な研究と設計を行っています。



簡単な例、たとえば、オンラインストアで製品を選択するプロセスはどのようになっていますか? たくさんのリスト、私が探し回って何かを選ぶカテゴリ。 それは吸うのです。 または、たとえば、インターネット銀行に行くと、さまざまなメニューに出くわし、振込を行いたい場合は、メニュー内の対応する項目を選択し、データの束を入力する必要があります。トランザクションのリストを表示するには、もう一度、脳と人差し指。 このページに移動して、「牛乳1リットルとウォッカ0.5リットルを買いたい」と言うか、単に銀行に「お金はいくらですか?」と言うと、はるかに簡単で便利になります。



かなり短期間で絶滅に直面している職業のリストには、窓口係、コールセンターのオペレーター、その他多数が含まれます。 実装に約7時間かかった簡単な例で、オープンなWit.Aiを例として使用して、音声認識とエンティティ検出の統合を非常に簡単に行う方法を示します(Google Speech API統合も含まれています)。







かなりの数の音声認識APIがあり、それらの一部は有料で、一部はシステムの開発用に公開されています。 たとえば、Google Speech APIは1か月あたり60分の認識を無料で提供します。この制限を超えると、料金は毎分0.006セントの料金で15秒単位で請求されます。 それどころか、Wit.aiは開発者向けのオープンAPIとして位置付けられていますが、たとえば、サービスへの呼び出しの数が月に数十万、さらには数百万にまで増加した場合、同じレベルのサービスを提供するかどうかは疑問のままです。



数週間前、データサイエンスと人工知能に関するセミナーがタルトゥで開催され、多くの講演者が、人間が理解できる言語で人間と機械の相互作用のトピックに何らかの方法で対処しました。 そして、次の週末のイベントの後、公共サービスを使用して音声認識を実装することにしました。 そしてもちろん、私はボットに、私がビールを飲みたい、そしてどのビールを正確に飲みたいかを理解してもらいたい。 暗いまたは明るい、そしておそらくまた品種を理解するでしょう。



一般に、タスクは、彼がクライアント側で言ったことを書き留め、サーバーに転送し、いくつかの変換を行い、サードパーティAPIを呼び出し、結果を取得することです。

最初は、Google Speech APIを使用して音声ファイルの文字起こしを取得する予定でしたが、その後、一連のエンティティと意図を取得するためにテキスト行をWit.AIに送信したいと考えていました。



バックエンドの選択は私にとって些細なことでした、それはSpring Bootです。 また、Javaスタックが私にとってネイティブであるだけでなく、サードパーティのAPIとクライアントの間の仲介として機能する小さなサービスを作成したかったためです。 追加のサービスを導入することにより、追加の機能を実装できます。



ソースコードをGitHubに投稿しました。 Herokuにデプロイした動作中のアプリケーションはhttps://speechbotpoc.herokuapp.com/です。 使用する前に、マイクの使用を許可してください。 次に、マイクアイコンをクリックして発言した後、もう一度アイコンをクリックします。 あなたが言ったことはあなたに対して使用され、認識のために送信されます。しばらくすると、左側のパネルに結果が表示されます。 この例は複数の人が使用できるため、競合状態を回避するために、認識言語の選択は無効になっているため、翻訳言語の選択をオフにしました。







したがって、最初に、Spring InitializrまたはSpring Boot CLIを使用して空のプロジェクトを作成しています。必要に応じて、Spring Initializrを選択しました。 必要な依存関係は、Spring MVC、Lombok(多くの定型コードを記述したくない場合)、Log4jです。 作成したプロジェクトフレームワークを好みのIDEにインポートします(他の人はEclipseを使用しますか?)。



開始するには、クライアント側でオーディオファイルを録音する必要があります。 HTML5はこれに対するすべての可能性を提供しますが(MediaRecorderインターフェイス)、MITライセンスの下で配布されるMatt Diamondとは異なる実装があり、Mattもクライアント側で優れた視覚化を開発したため、それを採用することにしました。 実際、ほとんどの場合、サーバー側の開発ではなく、クライアント側の実装が必要でした。 AngularJSやReactJSは使用しませんでした。一般的な統合に興味があり、jQueryが安くて陽気だったからです。



サーバー側については、最初に音声ファイルのテキストへの最初のトランスクリプションにGoogle Speech APIを使用したかったため、このAPIではクライアント側で録音された音声をBase64でトランスコードする必要があるため、音声データを受信したときにBase64にトランスコードしてから送信しましたサーバーに。



フレームワークでは、オーディオファイルを受け取るコントローラーを作成します。



@RestController public class ReceiveAudioController { @Autowired @Setter private WitAiService service; private static final Logger logger = LogManager.getLogger(ReceiveAudioController.class); @RequestMapping(value = "/save", method = RequestMethod.POST) public @ResponseBody String saveAudio(@RequestBody Audio data, HttpServletRequest request) throws IOException { logger.info("Request from:" + request.getRemoteAddr()); return service.processAudio(data); } }
      
      





すべてが非常に簡単です。データを受け入れ、それをさらにすべての作業を実行するサービスに送信します。



WitAiServiceサービスも非常に簡単です。



 @Data @Component @ConfigurationProperties(prefix="witai") public class WitAiService { private static final Logger logger = LogManager.getLogger(WitAiService.class); private String url; private String key; private String version; private String command; private String charset; public String processAudio(Audio audio) throws IOException { URLConnection connection = getUrlConnection(); OutputStream outputStream = connection.getOutputStream(); byte[] decoded; decoded = Base64.getDecoder().decode(audio.getContent()); outputStream.write(decoded); BufferedReader response = new BufferedReader(new InputStreamReader(connection.getInputStream())); StringBuilder sb = new StringBuilder(); String line; while((line = response.readLine()) != null) { sb.append(line); } logger.info("Received from Wit.ai: " + sb.toString()); return sb.toString(); } private URLConnection getUrlConnection() { String query = null; try { query = String.format("v=%s", URLEncoder.encode(version, charset)); logger.info("Query string for wit.ai: " + query); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } URLConnection connection = null; try { connection = new URL(url + "?" + query).openConnection(); } catch (IOException e) { e.printStackTrace(); } connection.setRequestProperty ("Authorization","Bearer " + key); connection.setRequestProperty("Content-Type", "audio/wav"); connection.setDoOutput(true); return connection; } }
      
      





Wit.AIのキーやトークンなどの必要なパラメーターはすべて、application.propertiesファイルから取得されます。 (はい、アプリケーションのトークンを開きました)。 Wit.AIでアプリケーションを登録する場合は、設定ファイルのトークンとApp.IDを変更する必要があります。 Wit.AIへの登録は非常に簡単です。トークンは[設定]セクションで取得できます。



Spring Bootは注釈付きの設定をプルアップします。 データおよびセッターアノテーションは、セッター、ゲッター、デフォルトコンストラクターなどの形式でテンプレートコードを記述しないようにするLombokプロジェクトアノテーションです。



モデルファイル、および補助コンバーター、私はここに持ってきません、これはすべてソースで見ることができます。



Chromeで開発者コンソールを開くと、上記を記述した後、RESTサービス呼び出しが行われ、Base64でエンコードされたオーディオデータがコンテンツフィールドでサーバーに転送されることがわかります。 Googleの請求に問題がありました(古いクレジットカードの請求は登録されていますが、まだ新しいクレジットカードは登録していません)。GoogleSpeech APIとのやり取りを書いた後、それをWit.AIに直接送信することにしました。 ただし、Wit.AIはストリーミング形式のデータをそのまま受け入れるため、サーバーはBase64からwav形式にトランスコードします。



  byte[] decoded; decoded = Base64.getDecoder().decode(audio.getContent()); outputStream.write(decoded);
      
      





認識に関する小さな点。 マイクのレベルに注意してください。マイクの感度が非常に高いと、認識音質に悪影響を与えるカット音が聞こえます。



これで、私たちが言ったことを認識できたので、具体的に何が欲しいかを理解するようにアプリケーションに教えましょう。 Wit.AIを理解するセクション(このためには、Wit.AIにアプリケーションを登録する必要があります。つまり、登録は難しくありません。)いわゆるインテントまたは意図を設定できます。 かなり論理的に見えます。たとえば、「ビールを飲みに行きましょう」という行を書き、必要な単語(この場合は「ビール」)を選択 、[ 新しいエンティティ追加 ]をクリックして、 インテントを選択し、 インテンションを作成しますビール。 さらに先に進み、ビールを飲みたいかどうかを理解し、新しいエンティティ「Drink」または「Drink」を作成します。 さらに、「今日はビールかもしれません」、「明日はビールを飲みましょう」など、いくつかの例を紹介することをお勧めします。 その後、システムは意図をより正確に割り当てます-ビール。



さて、どんな種類のビールを飲みたいか、明るいか暗いかを理解したいとしましょう。 同様に、「明日は黒ビールを飲みましょう」という新しいフレーズを導入し、「ダーク」という言葉でもう一度[ 新しいエンティティを追加 ] クリックする必要がありますが、既存のエンティティを使用する必要はありませんが、アプリケーションでは独自のエンティティを作成しますbeer_typeという名前です 。 次に、ライトビールについても繰り返します。作成済みのbeer_typeエンティティを選択するだけです。 その結果、システムは、私がビールを飲みたいと思っていること、そしてどのビールが特に好きかを理解し始めます。 WIT.AI RESTインターフェイスを使用して、上記のすべてを手動ではなく自動で設定することもできます。 カテゴリは、バッチモードでエンティティに簡単に変換できます。



例では、暗いビールまたは明るいビールを飲むことを提案しようとすると、システムは、ビールの意図とbeer_typeの両方を含むオブジェクト(暗いまたは明るい)を返すことがわかります。



この例はちょっとしたおもちゃですが、RESTインターフェースを介してエンティティを追加することもできるため、製品のカタログをボットエンティティに変換するのは非常に簡単です。また、Wit.AIには、時刻/日付、場所など、多くのコンテキストエンティティがあります。 つまり、今日または明日(日付)、ここ(場所)などの文脈上の単語から情報を取得できます。 詳細なドキュメントはこちらです。



コード自体は非常に単純であり、すべてが明らかです。 他のサービスとの統合のロジックは同じです。 トランスクリプションを受け取った後、この行を他のサービスに転送できます。たとえば、希望の製品をバスケットに追加するサービスを作成したり、翻訳用の行を単にニューロサービスに転送したりできます( http://xn--neurotlge-v7a.ee/#逆も同様ですが、他の言語でもモデルをトレーニングできます)。 つまり、この例は、より複雑な対話の流れを構築するための小さなレンガとして機能します。 たとえば、トークンまたはCookieを受け取ったこの例を食品注文サービスに接続して、自宅でビールを注文できます。 または、反対に、メッセンジャーでビールの提供を友人に送信します。 多くのユースケースがあります。



考えられる用途:オンラインストア、オンラインバンキング、翻訳システムなど



ご質問がある場合は、ご連絡ください。



All Articles