予測の基礎

トレーニング済み機械学習モデルをクラウドでホストし、Cloud ML 予測サービスを使用して、新しいデータのターゲット値を推測できます。このページでは、モデルのホスティングと予測について説明し、プロジェクトで留意すべき考慮事項を紹介します。

仕組み

Cloud ML Engine 予測サービスでは、クラウド内のコンピューティング リソースを管理してモデルを実行します。ユーザーはモデルからの予測をリクエストして、予測されたターゲット値を取得できます。クラウドで予測を行うための準備プロセスを次に示します。

  1. トレーニング アプリケーションの一環として、SavedModel を使用してモデルをエクスポートします。

  2. Cloud ML Engine でモデルリソースを作成し、保存したモデルからモデル バージョンを作成します。

  3. 予測に使用する入力データをフォーマットし、オンライン予測またはバッチ予測をリクエストします。

  4. オンライン予測を使用する場合、予測サービスは保存済みモデルを実行し、リクエストされた予測を呼び出しのレスポンス メッセージとして返します。

    • モデル バージョンは、モデルの作成時に指定したリージョンにデプロイされています。
    • 一般に、定期的に使用するモデル バージョンで予測が行われるよう準備されていますが、常にそうなる保証はありません。

    バッチ予測を使用する場合のプロセスはもう少し複雑になります。

    1. 予測サービスは、ジョブを実行するためのリソースを割り当てます。これには、1 つまたは複数の予測ノードが含まれます。

    2. サービスは、割り当てた各ノードで TensorFlow グラフを復元します。

    3. 予測サービスは、割り当てたノード全体に入力データを分散します。

    4. 各ノードはグラフを実行し、指定された Google Cloud Storage の場所に予測を保存します。

    5. すべての入力データが処理されると、予測サービスはジョブをシャットダウンし、割り当てていたリソースを解放します。

モデルのデプロイ

Cloud ML Engine ではモデルをホストできるため、クラウド内のモデルから予測を取得できます。保存したモデルをホスティングするプロセスをデプロイといいます。予測サービスでは、モデルを大規模に実行するために必要なインフラストラクチャを管理し、オンラインおよびバッチ予測リクエストにそれを使用できるようにします。このセクションでは、モデルのデプロイについて説明します。

モデルとバージョンについて

Cloud ML Engine は、「モデル」と「バージョン」と呼ばれるリソースを使用して、トレーニング済みのモデルを編成します。モデルとは、機械学習ソリューションのことです。たとえば、米国国勢調査の機械学習モデルに関する作業をすべて格納するために、census というモデルを作成するとします。census という名前で作成するエンティティは、機械学習モデルを実際に実装するコンテナで、バージョンと呼ばれます。

機械学習モデルの開発は反復的なプロセスです。そのため、Cloud Machine Engine のリソース パラダイムは、各機械学習モデルの複数のバージョンを作成することを想定して設定されています。この「モデル」と「バージョン」という用語が混乱を招くことがありますが、Cloud ML Engine のモデルリソースのひとつが、単独の機械学習モデルに当たるのではありません。Cloud ML Engine で使われるモデルとは、機械学習モデルの複数のバージョンを格納するコンテナに相当します。

バージョンには何が含まれるか

Cloud ML Engine にモデル バージョンとしてデプロイする「モデル」は、TensorFlow の SavedModel です。トレーナーに SavedModel をエクスポートします。SavedModel の使用する署名が serving_default に設定されている限り、モデルのトレーニング場所は問いません。もちろん、クラウドで Cloud ML Engine を使用することも可能です。

バージョン間のバリエーション

1 つのモデルリソースに対して、任意のバージョンを作成できます。つまり、バージョン間で機械学習モデルを完全に変更しても、同じモデルリソースをそのまま使用できます。モデルは、状況にかなうように任意に使用できる構成ツールにすぎません。

本番環境にバージョンを設定した後は特に、モデル バージョン間で入力と出力が同じになるようにするのが一般的です。それにより、モデルまわりに構築したその他のアプリケーション構造を変更する必要なく、バージョンを切り替えることができます。また、新しいバージョンを既存のデータで簡単にテストすることもできます。

デフォルトのバージョン

モデルのバージョンが 1 つでもあれば、そのモデルにはデフォルトのバージョンが存在します。デフォルトは、最初のバージョンの作成時に設定されます。モデル名だけを指定して予測をリクエストした場合、Cloud ML Engine ではそのモデルのデフォルトのバージョンが使用されます。

留意すべき点は、サービスでデフォルトのバージョンが自動的に設定されるのは、最初のバージョンを作成するときだけです。後続のバージョンを手動でデフォルトにするには、projects.models.versions.setDefault を呼び出します。これは gcloud ml-engine versions set-default として公開されているほか、Google Cloud Platform Console の [モデルの詳細] ページの [バージョン] リストのオプションにもあります([モデルの詳細] ページにアクセスするには、[モデル] ページのモデルリストでモデルをクリックします)。これにより、たとえば安定したデフォルトのバージョンを本番環境で予測に使用しながら、新しいバージョンのテスト用に別のモデルリソースを作成せずにテストを実行できます。

モデルとバージョンの命名

モデル名とバージョン名は次のようにする必要があります。

  • 文字(大文字と小文字を併用、大文字と小文字は区別される)、数字、およびアンダースコアのみ。
  • 文字から始まる。
  • 128 文字以下。
  • 特定のプロジェクト(モデルの場合)またはモデル(バージョンの場合)内で一意である。

これらの技術的な要件以外に名前のルールはありませんが、ここにいくつかのおすすめの方法を示します。

  • モデル名はわかりやすく、区別しやすくする必要があります。ログやレポートで、多数の名前のリストから見つけなければならない場合があるからです。
  • バージョン名は短くシンプルにしておくのがベストです。たとえば、リソースのリストで「2017_01_29T13_54_58」よりも「v1」を識別する方が簡単です。

モデルとバージョンの制限

Cloud ML Engine の割り当てポリシーでは、プロジェクトあたり 100 個にモデル数が制限され、バージョンの合計数(すべてのモデル間の総数)は 200 に制限されます。

モデルのデプロイ パラメータ

Cloud ML Engine は、モデル バージョンを作成するために情報を必要とします。ユーザーが設定できるオプションもいくつかあります。このセクションでは、両方のタイプのパラメータについて説明します。これらのパラメータは、Version オブジェクトで定義するか、またはそのつど gcloud ml-engine versions create コマンドに追加します。

バージョン名
新しいバージョンの名前。モデル内の他のバージョン名との間で一意にしてください。
説明
バージョンの説明を指定することができます。現時点では、説明は API でバージョン情報を取得する場合にのみ表示されます。gcloud コマンドライン ツールでも Google Cloud Platform Console でも説明は表示されません。
デプロイ URI
SavedModel が格納されている Cloud Storage の場所の URI を指定する必要があります。Cloud ML Engine は、この場所からモデルを取得してデプロイします。このパラメータは、gcloud ml-engine versions create コマンドで --origin と呼ばれます。
ランタイム バージョン
Cloud ML Engine は、サポートされている別のバージョンが指定されない限り、最新の安定したランタイム バージョンを使用してモデル バージョンをデプロイします。ランタイム バージョンは、予測サービスがモデルを実行するために使用する TensorFlow のバージョンを主に決定します。バッチ予測ジョブを実行する場合、割り当てられたランタイム バージョンを上書きするオプションがあります。オンライン予測では、モデル バージョンのデプロイ時に設定されたランタイム バージョンが使用されます。
手動スケーリング

モデル バージョンで実行し続けるトレーニング ノードの数を指定できます。詳細については、スケーリングのセクションをご覧ください。

ステージング バケット

gcloud コマンドライン ツールを使用してモデルをデプロイする場合、ローカル コンピュータにある SavedModel を使用できます。このモデルは Cloud ML Engine にデプロイされる前に、このツールで指定した Cloud Storage の場所にステージングされます。

予測前に行うグラフの変更

主にトレーニングの段階で利用された TensorFlow 演算が、計算グラフに含まれている場合があります。モデルをトレーニングしたら、最終バージョンをエクスポートする前に、グラフからそれらの演算を削除できます。

トレーニング アプリケーションの開発ページに示されているアドバイスの多くは、予測操作を対象としたものです。トレーニングの大部分が完了し、バージョンのデプロイを開始する準備が整ったときにモデルに加える変更もアドバイスの一部に含まれています。

予測の取得

デプロイ済みのモデル バージョンに新しいデータを送信して、予測を取得できます。以下のセクションでは、予測に際して考慮すべき重要な事項について説明します。

バッチ予測 vs オンライン予測

Cloud ML Engine では、トレーニング済みのモデルから予測を取得するために、「オンライン予測」(HTTP 予測と呼ばれることもある)と「バッチ予測」の 2 つの方法が用意されています。どちらもクラウドでホストされた機械学習モデルに入力データを渡し、各データ インスタンスについて推定を取得します。違いを次の表に示します。

オンライン予測 バッチ予測
予測のレイテンシを最小限に抑えるように最適化される。 ジョブ内の大量のインスタンスを処理し、より複雑なモデルを実行するように最適化される。
リクエストごとに 1 つまたは複数のインスタンスを処理できる。 リクエストごとに 1 つまたは複数のインスタンスを処理できる。
予測はレスポンス メッセージで返される。 予測は、指定した Cloud Storage の場所の出力ファイルに書き込まれる。
入力データは JSON 文字列として直接渡される。 入力データは、Cloud Storage の場所にある 1 つ以上のファイルの URI として間接的に渡される。
可能な限り早く戻される。 非同期リクエスト。
プロジェクトへの閲覧者アクセス権を持つユーザーは誰でもリクエストできる。 実行するにはプロジェクト編集者である必要がある。
モデルのデプロイ時に選択したランタイム バージョンとリージョンで実行される。 使用可能なランタイム バージョン、使用可能なリージョンで実行できる。ただし、デプロイしたモデルのデフォルト バージョンで実行する必要がある。
Cloud ML Engine にデプロイされたモデルを実行する。 Cloud ML Engine にデプロイされたモデルまたはアクセス可能な Google Cloud Storage の場所に格納されているモデルを実行する。

アプリケーションのニーズによって、使用すべき予測の種類が決まります。アプリケーションの入力に応じて、またはタイムリーな推定が必要な他の状況でリクエストを行う場合は、一般にオンライン予測の使用をおすすめします。バッチ予測は、すぐに結果を必要とせず、累積データを処理する場合に最適です。たとえば、最後のジョブ以降に収集されたすべてのデータの予測を取得する定期的なジョブなどです。使用する予測方法が決定したら、予測料金に差額が発生する可能性も含めて通知することをおすすめします。

バッチ予測のレイテンシ

使用するモデルが単純で入力インスタンス セットが少数の場合、オンライン予測とバッチ予測では同じ予測リクエストを完了するのに要する時間にかなりの差があることがわかります。オンライン リクエストではほぼ即時に返される予測が、バッチジョブでは数分かかることがあります。これは、2 つの予測方法で使用されているインフラストラクチャが異なることによる副作用です。バッチ予測ジョブは、リクエストが送信されてから Cloud ML Engine でリソースが割り当てられ初期化されるのに対し、オンライン予測は、通常はリクエスト時点でジョブを処理する準備ができています。

予測ノードとリソース割り当てについて

Cloud ML Engine は、「ノード時間」内で予測に消費された処理量を測定します。このセクションでは、これらのノードと、さまざまな種類の予測にノードがどのように割り当てられるかを説明します。

ノードは、仮想マシン(VM)のように考えるのが最も簡単でしょう。ただし、従来の VM とは実装の仕組みが異なります。似ている点としては、ノードごとに一定量の処理能力とメモリがプロビジョニングされます。また、モデルを実行して予測を取得するために必要なオペレーティング システムのイメージと一連のソフトウェア構成があります。

オンライン予測とバッチ予測は、分散処理でノードを実行するため、特定のリクエストまたはジョブで複数のノードを同時に使用できます。時間単位が採用されており、ノードの総使用量に対して分単位で課金されます。たとえば、2 つのノードを 10 分間実行した場合、1 つのノードを 20 分間実行する場合と同じ料金が請求されます。オンライン予測とバッチ予測では、ノードの割り当てが異なります。これにより、料金に大きな影響を及ぼす可能性があります。

バッチ予測のノード割り当て

バッチ予測サービスは、ジョブの所要時間を最小限に抑えるように、使用するノードの数をスケーリングします。そのために、サービスは次の処理を行います。

  • ジョブの開始時にジョブを処理するためのノードを割り当てます。

  • 効率を最適化するために、ジョブ中にノード数をスケーリングします。各ノードは起動に時間がかかるため、サービスは割り当てるノード数を必要最小限にとどめて経過時間を短縮し、起動時間の増加を相殺します。

  • ジョブが完了するとすぐにノードをシャットダウンします。

使用するノードの最大数を指定して、バッチ予測ジョブのスケーリングに影響を与えることができます。サービスで使われる最大ノード数を要求したくなるものですが、ノードの使用は Cloud ML Engine の割り当てポリシーの対象となります。特にプロジェクトを他のユーザーと共有し、ジョブ(トレーニングと予測の両方)を同時に実行する可能性がある場合は、そのジョブに割り当てるノード数を制限することをおすすめします。

オンライン予測のノード割り当て

オンライン予測サービスでは、レイテンシを増大させずにリクエストを処理できるように、使用するノード数をスケーリングします。そのために、サービスは次の処理を行います。

  • 予測リクエストがない状態が続く場合は、予測リクエストが実行されてからノードを割り当てる。

  • リクエスト トラフィックに応じてノード数をスケーリングし、トラフィック増加時にノードを追加し、リクエストが減ったらノードを削除する。

  • 処理するリクエストがない場合でも、少なくとも 1 つのノードが数分間リクエストを処理できる状態にしておく。これにより、サービスですぐに予測を行うことができます。

  • モデル バージョンが予測リクエストを受信しない状態で数分間経過したら、ノード数をゼロにスケールダウンする。

サービスがゼロにスケールダウンされると、リクエストを処理するノードの初期化に時間がかかります(数秒から数分)。初期化の時間はモデル バージョンのサイズによって異なります。このため、クライアント側のタイムアウトにより、大型モデルの最初のリクエストが破棄される可能性があります。

常に迅速に処理されるようにするには、モデル バージョンで minNodes オプションを設定し、サービスが処理できる状態を維持できる最小限のノード数を指定します。この設定では、予測が処理されない場合でもノードの料金が発生するため、コストが増加する可能性があります。

自動スケーリングの制限

Cloud ML Engine のオンライン予測の自動スケーリングは、費用を最小限に抑えながらさまざまな頻度の予測リクエストの処理に役立ちます。しかし、それはすべての状況に最適とは限りません。このサービスで、リクエスト トラフィックの急増に追いつけるほど高速にノードをオンラインにすることができない場合があります。トラフィックが定期的に急増する場合や、アプリケーションが確実な低レイテンシを必要とする場合は、「手動スケーリング」を検討することをおすすめします。

手動スケーリングの使用

トラフィックに関係なく実行し続けるノードの数を指定することで、モデル バージョンに対するオンライン予測のスケーリングに影響を与えることができます。ノード数を手動で設定した場合、サービスは自動スケーリングしなくなります。つまり、指定した数のノードが常に準備完了状態に置かれ、そのノード数に対して継続的に課金されることになります。モデルが受信するリクエストの数が絶えず変動し、自動スケーリングで追いつけないような場合を除き、これは避けるべきです。projects.models.versions.create に渡す Version オブジェクトに manualScaling を設定することにより、使用するノードの数を設定します。

予測の入力データ

予測を取得するために使用するデータは、トレーニングに使用したデータと同じ形式をとる新しいデータです。オンライン予測とバッチ予測はどちらも同じデータ(モデルの機能)を使用しますが、使用する予測の種類とインターフェースによって異なる形式が必要です。これらの形式を次の表にまとめます。各形式については、後述のセクションで詳しく説明します。

予測の種類とインターフェース サポートされている入力形式
バッチ予測、API 呼び出し JSON インスタンス文字列を含むテキスト ファイルまたは TFRecords ファイル(圧縮可能)
バッチ予測、gcloud ツール JSON インスタンス文字列を含むテキスト ファイルまたは TFRecords ファイル(圧縮可能)
オンライン予測、API 呼び出し JSON リクエスト メッセージ
オンライン予測、gcloud ツール JSON インスタンス文字列を含むテキスト ファイルまたは CSV ファイル

インスタンス JSON 文字列

オンライン予測とバッチ予測の両方の基本形式は、インスタンス データのテンソルのリストです。これらは、トレーニング アプリケーションで入力を構成した方法に応じて、値のプレーンリストまたは JSON オブジェクトのメンバーのいずれかになります。

次の例は、入力テンソルとインスタンス キーを示しています。

{"values": [1, 2, 3, 4], "key": 1}

次の規則に従う限り、JSON 文字列の構成は複雑になってもかまいません。

  • インスタンス データの最上位レベルは、Key-Value ペアの辞書である JSON オブジェクトでなければならない。

  • インスタンス オブジェクト内の個々の値は、文字列、数字、またはリスト。JSON オブジェクトを埋め込むことはできない。

  • リストには、同じ型(他のリストも含む)のアイテムのみが含まれている必要がある。文字列と数値を混在させることはできない。

次の文字列(読みやすいように書式設定されています)は、ラベルとイメージを含むオブジェクトを示しています。このイメージは 8 ビット整数の 3 次元配列で表されています。

{
  "tag": "beach",
  "image": [
    [
      [138, 30, 66],
      [130, 20, 56],
      ...
    ],
    [
      [126, 38, 61],
      [122, 24, 57],
      ...
    ],
        ...
  ]
}

モデルが単一の入力だけを受け取る場合、JSON オブジェクトでラップする必要はありません。たとえば、4 つの値が含まれる 1 つのテンソル(この例ではベクトル)を送信する場合、次のようにフォーマットする必要はありません。

{"values": [1, 2, 3, 4]}

各インスタンスをリストとしてフォーマットするだけです。

[1, 2, 3, 4]
予測入力でのバイナリデータ

バイナリデータは、JSON がサポートする UTF-8 エンコード文字列としてフォーマットできません。入力にバイナリデータがある場合は、base64 エンコーディングで表す必要があります。次の特殊なフォーマットが必要です。

  • エンコードされた文字列は、b64 という 1 つのキーを持つ JSON オブジェクトとしてフォーマットする必要があります。次の Python の例では、base64 ライブラリを使用して生の JPEG データのバッファをエンコードし、インスタンスを作成しています。

    {"image_bytes":{"b64": base64.b64encode(jpeg_data)}}
    
  • TensorFlow モデルのコードでは、入力 / 出力テンソルのエイリアスの名前を「_bytes」で終わらせる必要があります。

オンライン予測の入力データ

オンライン予測の入力インスタンスは、予測リクエストのメッセージ本文として渡します。リクエストとレスポンスの本文のフォーマットについては、予測リクエストの詳細をご覧ください。

簡単に説明すると、各インスタンスをリスト内のアイテムにし、リストメンバーに instances という名前を付けます。したがって、先述の簡単なデータ インスタンス JSON の例は次のようになります。

{"instances": [{"values": [1, 2, 3, 4], "key": 1}]}

gcloud ml-engine projects predict を使用してオンライン予測をリクエストする場合、バッチ予測で使用する場合と同じ形式のファイルを渡します。

バッチ予測の入力データ

バッチ予測の入力データは、前述の JSON インスタンス データの行を含む 1 つまたは複数のテキスト ファイルとして渡します。入力ファイルには、単純な JSON 構文以外の列ヘッダーやその他の形式は含まれません。

{"image": [0.0, 0.0, ... ], "key": 0}
{"image": [0.0, 0.0, ... ], "key": 1}
{"image": [0.0, 0.0, ... ], "key": 2}

インスタンス キー

Cloud ML Engine は、分散処理を使用してバッチ予測ジョブを実行します。つまり、データは仮想マシンの任意のクラスタに分散され、予測できない順序で処理されます。返される予測と入力インスタンスを照合できるようにするには、インスタンス キーを定義しておく必要があります。インスタンス キーは、すべてのインスタンスが持つ値であり、一連のデータのインスタンス間で一意です。最も簡単なキーはインデックス番号です。

トレーニング アプリケーションで変化しなかったグラフからキーを渡すことをおすすめします。データにまだインスタンス キーがない場合は、データの前処理の一部として追加できます。

ランタイム バージョン

Cloud ML Engine の新しいバージョンがリリースされると、古いバージョンで開発されたモデルはサポートされなくなる可能性があります。特に、効果的なモデル バージョンに達した後、変更を加えない状態が長期間続いた場合はこの問題に該当します。Cloud ML Engine バージョニング ポリシーを確認し、モデル バージョンをトレーニングするために使用する Cloud ML Engine ランタイム バージョンを理解しておいてください。

ランタイム バージョンと予測

モデル バージョンの作成時に、サポートされている Cloud ML Engine ランタイム バージョンを指定できます。これにより、モデル バージョンのデフォルトの設定が確立されます。バージョンを明示的に指定しない場合、Cloud ML Engine では現在のデフォルトのランタイム バージョン(通常は最新の安定バージョン)を使用してバージョンが作成されます。

バッチ予測ジョブを開始するときに、使用するランタイム バージョンを指定できます。これは、Cloud ML Engine にデプロイされていないモデルを使用して予測を取得する場合に対応するためです。デプロイしたモデルには、デフォルトと異なるランタイム バージョンを使用しないでください。予期しないエラーが発生する可能性があります。

オンライン予測では、Cloud ML Engine 以外のモデルにリクエストできません。そのため、リクエストでデフォルトのランタイム バージョンを上書きするオプションはありません。

モデル バージョンに設定されたデフォルトのランタイム バージョンは変更できません。モデル バージョンに対して別のランタイム バージョンを指定するには、最初に使用したのと同じトレーニング アーティファクトを使用して新しいバージョンをデプロイします。

リージョンと予測

Google Cloud Platform では、ゾーンに分割されたリージョンを使用して、物理的なコンピューティング リソースの地理的なロケーションを定義します。Cloud ML Engine を使用して予測のモデルをデプロイする際に、予測を実行するデフォルトのリージョンを指定します。

バッチ予測ジョブを開始する際に、ジョブを実行するリージョンを指定して、デフォルトのリージョンをオーバーライドできます。オンライン予測は、常にモデルに指定されたデフォルトのリージョンで処理されます。

モデル トレーニングやオンライン / バッチ予測など、Cloud ML Engine サービスの利用可能なリージョンを確認するには、リージョン ガイドをお読みください。

予測のロギング

バッチ予測で生成されるジョブのログは、Stackdriver Logging で表示できます。オンライン予測のリクエストでも、モデルの作成時にログを生成するように構成しておけばログを取得できます。このオプションは Cloud ML Engine でモデルリソースを作成するときに指定する必要があり、モデルのすべてのバージョンでオンライン予測のログを生成するか、またはまったく生成しないかのいずれかを選択します。

モデルに対してオンライン予測のロギングを設定するには、projects.models.create でモデルを作成するときに使用するモデルリソースonlinePredictionLogging を true(Python では True)に設定します。gcloud コマンドライン ツールを使用してモデルを作成する場合は、gcloud ml-engine models create を実行するときに --enable-logging フラグを含めます。

デプロイされていないモデルからの予測の取得

Cloud ML Engine サービスにデプロイしていないモデルを使用して、バッチ予測をリクエストできます。モデルまたはバージョン名を指定する代わりに、実行するモデルが格納されている Google Cloud Storage の場所の URI を使用できます。

デプロイされていないモデルにはデフォルトのランタイム バージョンが設定されていないため、ジョブ リクエストでそれを明示的に設定する必要があります。設定がなければ、Cloud ML Engine は最新の安定したランタイム バージョンを使用します。

他のすべての点で、デプロイされていないモデルを使用したバッチ予測ジョブは、他のバッチジョブと同様に動作します。

モデルのテスト

Cloud ML Engine 予測サービスを使用して、本番環境でモデルをホストすることができますが、このサービスはモデルのテストにも使用できます。従来、モデルのテストは、機械学習ソリューションのデプロイを準備する前の段階でした。テストパスの目的は、実際の状況で使用される方法に近い環境でモデルをテストすることです。

前述したように、予測サービスには、1 つのモデルの複数のバージョンを同時にデプロイできます。つまり、必要に応じてモデルの複数のリビジョンを用意して、一度にテストできます。また、次のリビジョンをテストしながら、モデルの本番環境バージョンを容易にデプロイすることもできます。機械学習アプリケーションの開発の大半がそうであるように、新しいデータの可用性が制限要因となることがあります。そのためデベロッパーは、手持ちのデータを分割し、テストに使用する新しいデータを収集するための戦略を開発する必要があります。

次のステップ

  • オンライン予測によって新しいデータ インスタンスから値を推定する。

  • バッチ予測によって新しいデータ インスタンスから値を推定する。

このページは役立ちましたか?評価をお願いいたします。

フィードバックを送信...

Cloud Machine Learning Engine(Cloud ML Engine)