みんな知らない凄いヤツ はじめようProject Oxford

2015年12月14日月曜日

この記事はMS技術Advent Calendarの14日目のものです。

Project Oxfordとは何か

Project OxfordはMicrosoftの自然データ解釈技術をアプリやサービスへと簡単に取り込めるようにするプロジェクト(Microsoft Project Oxford)です。
2015年4月のMicrosoft主催のデベロッパーカンファレンス(//build 2015)で発表されました。
このカンファレンス時には多少話題になったのですが、実際のSDK提供までにしばらくのタイムラグがあったためあまり最近話題になっていないのが現状です。つまり、ほとんど知られていないので紹介していきますよという話です!
使える機能群には自然言語処理や画像認識など、事前にガンガンとトレーニングをかけた機械学習の権化のようなものがいっぱいあります。MSの技術というよりもMSR(Microsoft Research)の成果を一般転用したものという印象です。

アイドルCortanaさん

Project Oxfordで提供される仕組みを使った実世界のサービスの代表格がWindowsアイドル、Cortanaさんです。iOS界のスーパーアイドルSiriと競い合う感じで日々前へ出ようとしていますね。
コル、コル、タナーーー! みなさん一緒に、「「「コル、コル、タナーーー! 」」」

なぜProject Oxfordが嬉しいのか

みなさんご存知のhttps://how-old.net/、平和の極みみたいなサービスですよね。特に誰も傷つけることなく*1写真からの顔認識とその年齢推定を楽しさへと変えてくれるサービスです。
その昔、face.comというオンラインの顔認識サービスがありました。残念ながらFacebookが買収してサービスをシャットダウンしたので、私は安価/無料で比較的自由に利用できるオンラインの顔認識サービスがなくて厄介だなぁと思っていました。
Project Oxfordでは顔認識サービスも公開されています。顔認識と共に感情の推定もおこなってくれる、なかなかすごいやつです。
私はどちらかというと機械学習したいマンではなくて機械学習結果を使いたいマンなので、ひとまずProject Oxfordのあれこれを触ってみようという次第です*2
[*1] 勝手に他人の画像をアップロードして不快感を生むなどはさすがに例外とさせてください。
[*2] 同じ方面ではGoogleが2015年12月にCloud Vision APIという仕組みの限定プレビュー版を開始したようですね。https://cloud.google.com/vision/

提供されている機能の概要

Project Oxfordで提供する機能は多岐にわたります。ここでは本家サイトの構成に準ずる形で一覧を紹介します。
興味をもった項目はぜひリンクを辿って詳しく調べてみてください。
  • Vision
    • Computer Vision APIs
      • 画像分析、サムネイル生成、OCR(文字認識)
    • Face APIs
      • 顔認識、顔認証、類似顔検索、顔分類、顔識別
    • Emotion APIs
      • 感情認識
    • Video APIs
      • 未公開(実際にはProject Oxfordポータル側では映像の安定化(stabilize)、動き検出、顔認識とトラッキングを制限つきで提供するとあります)
  • Speech
    • Speech APIs
      • 音声認識、音声意図認識、音声合成(TTS)
    • Speaker Recognition APIs
      • 未公開(音声データを突っ込むと話者を識別して返してくれるものになるはず)
    • Custom Recognition Intelligent Service
      • 未公開(IBMのワトソンみたいな、とまではいかないまでも、アプリケーションを音声入力でサクサク使えるようにする仕組みのはず)
  • Language
    • Spell Check APIs
      • スペルチェッカとしての高度な機能(単語区切り位置の間違い訂正、スラング込みの認識、ありがちな名前のスペルミス訂正、文脈中での間違い訂正、最近のブランド名サポート)
    • Language Understanding Intelligent Service(LUIS)
      • 自然言語を使ってアプリケーションを操作する仕組みを簡単に実現する仕組み
一覧の最新版はわりとhttps://github.com/Microsoft/ProjectOxford-ClientSDKにまとまっています。

サポートするプラットフォーム

音声認識系APIが最も対応範囲の広いもので、Windows/iOS/Androidをサポートします。顔認識とCVはWindows/AndroidのSDKを提供しています。スペルチェックと感情認識はWindowsのSDKのみを提供しています。
音声認識など一部の機能はWindows 10に組み込まれているもので、Windows版SDKの内部でそのOS組み込み機能を呼んでいるようです。Windows 10 Mobileでの挙動についてはまだ実機で確認していないので把握できていません*3
[*3] MADOSMAのOTA更新がなかなか来ないのでそろそろマウスショップへ持ち込もうかなと思い始めた昨今です。

利用制限

利用制限はそれぞれのAPIごとに異なります。たとえば音声認識APIでは月間のAPI呼び出し可能回数が5,000回に制限されています。
詳しくはドキュメントを読む必要があります。

音声認識APIことはじめ

まずはこのデモをごらんください。
https://www.projectoxford.ai/demo/speech#recognition
これは、Project Oxfordの本家サイトでホストされている音声認識と音声合成のデモです。PC向けのモダンなWebブラウザで開くと、一切のプラグインを要求することなく音声認識を実現できることがわかるでしょう。
ちなみに音声認識についてはAndroid向けのクイックスタートガイドがあります。Android勢はこちらを参照してください。
そしてProject Oxfordの真骨頂ともいえるRESTのAPIはこのような構成です。もちろんRESTのAPIよりも事前に構成されたC# SDKのほうが使いやすいケースもあるでしょう。そのような場合にはお馴染みのドキュメントを出発点としてAPIを掘り下げられます。

私がやっていること

私は目下、Project Oxfordが提供する音声認識エンジンを使ってWebアプリを作っています。ここでは、この中で中核を担う音声認識部分のコード断片を紹介します。
まずは音声認識クライアントを生成してAPIキーを設定、そして送信する音声のフォーマット指定をおこないます。
  var speechClient = SpeechRecognitionServiceFactory.CreateDataClient(SpeechRecognitionMode.LongDictation, "en-us", API_KEY);
  speechClient.SendAudioFormat(SpeechAudioFormat.create16BitPCMFormat(8000));
SpeechRecognitionModeには短時間版と長時間(最大2分)版の二種類を設定できます。ここでは長時間版(LongDictation)を設定しました。
Project Oxfordが提供する音声認識エンジンで認識できる言語はいくつかあります。具体的にはこのページへ記載されているとおり「英語(US)、英語(英国)、ドイツ語、スペイン語、フランス語、イタリア語、中国語」です。ここでは英語(US)を指定しました。
APIキーは2015年11月まではMicrosoft Azureの管理画面から発行したものを利用していました。この手順はごく最近(2015年12月上旬?)に変わり、https://www.projectoxford.ai/Subscription/Indexへとアクセスして必要なAPIキーを発行するようになりました(図1)。
図1 保持しているProject Oxfordライセンスの一覧
このサイト上から残り利用可能なAPI呼び出し回数なども確認できるようになりました。
さて、コードに戻ります。
音声認識クライアントの初期化を完了したら、続いていくつかコールバックを仕込みます。
音声認識においては
  • 部分結果(認識途中の候補データ)
  • 最終結果(認識完了時の結果データ)
が大切です。最終結果だけを使うケースもありますが、今回は「音声認識実行中であり、何かしらの中間結果が得られている」ことを呼び出し側で判断したかったので次のように両方を利用しています。
  speechClient.OnPartialResponseReceived += async (sender, e) =>
  {
      await SendCommandToClient(new JsonCmd { Command = "partial-result", Parameters = e.PartialResult });
  };
  speechClient.OnResponseReceived += async (sender, e) =>
  {
      var result = e.PhraseResponse.Results.FirstOrDefault();
      if (result == null)
      {
          return;
      }
      var resultObj = new { text = result.MaskedInverseTextNormalizationResult };
      // ...
  };
OnPartialResponseReceivedで得られるのが途中結果、OnResponseReceivedで得られるのが最終結果です。
ここでは最終結果で渡される結果オブジェクト内のMaskedInverseTextNormalizationResultを読み出しています。これは、不適切なワード(いわゆる4-letter wordsなど)を****とマスクした状態で格納したものです。InverseTextNormalizationResultには認識結果がそのまま格納されます。
基本的に音声認識に関わるコードはこれだけです。これに加えて実際にはWebSocket経由でオーディオストリームを受け取って右から左へ流す仕組みや、不要の際に流れてきたデータを一時的に音声認識サーバへ流さず捨てる「ミュート」機能などを持ちますが、根っこの部分はこれだけです。

クロスプラットフォームでの音声認識API利用

音声認識APIは前述のようにWeb版(REST版)のみならずWindows版Android版、iOS版も提供しています。個人的にはWeb版(Rest版)ですべてのプラットフォームをカバーできるならばそれでよかったのですが、この場合に大きな壁となるのがiOSです。
iOSでは残念ながらiOS(Mobile Safari)のWebRTCサポートは弱く、音声キャプチャの機能がいまだに(iOS 9.2時点)存在しません*4
iOS側のサポート状況が改善するのを待つよりは普通にネイティブアプリで組んだほうが良い結果となりそうなので、目下Xamarinを通じてWindows Phone(Windows 10 Mobile)、iOS、Androidで共通利用できるラッパーライブラリを書いているところです。
こういうところでXamarinの楽しさが活きますね!
[*4] BowserというiOS向けのWebRTC機能組み込みWebブラウザを使えばゴリ押し利用できるのですが、いかんせん実験的なWebブラウザで出来がイマイチなので常用に耐えるものではありません。iOS版Firefoxでの音声キャプチャサポートはよ

ASP.NETに関わる部分

今回は音声認識結果をもとに遊ぶ簡単なゲームを作り、そのなかではVS 2015上でASP.NET 5のテンプレを使ってコードを書いてみました。
データの保存にはEF7(Entity Framework 7)を試しに使っているのですけれど、インデックスを張るためのAttributeを探したところなくなったようで難儀しました。結局、EF7では基本的にデータベースの細かな部分をすべてプログラム側コード(EF7の場合はC#)で完結するのではなく、適宜DDLを自前で書くのが良いという思想だと解釈して自分でインデックスをぽちぽちと張るようにしました。
ASP.NET 5系のロードマップ上でEF7自体に大きな手が入る場面はこの先なさそう&これはこれで良いと感じているのですが、EF7としてのプラクティス集(DOs and DON'Ts)が欲しいなと感じたりもしましたとさ。
あっ、Microsoft Azure Web Apps+ASP.NET系の環境でWebSocketを利用する場合には、AzureのPortal上からWebSocket利用オプションを有効にするのを忘れないようにしましょう。私はこれで割とハマりました。

まとめ

Project Oxfordすごいぞい楽しいぞいという話でした。
メインで紹介した音声認識系以外にも楽しい技術がいっぱいなので順次さわっていきたいところです。
明日のMS技術Advent Calendar担当はredwarriorさんです。

4 件のコメント:

  1. こんにちは。UnityでクロスプラットフォームのTTSができないか調べていて、こちらにたどり着きました。UE4の記事に「Unity」についても書いてあったのでご存知だと思うのですが、Project Oxford Speech APIを使えばC#(.NET3.5相当)でMac, iPhone, Androidで動作するTTSは作れそうでしょうか?何かヒントを頂ければ幸いです。またネットでもProject Oxford Speechの利用についてあまり情報が見つからないので、相談できそうな人たちが集まるイベントなどご存知でしたら教えていただけると助かります。宜しくお願いします。

    返信削除
    返信
    1. こんにちは、コメントありがとうございます。

      Speech APIの本体は、私が調べていた時点では大きく2つに分かれていました。
      Windows用のものと非Windows(Android/iOS/HTML5)用のものです。

      Windows用のものは、Windows 10が提供するOS APIの存在を前提とするもので、たとえばネットにつながっていない状態でもTTS/STTを実現できる仕組みを持っていたと記憶しています。
      一方、Android/iOS向けのものはProject Oxford(現Microsoft Cognitive Services)へとクライアントライブラリからアクセスするか、またはRESTベースのAPIアクセス(HTML5の場合はこれのみ)をおこないます。

      興味をお持ちの仕組みは後者かと思いますので、後者についてもう少々続けます。

      Android/iOS上でUnityからMicrosoft Cognitive Servicesへアクセスする手法としては、大きく2つのものが考えられます。

      1. 本家ClientSDKを利用するUnity向けのネイティブライブラリを作成し、データ中継をおこなう
      https://github.com/Microsoft/ProjectOxford-ClientSDK にてAndroid、iOSそれぞれのSDKが配布されています。
      これのラッパをプラットフォームごとに作成・メンテすることで実現できるかと思います。
      注意点として、これらのSDKの中核部分はネイティブバイナリであり、ソースが公開されているわけではありません。
      また、残念ながらMac版は提供されていません。

      2. REST APIを叩く仕組みを自前で作ってAPIへアクセスする
      クライアントライブラリと比較していくらかの制約事項がありますが、REST APIを叩くC#の公式サンプルが以下URIにあるので参考になるかと思います。
      https://github.com/Microsoft/ProjectOxford-ClientSDK/blob/master/Speech/TextToSpeech/Samples-Http/CSharp/TTSProgram.cs
      私自身は試したことがありませんが、UnityのWWW向けに移植するのもさほど難しくはないでしょう(最低限の動作だけでなく、ちゃんと移植する際には https://www.microsoft.com/cognitive-services/en-us/speech-api/documentation/api-reference-rest/bingvoiceoutput のREST APIリファレンスが役に立つはずです)。

      > Project Oxford Speechの利用についてあまり情報が見つからないので
      この点については、前述のようにProject Oxfordが今年3月のbuild 2016イベントのタイミングでMicrosoft Cognitive Servicesへとブランド変更されたことが一因かもしれません。
      依然として情報が少ないには違いありませんが、公式ドキュメントはずいぶん整っていますし、今後はこちらの名前で探したほうが情報を見つけやすいかも、と思います。

      > 相談できそうな人たちが集まるイベントなど
      コミュニティのエリアとしてはJapan Azure User Group (JAZUG) https://jazug.doorkeeper.jp/ が近いと思いますが、Project Oxford / Microsoft Cognitive Servicesは少々立ち位置が特殊(Bing系に統合されたこともあり)なので今のところあまり話題にはなっていないと認識しています。
      今月後半に開催される、build 2016の姉妹イベントであるde:code 2016では「有能な AI アシスタントを手に入れる! Microsoft Cognitive Services 入門」というセッションがおこなわれるようです:
      https://www.microsoft.com/ja-jp/events/decode/2016/session.aspx#DBP_018
      この場で講師の方に質問をぶつけてみる、というのが正攻法だと思います(このイベント、参加費が結構するのですが、もし参加される予定があれば...)。

      削除
    2. たくさんの有益な情報を大変ありがとうございます。丁寧にまとめられた話に感服しました。教えていただいたREST APIを叩く方法で頑張ってみようと思います。親切に対応してくださり本当にありがとうございました。

      削除
  2. このコメントは投稿者によって削除されました。

    返信削除