HoloLens (第 1 世代) と Azure 303: 自然言語の理解 (LUIS)
Note
Mixed Reality Academy のチュートリアルは、HoloLens (第 1 世代) と Mixed Reality イマーシブ ヘッドセットを念頭に置いて編成されています。 そのため、それらのデバイスの開発に関するガイダンスを引き続き探している開発者のために、これらのチュートリアルをそのまま残しておくことが重要だと考えています。 これらのチュートリアルが、HoloLens 2 に使用されている最新のツールセットや操作に更新されることは "ありません"。 これらは、サポートされているデバイス上で継続して動作するように、保守されます。 今後、HoloLens 2 の開発方法を説明する新しいチュートリアルが公開される予定です。 この通知は、それらのチュートリアルが投稿されたときにリンクと共に更新されます。
このコースでは、Language Understanding API で Azure Cognitive Services を使用して Mixed Reality アプリケーションに Language Understanding を統合する方法について説明します。
Language Understanding (LUIS) は Microsoft Azure サービスです。このサービスにより、アプリケーションは、ユーザーが必要とするものを抽出するなどして、ユーザーの入力を独自の言葉で除外することができます。 これは機械学習を通じて実現されます。機械学習では、入力情報を認識して学習した後、詳細な関連情報を返信できます。 詳細については、Azure Language Understanding (LUIS) のページを参照してください。
このコースを修了すると、次のことができる Mixed Reality イマーシブ ヘッドセット アプリケーションを手に入れることができます。
- イマーシブ ヘッドセットに接続されているマイクを使用して、ユーザー入力音声をキャプチャします。
- キャプチャしたディクテーションを Azure Language Understanding Intelligent Service (LUIS) に送信します。
- LUIS では、送信情報から意味を抽出して分析し、ユーザーの要求の意図を判断しようとします。
開発には、ユーザーが音声を使用したり視線入力してシーン内のオブジェクトのサイズと色を変更できるアプリの作成が含まれます。 モーション コントローラーの使用については説明しません。
お客様のアプリケーションで、結果をどのようにデザインと統合するかは、お客様次第です。 このコースは、Azure のサービスを Unity プロジェクトに統合する方法を学べることを目的としています。 このコースで得られた知識を使用して、ご自分の Mixed Reality アプリケーションを強化しましょう。
LUIS を複数回トレーニングできるように準備します。これについては、第 12 章で説明します。 LUIS がトレーニングされると、より多くの結果が得られます。
デバイス サポート
コース | HoloLens | イマーシブ ヘッドセット |
---|---|---|
MR と Azure 303: 自然言語の理解 (LUIS) | ✔️ | ✔️ |
Note
このコースは主に Windows Mixed Reality イマーシブ(VR)ヘッドセットに焦点を当てていますが、このコースで学んだことを Microsoft HoloLens にも応用できます。 このコースに取り組む過程で、HoloLens をサポートするために採用する必要のある変更に関するノートが表示されます。 HoloLens を使用すると、音声キャプチャ中に反響音が生じることがあります。
前提条件
Note
このチュートリアルは、Unity と C# の基本的な使用経験がある開発者を対象としています。 また、このドキュメント内の前提条件や文章による説明は、執筆時 (2018 年 5 月) にテストおよび検証された内容であることをご了承ください。 「ツールのインストール」の記事に記載されているように、最新のソフトウェアを自由に使用できます。ただし、このコースの情報は、以下に記載されているものよりも新しいソフトウェアで見つかったものと完全に一致するとは限りません。
このコースでは、次のハードウェアとソフトウェアをお勧めします。
- イマーシブ (VR) ヘッドセットの開発に必要な Windows Mixed Reality と互換性のある開発用 PC
- 開発者モードが有効になっている Windows 10 Fall Creators Update (またはそれ以降)
- 最新の Windows 10 SDK
- Unity 2017.4
- Visual Studio 2017
- 開発者モードが有効になっている Windows Mixed Reality イマーシブ (VR) ヘッドセットまたは Microsoft HoloLens
- 内蔵マイク付きヘッドホンのセット (ヘッドセットにマイクとスピーカーが組み込まれていない場合)
- Azure の設定とデータ取得のためのインターネット アクセス
開始する前に
このプロジェクトをビルドする際の問題を避けるために、このチュートリアルで紹介するプロジェクトをルートまたはルートに近いフォルダーに作成することを強くお勧めします (フォルダー パスが長いと、ビルド時に問題が発生する可能性があります)。
コンピューターでディクテーションを有効にするには、[Windows の設定] > [プライバシー>音声]、[手描き入力]、[入力] の順にに移動しボタンを押音声サービスを表示し、候補を入力します。
このチュートリアルのコードを使用すると、コンピューターに設定されている既定のマイク デバイスから録音できます。 既定のマイク デバイスが、音声をキャプチャするために使用するものとして設定されていることを確認します。
ヘッドセットにマイクが内蔵されている場合、Mixed Reality ポータルの設定で [ヘッドセット着用時はヘッドセットのマイクに切り替える] オプションがオンになっていることを確認します。
第 1 章 – Azure portal を設定する
Azure で Language Understanding サービスを使用するには、アプリケーションで使用できるようにサービスのインスタンスを構成する必要があります。
Azure Portal にログインします。
Note
まだ Azure アカウントをお持ちでない方は、作成する必要があります。 このチュートリアルを教室やラボで受講している場合は、インストラクターや監督者に新しいアカウントの設定方法を質問してください。
ログインしたら、左上隅にある[新規作成] をクリックして、Language Understanding を検索し、Enter キーを押します。
Note
新しいポータルでは、[新規作成] という文字列が [リソースの作成] に置き換えられることがあります。
右側の新しいページには、Language Understanding サービスの説明が表示されます。 このページの左下にある [作成] ボタンをクリックすると、このサービスのインスタンスが作成されます。
[作成] をクリックしたら、次のようにします。
このサービス インスタンスに任意の名前を付けて入力します。
サブスクリプションを選択します。
適切な [価格レベル] を選択します。これが初めて作成する LUIS Service の場合は、無料レベル (F0 という名前) を使用できるはずです。 無料の割り当て分でもこのコースには十分です。
[リソース グループ] を選択するか、新規に作成します。 リソース グループは、Azure アセットのコレクションの監視、アクセス制御、プロビジョニング、課金管理を行う方法を提供します。 共通のリソース グループで、1 つのプロジェクト (たとえば、これらのコースなど) に関連するすべての Azure サービスを保持することをお勧めします。
Azure リソース グループの詳細については、リソース グループに関する記事を参照してください。
リソース グループの [場所] を決定します (新しいリソース グループを作成する場合)。 この場所は、アプリケーションが実行されるリージョン内にすることが理想的です。 一部の Azure アセットは、特定のリージョンでしか利用できません。
またお客様は、本サービスに適用されるご契約条件を理解していることを確認する必要があります。
[作成] を選択します
[作成] をクリックしたら、サービスが作成されるのを待つ必要があります。これには 1 分ほどかかることがあります。
サービス インスタンスが作成されると、ポータルに通知が表示されます。
通知をクリックして、新しいサービス インスタンスを確認します。
通知の[リソースに移動]ボタンをクリックして、新しいサービスインスタンスを探します。 新しい LUIS サービス インスタンスが表示されます。
このチュートリアルでは、アプリケーションがサービスの呼び出しを行う必要があります。これは、サービスのサブスクリプション キーを使用して実行されます。
LUIS API サービスの [クイック スタート] ページで、最初の手順の [キーを取得する] に移動して、[キー] をクリックします (サービスのナビゲーション メニューにある鍵のアイコンで示された青いハイパーリンクの [キー] をクリックして、これを行うこともできます)。 これにより、サービスの "キー" が表示されます。
表示されているキーの 1 つをコピーします。これは、プロジェクトの後半で必要になります。
[サービス] ページで、[Language Understanding ポータル] をクリックして、LUIS アプリ内で新しいサービスの作成に使用する Web ページにリダイレクトします。
第 2 章 – Language Understanding ポータル
このセクションでは、LUIS ポータルで LUIS アプリを作成する方法について説明します。
重要
この章では "エンティティ"、"意図"、および "発話" を設定しますが、これは LUIS サービス構築の最初の手順にすぎないことに注意してください。サービスを何度も再トレーニングして、より正確なものにする必要もあります。 サービスの再トレーニングについては、このコースの最後の章で説明されています。完了していることを確認してください。
Language Understanding ポータルにアクセスしたら、Azure portal と同じ資格情報を使用してログインすることが必要な場合があります (まだログインしていない場合)。
LUIS を初めて使用する場合は、[ようこそ] ページの一番下までスクロールして [LUIS アプリの作成] ボタンを見つけてクリックする必要があります。
ログインしたら、[マイ アプリ] をクリックします (現在このセクションにいない場合)。 次に [新しいアプリの作成] をクリックします。
アプリに名前を付けます。
アプリで英語以外の言語を認識する場合は、[カルチャ] を適切な言語に変更する必要があります。
ここでは、新しい LUIS アプリの説明を追加することもできます。
[完了] をクリックすると、新しいLUISアプリケーションの [ビルド] ページが表示されます。
ここで理解しておくべき重要な概念がいくつかあります。
- "意図" は、ユーザーからのクエリに従って呼び出されるメソッドを表します。 "意図" には、1 つまたは複数の "エンティティ" を含めることができます。
- "エンティティ" は、"意図" に関連する情報を記述するクエリのコンポーネントです。
- "発話" は、開発者によって提供されるクエリの例であり、自身をトレーニングするために LUIS が使用します。
これらの概念をはっきり理解できていなくても問題ありません。この章ではさらに詳しく説明します。
最初に、このコースを構築するために必要な "エンティティ" を作成します。
ページの左側にある [エンティティ] をクリックし、[新しいエンティティの作成] をクリックします。
新しいエンティティに「色」という名前を付け、その種類を [シンプル] に設定して [完了] を押します。
このプロセスを繰り返して、次の名前のシンプルなエンティティをあと 3 つ作成します。
- アップサイズ
- ダウンサイズ
- ターゲット
結果は次の図のようになります。
この時点で、 インテントの作成を開始できます。
警告
"None" という意図は削除しないでください。
ページの左側にある [インテント] をクリックし、[新しいエンティティの作成] をクリックします。
新しい Intent ChangeObjectColor を呼び出します。
重要
この意図の名前は、このコースの後半でコード内で使用されます。したがって、最適な結果を得るために、この名前を指定されたとおりに使用してください。
名前を確認すると、インテント ページにリダイレクトされます。
5 つ以上の異なる "発話" を入力するよう求めるテキスト ボックスが表示されます。
Note
すべての発話は LUIS によって小文字に変換されます。
- (現在は "5 つくらいの例を入力してください..." というテキストが表示されている) 上部のテキスト ボックスに次の発話を入力して、Enter キーを押します。
The color of the cylinder must be red
その新しい発話が、下の一覧に表示されます。
同じ手順を繰り返して、次の 6 つの発話を入力します。
make the cube black
make the cylinder color white
change the sphere to red
change it to green
make this yellow
change the color of this object to blue
作成した発話ごとに、LUIS でエンティティとして使用する単語を識別する必要があります。 この例では、すべての色に "色" エンティティのラベルを、ターゲットへの参照になる可能性があるものすべてに "ターゲット" エンティティのラベルを付ける必要があります。
これを行うために、最初の発話の "円柱" という単語をクリックして "ターゲット" を選択してみてください。
次に、最初の発話の "赤" という単語をクリックして、"色" を選択します。
次の行にもラベルを付けます。ここで、 キューブはターゲットにする必要があり、黒は色にする必要があります。 具体的でないターゲットの種類も利用できるように、提供している例では "これ"、"それ"、"このオブジェクト" などの語も使用しています。
すべての発話がラベル付きのエンティティを持つようになるまで、上記の手順を繰り返します。 ヘルプが必要な場合は、次の図を参照してください。
ヒント
エンティティ ラベルを付ける単語を選択するときは:
- 単語が 1 つの場合は、クリックするだけです。
- 2 つ以上の単語のセットについては、セットの先頭と末尾をクリックします。
Note
[トークン ビュー] トグルボタンを使用して、エンティティ ビューとトークン ビューを切り替えることができます。
次の図は、エンティティ ビューとトークン ビューのそれぞれに表示された結果を示しています。
この時点で、ページの右上にある [トレーニング] ボタンを押して、小さな丸のインジケーターが緑色になるまで待ちます。 これは、この意図を認識するために LUIS のトレーニングが正常に行われたことを示します。
この演習では、 target、upsize、およびdownsize のエンティティを使用して、 ChangeObjectSizeという新しいインテントを作成します。
前の意図と同じ手順に従って、"サイズ" の変更に関する次の 8 つの発話を入力します。
increase the dimensions of that reduce the size of this i want the sphere smaller make the cylinder bigger size down the sphere size up the cube decrease the size of that object increase the size of this object
結果は次の図のようになります。
ChangeObjectColor と ChangeObjectSize の両方のインテントの作成とトレーニングが完了したら、ページの上部にある [発行] ボタンをクリックします。
[発行] ページで、LUIS アプリを完成させ発行して、コードからアクセスできるようにします。
[発行先] ドロップダウンを [運用環境] に設定します。
[タイム ゾーン] を、使用する地域のタイム ゾーンに設定します。
[予測されるすべての意図スコアを含める] チェック ボックスをオンにします。
[運用スロットに発行] をクリックします。
[リソースとキー] セクションで、次の手順を実行します。
- Azure Portal でサービス インスタンスに設定するリージョンを選択します。
- 次の Starter_Key 要素があることがわかりますが、無視します。
- [キーの追加] をクリックし、サービス インスタンスを作成するときに Azure Portal で取得した "キー" を入力します。 Azure と LUIS ポータルが同じユーザーにログインしている場合は、[テナント名]、[サブスクリプション名]、および使用する [キー] のドロップダウン メニューが表示されます (Azure portal で以前に指定したものと同じ名前になります)。
重要
[エンドポイント] には、入力したキーに対応するエンドポイントが表示されています。直後にコードで使用するので、コピーしておきます。
第 3 章 – Unity プロジェクトを設定する
次に示すのは、Mixed Reality で開発するための一般的な設定であり、他のプロジェクトのテンプレートとしても適しています。
Unity を開き、[新規] をクリックします。
Unity プロジェクトに名前を付ける必要があります。MR_LUIS を挿入します。 プロジェクトの種類が [3D] に設定されていることを確認します。 [場所] を適切な場所に設定します (ルート ディレクトリに近い方が適しています)。 [Create project]\(プロジェクトの作成\) をクリックします。
Unity を開いた状態で、既定のスクリプト エディターが Visual Studio に設定されているかどうか確認することをお勧めします。 [編集] > [基本設定] に移動し、新しいウィンドウで [外部ツール] に移動します。 [外部スクリプト エディター] を [Visual Studio 2017] に変更します。 [環境設定] ウィンドウを閉じます。
次に、[ファイル] > [ビルド設定] で、[プラットフォームの切り替え] ボタンをクリックして、プラットフォームを [ユニバーサル Windows プラットフォーム] に切り替えます。
[ファイル] > [ビルド設定] に移動して、次を確認します。
[Target Device] (ターゲット デバイス) が [Any Device] (任意のデバイス) に設定されている
Microsoft HoloLens の場合は、[ターゲット デバイス] を [HoloLens] に設定します。
[Build Type] (ビルドの種類) が [D3D] に設定されている
[SDK] が [最新のインストール] に設定されている。
[Visual Studio Version] (Visual Studio のバージョン) が [Latest installed] (最新のインストール) に設定されている
[Build and Run] (ビルドと実行) が [Local Machine] (ローカル マシン) に設定されている
シーンを保存し、ビルドに追加します。
これを行うには、[Add Open Scenes] (開いているシーンを追加) を選択します。 保存ウィンドウが表示されます。
これと、今後のシーン用の新しいフォルダーを作成し、[新しいフォルダー] ボタンを選択して、新しいフォルダーを作成し、「Scenes」という名前を付けます。
新しく作成した Scenes フォルダーを開き、[ファイル名] テキスト フィールドに「FaceRecScene」と入力して [保存] をクリックします。
[ビルド設定] の残りの設定は、ここでは既定値のままにしておきます。
Build Settings (ビルド設定) ウィンドウで、[プレーヤー設定] ボタンをクリックすると、"インスペクター" が配置されているスペースに関連パネルが表示されます。
このパネルでは、いくつかの設定を確認する必要があります。
[Other Settings] (その他の設定) タブで、次の内容を確認します。
[Scripting Runtime Version] (スクリプト ランタイムのバージョン) が [Stable] (安定) (.NET 3.5 と同等) である。
[スクリプト バックエンド] が [.NET] である。
[API Compatibility Level]\(API 互換性レベル\) が [.NET 4.6] である。
[Publishing Settings]\(公開設定\) タブ内の [Capabilities]\(機能\) で、次の内容を確認します。
InternetClient
マイク
さらに、パネルの下にある [XR Settings]\(XR 設定\) ([Publish Settings]\(公開設定\) の下) で、[Virtual Reality Supported]\(Virtual Reality サポート\) をオンにし、Windows Mixed Reality SDK が追加されていることを確認します。
Build の設定に戻ります Unity C# Projects はグレー表示されなくなりました。この横にあるチェックボックスをオンにします。
[ビルド設定] ウィンドウを閉じます。
シーンとプロジェクトを保存します ([FILE] (ファイル) > [SAVE SCENE / FILE] (シーン/ファイルの保存) > [SAVE PROJECT] (プロジェクトの保存))。
第 4 章 – シーンを作成する
重要
このコースの "Unity のセットアップ" コンポーネントをスキップして、そのままコードに進みたい場合は、この .unitypackage をダウンロードし、これをカスタム パッケージとしてプロジェクトにインポートした後で第 5 章から続けてください。
[階層パネル]の何もない領域を右クリックし、[3D オブジェクト]、[平面] の順に選択して追加します。
[階層] 内で右クリックしてさらにオブジェクトを作成する場合、最後のオブジェクトがまだ選択されていると、選択したオブジェクトが新しいオブジェクトの親になることに注意してください。 これを回避するには、[階層] 内の何もない領域で左クリックしてから右クリックします。
上記の手順を繰り返して、次のオブジェクトを追加します。
- 球
- シリンダー
- Cube
- 3D テキスト
結果のシーン階層は次の図のようになります。
メイン カメラを左クリックして選択します。インスペクター パネルを見て、すべてのコンポーネントを含む Camera オブジェクトが表示されます。
インスペクター パネルの一番下にある [コンポーネントの追加] ボタンを クリックします。
上の図のように、"オーディオ ソース" という名前のコンポーネントを検索します。
[メイン カメラ] の [変換] コンポーネントが (0,0,0) に設定されていることも確認してください。このように設定するには、[カメラ] の [変換] コンポーネントの横にある歯車のアイコンを押して [リセット] を選択します。 [変換] コンポーネントは次のようになります。
- [位置] は 0, 0, 0 に設定されます。
- [回転] は 0, 0, 0 に設定されます。
Note
Microsoft HoloLens の場合、[メイン カメラ]上にある [カメラ] コンポーネントの一部である以下も変更する必要があります。
- [クリア フラグ]: 単色。
- [背景] "黒、アルファ 0" – [Hex カラー]: #00000000
[平面] を左クリックして選択します。 [インスペクター] パネルで、[変換] コンポーネントに次の値を設定します。
X 軸 Y 軸 Z 軸 0 -1 0 [球] を左クリックして選択します。 [インスペクター] パネルで、[変換] コンポーネントに次の値を設定します。
X 軸 Y 軸 Z 軸 2 1 2 [円柱] を左クリックして選択します。 [インスペクター] パネルで、[変換] コンポーネントに次の値を設定します。
X 軸 Y 軸 Z 軸 -2 1 2 [立方体] を左クリックして選択します。 [インスペクター] パネルで、[変換] コンポーネントに次の値を設定します。
変換 - 位置
X | Y | Z |
---|---|---|
0 | 1 | 4 |
変換 - 回転
X | Y | Z |
---|---|---|
45 | 45 | 0 |
- [新しいテキスト] オブジェクトを左クリックして選択します。 [インスペクター] パネルで、[変換] コンポーネントに次の値を設定します。
変換 - 位置
X | Y | Z |
---|---|---|
-2 | 6 | 9 |
変換 - スケール
X | Y | Z |
---|---|---|
0.1 | 0.1 | 0.1 |
[テキスト メッシュ] コンポーネントの [フォント サイズ] を 50 に変更します。
Text Mesh オブジェクトの 名前をディク テーション テキスト に変更します。
階層パネルの構造は次のように表示されます。
最終的なシーンは次の図のようになります。
第 5 章 – MicrophoneManager クラスを作成する
最初に作成するスクリプトは、MicrophoneManager クラスです。 次に、LuisManager、Behaviours クラス、最後に Gaze クラスを作成します (各章で取り扱いますが、すべてをここで作成してもかまいません)。
MicrophoneManager クラスは次の責任を負います。
- ヘッドセットまたはコンピューターに接続されている録音デバイス (既定のものである方) を検出する。
- オーディオ (音声) をキャプチャし、ディクテーションを使用して文字列として保存する。
- 音声が一時停止したら、LuisManager クラスにディクテーションを送信する。
このクラスを作成するには、次の手順を実行します。
[プロジェクト] パネル内で右クリックして [作成] > [フォルダー] を選択します。 フォルダーに「Scripts」という名前を付けます。
作成した Scripts フォルダーをダブルクリックして開きます。 次に、そのフォルダー内で右クリックして、[作成] > [C# スクリプト] を選択します。 スクリプトに「MicrophoneManager」という名前を付けます。
MicrophoneManager をダブルクリックして、Visual Studio で開きます。
次の名前空間を ファイルの先頭に追加します。
using UnityEngine; using UnityEngine.Windows.Speech;
次に、MicrophoneManager クラス内に以下の変数を追加します。
public static MicrophoneManager instance; //help to access instance of this object private DictationRecognizer dictationRecognizer; //Component converting speech to text public TextMesh dictationText; //a UI object used to debug dictation result
ここで、Awake() メソッドと Start() メソッドのコードを追加する必要があります。 これらは、クラスの初期化時に呼び出されます。
private void Awake() { // allows this class instance to behave like a singleton instance = this; } void Start() { if (Microphone.devices.Length > 0) { StartCapturingAudio(); Debug.Log("Mic Detected"); } }
ここで、音声キャプチャを開始および停止し、その音声キャプチャをこの後の手順で作成する LuisManager クラスに渡すのにアプリが使用するメソッドが必要になります。
/// <summary> /// Start microphone capture, by providing the microphone as a continual audio source (looping), /// then initialise the DictationRecognizer, which will capture spoken words /// </summary> public void StartCapturingAudio() { if (dictationRecognizer == null) { dictationRecognizer = new DictationRecognizer { InitialSilenceTimeoutSeconds = 60, AutoSilenceTimeoutSeconds = 5 }; dictationRecognizer.DictationResult += DictationRecognizer_DictationResult; dictationRecognizer.DictationError += DictationRecognizer_DictationError; } dictationRecognizer.Start(); Debug.Log("Capturing Audio..."); } /// <summary> /// Stop microphone capture /// </summary> public void StopCapturingAudio() { dictationRecognizer.Stop(); Debug.Log("Stop Capturing Audio..."); }
音声が一時停止したときに呼び出される "ディクテーション ハンドラー" を追加します。 このメソッドは、ディクテーション テキストを LuisManager クラスに渡します。
/// <summary> /// This handler is called every time the Dictation detects a pause in the speech. /// This method will stop listening for audio, send a request to the LUIS service /// and then start listening again. /// </summary> private void DictationRecognizer_DictationResult(string dictationCaptured, ConfidenceLevel confidence) { StopCapturingAudio(); StartCoroutine(LuisManager.instance.SubmitRequestToLuis(dictationCaptured, StartCapturingAudio)); Debug.Log("Dictation: " + dictationCaptured); dictationText.text = dictationCaptured; } private void DictationRecognizer_DictationError(string error, int hresult) { Debug.Log("Dictation exception: " + error); }
重要
Update() メソッドは、このクラスでは使用しないので削除します。
Unity に戻る前に、必ず Visual Studio で変更を保存してください。
Note
この時点で、Unity エディターの [コンソール] パネルにエラーが表示されます。 これは、次の章で作成する LuisManager クラスがコードで参照されているためです。
第 6 章 – LUISManager クラスを作成する
次に、LuisManager クラスを作成します。このクラスは、Azure LUIS サービスの呼び出しを行います。
このクラスの目的は、MicrophoneManager クラスからディクテーション テキストを受け取り、分析のために Azure Language Understanding API に送信することです。
このクラスは、JSON 応答を逆シリアル化し、Behaviours クラスの適切なメソッドを呼び出してアクションをトリガーします。
このクラスを作成するには、次の手順を実行します。
Scripts フォルダーをダブルクリックして開きます。
[Scripts] フォルダー内で右クリックし、[Create] (作成) > [C# Script] (C# スクリプト) をクリックします。 スクリプトに「LuisManager」という名前を付けます。
スクリプトをダブルクリックして Visual Studio で開きます。
次の名前空間を ファイルの先頭に追加します。
using System; using System.Collections; using System.Collections.Generic; using System.IO; using UnityEngine; using UnityEngine.Networking;
まず、LuisManager クラスの内部 (同じスクリプト ファイル内、Start() メソッドの上) に、Azure からの逆シリアル化された JSON 応答を表す 3 つのクラスを作成します。
[Serializable] //this class represents the LUIS response public class AnalysedQuery { public TopScoringIntentData topScoringIntent; public EntityData[] entities; public string query; } // This class contains the Intent LUIS determines // to be the most likely [Serializable] public class TopScoringIntentData { public string intent; public float score; } // This class contains data for an Entity [Serializable] public class EntityData { public string entity; public string type; public int startIndex; public int endIndex; public float score; }
次に、LuisManager クラス内に以下の変数を追加します。
public static LuisManager instance; //Substitute the value of luis Endpoint with your own End Point string luisEndpoint = "https://westus.api.cognitive... add your endpoint from the Luis Portal";
必ず、ここで LUIS エンドポイントを配置してください (LUIS ポータルから取得します)。
Awake() メソッドのコードを追加する必要があります。 このメソッドは、クラスの初期化時に呼び出されます。
private void Awake() { // allows this class instance to behave like a singleton instance = this; }
次に、このアプリケーションが MicrophoneManager クラスから受信したディクテーションを LUIS に送信し、応答を受信して逆シリアル化するために使用するメソッドが必要になります。
意図の値と、関連付けられたエンティティが決定されると、意図したアクションをトリガーするために、これらが Behaviours クラスのインスタンスに渡されます。
/// <summary> /// Call LUIS to submit a dictation result. /// The done Action is called at the completion of the method. /// </summary> public IEnumerator SubmitRequestToLuis(string dictationResult, Action done) { string queryString = string.Concat(Uri.EscapeDataString(dictationResult)); using (UnityWebRequest unityWebRequest = UnityWebRequest.Get(luisEndpoint + queryString)) { yield return unityWebRequest.SendWebRequest(); if (unityWebRequest.isNetworkError || unityWebRequest.isHttpError) { Debug.Log(unityWebRequest.error); } else { try { AnalysedQuery analysedQuery = JsonUtility.FromJson<AnalysedQuery>(unityWebRequest.downloadHandler.text); //analyse the elements of the response AnalyseResponseElements(analysedQuery); } catch (Exception exception) { Debug.Log("Luis Request Exception Message: " + exception.Message); } } done(); yield return null; } }
結果の AnalysedQuery を読み取ってエンティティを決定する、AnalyseResponseElements() という名前の新しいメソッドを作成します。 これらのエンティティが決定されると、アクションで使用するために Behaviours クラスのインスタンスに渡されます。
private void AnalyseResponseElements(AnalysedQuery aQuery) { string topIntent = aQuery.topScoringIntent.intent; // Create a dictionary of entities associated with their type Dictionary<string, string> entityDic = new Dictionary<string, string>(); foreach (EntityData ed in aQuery.entities) { entityDic.Add(ed.type, ed.entity); } // Depending on the topmost recognized intent, read the entities name switch (aQuery.topScoringIntent.intent) { case "ChangeObjectColor": string targetForColor = null; string color = null; foreach (var pair in entityDic) { if (pair.Key == "target") { targetForColor = pair.Value; } else if (pair.Key == "color") { color = pair.Value; } } Behaviours.instance.ChangeTargetColor(targetForColor, color); break; case "ChangeObjectSize": string targetForSize = null; foreach (var pair in entityDic) { if (pair.Key == "target") { targetForSize = pair.Value; } } if (entityDic.ContainsKey("upsize") == true) { Behaviours.instance.UpSizeTarget(targetForSize); } else if (entityDic.ContainsKey("downsize") == true) { Behaviours.instance.DownSizeTarget(targetForSize); } break; } }
重要
Start() メソッドと Update() メソッドは、このクラスでは使用しないので削除します。
Unity に戻る前に、必ず Visual Studio で変更を保存してください。
Note
この時点で、Unity エディターの [コンソール] パネルにいくつかのエラーが表示されます。 これは、次の章で作成する Behaviours クラスがコードで参照されているためです。
第 7 章 – Behaviours クラスを作成する
Behaviours クラスは、LuisManager クラスによって提供されるエンティティを使用してアクションをトリガーします。
このクラスを作成するには、次の手順を実行します。
Scripts フォルダーをダブルクリックして開きます。
[Scripts] フォルダー内で右クリックし、[Create] (作成) > [C# Script] (C# スクリプト) をクリックします。 スクリプトに「Behaviours」という名前を付けます。
スクリプトをダブルクリックして Visual Studio で開きます。
次に、Behaviours クラス内に以下の変数を追加します。
public static Behaviours instance; // the following variables are references to possible targets public GameObject sphere; public GameObject cylinder; public GameObject cube; internal GameObject gazedTarget;
Awake() メソッドのコードを追加します。 このメソッドは、クラスの初期化時に呼び出されます。
void Awake() { // allows this class instance to behave like a singleton instance = this; }
次のメソッドは、どのオブジェクトがクエリのターゲットであるかを決定して適切なアクションをトリガーするために、(前に作成した) LuisManager クラスによって呼び出されます。
/// <summary> /// Changes the color of the target GameObject by providing the name of the object /// and the name of the color /// </summary> public void ChangeTargetColor(string targetName, string colorName) { GameObject foundTarget = FindTarget(targetName); if (foundTarget != null) { Debug.Log("Changing color " + colorName + " to target: " + foundTarget.name); switch (colorName) { case "blue": foundTarget.GetComponent<Renderer>().material.color = Color.blue; break; case "red": foundTarget.GetComponent<Renderer>().material.color = Color.red; break; case "yellow": foundTarget.GetComponent<Renderer>().material.color = Color.yellow; break; case "green": foundTarget.GetComponent<Renderer>().material.color = Color.green; break; case "white": foundTarget.GetComponent<Renderer>().material.color = Color.white; break; case "black": foundTarget.GetComponent<Renderer>().material.color = Color.black; break; } } } /// <summary> /// Reduces the size of the target GameObject by providing its name /// </summary> public void DownSizeTarget(string targetName) { GameObject foundTarget = FindTarget(targetName); foundTarget.transform.localScale -= new Vector3(0.5F, 0.5F, 0.5F); } /// <summary> /// Increases the size of the target GameObject by providing its name /// </summary> public void UpSizeTarget(string targetName) { GameObject foundTarget = FindTarget(targetName); foundTarget.transform.localScale += new Vector3(0.5F, 0.5F, 0.5F); }
どの GameObjects が現在の意図のターゲットであるかを決定するための FindTarget() メソッドを追加します。 このメソッドは、エンティティで明示的なターゲットが定義されていない場合、"視線の先にある" GameObject を既定でターゲットとします。
/// <summary> /// Determines which object reference is the target GameObject by providing its name /// </summary> private GameObject FindTarget(string name) { GameObject targetAsGO = null; switch (name) { case "sphere": targetAsGO = sphere; break; case "cylinder": targetAsGO = cylinder; break; case "cube": targetAsGO = cube; break; case "this": // as an example of target words that the user may use when looking at an object case "it": // as this is the default, these are not actually needed in this example case "that": default: // if the target name is none of those above, check if the user is looking at something if (gazedTarget != null) { targetAsGO = gazedTarget; } break; } return targetAsGO; }
重要
Start() メソッドと Update() メソッドは、このクラスでは使用しないので削除します。
Unity に戻る前に、必ず Visual Studio で変更を保存してください。
第 8 章 – Gaze クラスを作成する
このアプリを完成させるために必要な最後のクラスは、Gaze クラスです。 このクラスは、ユーザーの視覚フォーカスが現在捉えている GameObject への参照を更新します。
このクラスを作成するには、次の手順を実行します。
Scripts フォルダーをダブルクリックして開きます。
[Scripts] フォルダー内で右クリックし、[Create] (作成) > [C# Script] (C# スクリプト) をクリックします。 スクリプトに Gaze という名前を付けます。
スクリプトをダブルクリックして Visual Studio で開きます。
このクラスの次のコードを挿入します。
using UnityEngine; public class Gaze : MonoBehaviour { internal GameObject gazedObject; public float gazeMaxDistance = 300; void Update() { // Uses a raycast from the Main Camera to determine which object is gazed upon. Vector3 fwd = gameObject.transform.TransformDirection(Vector3.forward); Ray ray = new Ray(Camera.main.transform.position, fwd); RaycastHit hit; Debug.DrawRay(Camera.main.transform.position, fwd); if (Physics.Raycast(ray, out hit, gazeMaxDistance) && hit.collider != null) { if (gazedObject == null) { gazedObject = hit.transform.gameObject; // Set the gazedTarget in the Behaviours class Behaviours.instance.gazedTarget = gazedObject; } } else { ResetGaze(); } } // Turn the gaze off, reset the gazeObject in the Behaviours class. public void ResetGaze() { if (gazedObject != null) { Behaviours.instance.gazedTarget = null; gazedObject = null; } } }
Unity に戻る前に、必ず Visual Studio で変更を保存してください。
第 9 章 – シーンのセットアップの完了
シーンのセットアップを完了するには、[階層] パネルで、作成した各スクリプトを Scripts フォルダーから [メイン カメラ] オブジェクトにドラッグします。
メイン カメラを選択し、インスペクター パネルを見ると、アタッチした各スクリプトを確認できます。各スクリプトには、まだ設定されていないパラメーターがある場合があります。
これらのパラメーターを正しく設定するには、次の手順に従います。
MicrophoneManager については、次のように操作します。
- [階層] パネルから、[ディクテーション テキスト] オブジェクトを [ディクテーション テキスト] のパラメーター値ボックスにドラッグします。
Behaviours については、[階層] パネルから次のように操作します。
- [球] オブジェクトを [球] の参照ターゲット ボックスにドラッグします。
- [円柱] を [円柱] の参照ターゲット ボックスにドラッグします。
- [立方体] を [立方体] の参照ターゲット ボックスにドラッグします。
Gaze については、次のように操作します。
- [視線入力の最大距離] を 300 に設定します (まだ設定されていない場合)。
結果は次の図のようになります。
第 10 章 – Unity エディターでのテスト
シーンのセットアップが正しく実装されているかテストします。
次のことを確認してください。
- すべてのスクリプトが Main Camera オブジェクトにアタッチされています。
- Main Camera の [Inspector] (インスペクター) パネルのすべてのフィールドに適切な値が割り当てられています。
Unity エディターで [再生] ボタンを押します。 アプリは、アタッチ状態のイマーシブ ヘッドセット内で実行されている必要があります。
次のようないくつかの発話を試してみてください。
make the cylinder red change the cube to yellow I want the sphere blue make this to green change it to white
Note
既定のオーディオ デバイスの変更について Unity コンソールにエラーが表示される場合は、シーンが想定どおりに機能しない可能性があります。 これは、ヘッドセットにマイクが内蔵されている場合の、Mixed Reality ポータルにおける内蔵マイクの取り扱いが原因です。 このエラーが表示された場合は、シーンを停止してからもう一度開始するだけで、期待どおりに動作するはずです。
第 11 章 – UWP ソリューションをビルドしてサイドロードする
アプリケーションが Unity エディターで動作している状態を確認したら、ビルドしてデプロイする準備が整います。
ビルドするには、
[ファイル] > [保存] の順にクリックして現在のシーンを保存します。
[ファイル] > [ビルド設定] に移動します。
[Unity C# プロジェクト] チェック ボックスをオンにします (UWP プロジェクトが作成された後にコードを表示およびデバッグするのに便利です)。
[開いているシーンの追加] をクリックし、[ビルド] を クリックします。
ソリューションをビルドするフォルダーを選択するよう求めるプロンプトが表示されます。
BUILDS フォルダーを作成し、そのフォルダー内にお好みの適切な名前で別のフォルダーを作成します。
新しいフォルダーをクリックし、[フォルダーの選択] をクリックすると、その場所でビルドが開始されます。
Unity でビルドが完了すると (これには時間がかかる場合があります)、[エクスプローラー] ウィンドウでビルドの場所が開きます。
ローカル コンピューターにデプロイするには、以下の手順を実行します。
Visual Studio で、前の章で作成したソリューション ファイルを開きます。
[ソリューション プラットフォーム] で、[x86]、[ローカル コンピューター] を選択します。
[ソリューション構成] で、[デバッグ] を選択します。
Microsoft HoloLens の場合は、これを [リモート コンピューター] に設定した方が便利かもしれません。そうすると、お使いのコンピューターに縛られずに済みます。 ただし、次のことも行う必要があります。
- HoloLens の IP アドレス を把握します。これは、 Settings > ネットワークとインターネット > Wi-Fi > 詳細オプション内にあります。IPv4 は使用する必要があるアドレスです。
- Developer Mode が On; であることを確認します。これは、開発者向け Settings > Update および Security > にあります。
[ビルド] メニューの [ソリューションの配置] をクリックして、アプリケーションをお使いのコンピューターにサイドロードします。
インストールされたアプリの一覧にこのアプリが表示され、起動できる状態になります。
起動すると、"マイク" へのアクセスを認可するように求めるメッセージがアプリに表示されます。 "モーション コントローラー"、"音声入力"、または "キーボード" を使用して [はい] ボタンを押します。
第 12 章 – LUIS サービスの改善
重要
この章の内容は非常に重要であり、LUIS サービスの精度向上に役立つため、何度か繰り返すことが必要な場合があります。必ず完了してください。
LUIS によって提供される理解のレベルを向上させるためには、新しい発話をキャプチャし、それらを使用して LUIS アプリを再トレーニングする必要があります。
たとえば、 "増やす" や "アップサイズ" を理解するように LUIS をトレーニングした場合、"大きくする" のような言葉もアプリに理解させたいと考えるでしょう。
アプリケーションを数回使用すれば、話したすべての言葉が LUIS によって収集され、LUIS ポータルで使用できるようになります。
このリンクからポータル アプリケーションに移動し、ログインします。
Microsoft 資格情報でログインしたら、アプリの名前をクリックします。
ページの左側にある [エンドポイント発話の確認] ボタンをクリックします。
Mixed Reality アプリケーションによって LUIS に送信された発話の一覧が表示されます。
いくつかの "エンティティ" が強調表示されています。
強調表示された各単語にマウス ポインターを合わせると、各発話を確認し、正しく認識されたエンティティ、間違っているエンティティ、欠落しているエンティティを特定できます。
上の例では、"スペア" という単語がターゲットとして強調表示されているため、間違いを修正する必要があります。そのためには、マウスでこの単語をポイントして [ラベルの削除] をクリックします。
完全に間違っている発話が見つかった場合は、画面の右側にある [削除] ボタンを使用して削除できます。
または、発話が LUIS によって正しく解釈されたと思われる場合は、[調整された意図に追加] ボタンを使用してこの理解を有効にすることができます。
表示されている発話をすべて並べ替えたら、ページを再度読み込み、使用可能な発話がほかにないか確認してください。
アプリケーションの理解を向上させるために、このプロセスは可能な限り何度も繰り返す必要があります。
楽しんでください!
完成した LUIS 統合アプリケーション
おめでとうございます。Azure Language Understanding Intelligence Service を活用して、ユーザーの言葉を理解し、その情報に対して行動する Mixed Reality アプリを構築しました。
ボーナス演習
演習 1
このアプリケーションの使用中、床オブジェクトを視線で捉えてその色を変更するように指示すると、変更が行われます。 アプリケーションが床の色を変更するのをやめさせるにはどうすればよいですか?
演習 2
LUIS とアプリの機能を拡張して、シーン内のオブジェクトに対する機能を追加してみてください。たとえば、ユーザーの発声内容に応じて、視線入力のヒット ポイントに新しいオブジェクトを作成し、それらのオブジェクトを現在のシーン オブジェクトと共に既存のコマンドで操作できるようにする機能などです。