Cloud Vision API と Cloud AutoML Vision を使用する画像検索アプリケーションの構築

このチュートリアルでは、Cloud Vision APIAutoML Vision のラベル検出を使用して、画像の検索と分類のアプリケーションを強化する方法について説明します。これらのサービスを他の Google Cloud Platform(GCP)サービスと組み合わせると、以下のことが簡単にできます。

  • 画像内で検出されたオブジェクトやシーンを検索します。
  • 検出された画像ラベルに基づいて画像をさまざまなカテゴリに分類します。
  • 画像ラベルとカテゴリを検索ファセットとして使用します。

Cloud Vision API を使用して検索アプリケーションを強化する方法については、Cloud Vision API と AutoML Vision を使用する画像検索アプリケーションをご覧ください。

ラベル検出を使用して画像を検索可能にする

Cloud Vision API のラベル検出機能は、数千のオブジェクト カテゴリにわたる幅広いオブジェクト セットを識別します。オブジェクト識別はラベルとして返され、各ラベルは文字列値(「dog」や「cat」など)と文字列に関連付けられた信頼スコアで構成されます。信頼スコアは、Cloud Vision API によるラベルの正確さの判定を表します。

AutoML Vision は、ユーザーが提供するラベル付きトレーニング セットによるカスタム画像分類に最適です。Cloud Vision API のラベル検出が分類タスクに適切なラベルを返さない場合、AutoML Vision を使用してカスタム画像モデルをトレーニングすることをおすすめします。

ラベル検出と検索インデックスを組み合わせることで、画像を新しい方法で検索可能にします。

目標

このチュートリアルでは、GCP を使用して、Cloud Vision API によって拡張された基本的な画像検索アプリケーションをビルドおよびデプロイする方法を示します。以下を行う方法について説明します。

  • アップロードされた画像を保存するための Cloud Storage バケットを作成します。
  • 新しい画像が画像ストレージ バケットに追加されたときにトリガーされる Cloud Pub/Sub Notifications を構成します。
  • Cloud Vision との統合を含む、フロントエンド サービスとバックエンド サービスを提供するサービスを App Engine にデプロイします。
  • Cloud Machine Learning Engine を使用して、基本的な画像カテゴリ予測サービスをデプロイします。
  • サンプル画像を使用して画像検索アプリケーションをテストします。

料金

このチュートリアルでは、以下を含む GCP の課金対象となるコンポーネントを使用しています。

GCP の無料枠を超える使用量には、最新の料金設定に従って請求されます。このチュートリアルの指示に従う場合、費用の見積もりは $1.00 未満です。

始める前に

  1. Google アカウントにログインします。

    Google アカウントをまだお持ちでない場合は、新しいアカウントを登録します。

  2. GCP プロジェクトを選択または作成します。

    [リソースの管理] ページに移動

  3. プロジェクトに対して課金が有効になっていることを確認します。

    課金を有効にする方法について

  4. Cloud Vision、Cloud Pub/Sub、Cloud Machine Learning API を有効にします。

    APIを有効にする

Cloud SDK をインストールしていない場合は、アプリケーションのデプロイに Cloud Shell を使用します。Cloud Shell は Cloud SDK がプリインストールされた shell 環境を提供します。

サンプル画像検索アプリケーションのデプロイ

サンプル画像検索アプリケーションでは、ラベル検出に基づいて広範な機能を使用できます。サンプル アプリケーションは次の 2 つの部分に分かれています。

  • ベース検索アプリケーション

    Cloud Storage バケット、Cloud Pub/Sub Notifications、App Engine を使用して簡単な検索アプリケーションを作成します。ベース検索アプリケーションは、キーワードとファセット検索を使用した画像検索を行います。ベース検索アプリケーションは、Cloud Vision を使用して、ラベルを特定のカテゴリにマッピングすることにより画像を分類する方法を示します。

  • カテゴリ予測サービス

    Cloud ML Engine を使用して、予測モデルによりベース検索アプリケーションを拡張します。このモデルは、画像ラベルの意味的関連性を使用して、分類用のさまざまなカテゴリを作成します。

ラベル検出は、多様な主題にわたるオブジェクトとシーンを幅広く把握します。とはいえ、Cloud Vision API が検出しないカテゴリが必要な場合もあります。その場合は、AutoML Vision を使用して特定のカテゴリのカスタム画像モデルをトレーニングすることをおすすめします。サンプル検索アプリケーションを拡張すれば、ユーザー独自のモデルによるカスタムラベル検出のリクエストが可能になります。これについては、このチュートリアルの後半にある AutoML Vision を使用するためのサンプル アプリケーションの拡張で説明しています。

検索アプリケーションの概要

ベース検索アプリケーションは、Cloud Pub/Sub 通知を使用して、新しい画像が Cloud Storage バケットに到着したときに Cloud Vision ラベルの検出を自動的にトリガーする方法を示します。検出されたラベルを App Engine Search API に追加すると、ユーザーはキーワード検索で画像を検索できるようになります。Search API には、キーワード検索に加えて、返された Cloud Vision ラベルを検索ファセットとして公開するファセット検索機能も用意されています。

ラベル検出は、ユーザーが定義した特定のカテゴリではなく、サービスによって決定された最も関連性の高いラベルを返します。たとえば、浴室キッチン寝室のカテゴリを使用して住宅のインテリアの画像を分類することを目標にするとします。ベース検索アプリケーションは、ラベルを検索ファセットとして公開するだけでなく、これらのラベルを使用して、ラベルからカテゴリへの固定マッピングにより画像を所定のカテゴリに分類する方法を示します。この分類方法では各カテゴリのラベル辞書も作成します。この辞書は、特定の Cloud Vision ラベルを 1 つまたは複数の目的のカテゴリにマッピングします。たとえば、キッチン寝室浴室のための次のようなラベルからカテゴリへのマッピングを考えます。

カテゴリ ラベル 1 ラベル 2 ラベル 3 ラベル 4 ラベル 5
キッチン キッチン 食器洗い機 オーブン シンク ガスコンロ
浴室 浴室 シャワー トイレ タイル 配管
寝室 寝室 ベッド ナイトスタンド マットレス

与えられた画像に対して Cloud Vision API が「ベッド」、「マットレス」、「シャワー」というラベルを信頼スコア 0.9、0.7、0.3 で返した場合、検索アプリケーションはその画像を寝室に分類します。なぜなら、返されたラベルに対して計算された信頼スコアのうち、このカテゴリのスコアが一番高いからです。

カテゴリ ラベルからカテゴリへのマッピング ラベル信頼スコア カテゴリ信頼スコア合計
寝室 'ベッド' ∈ {'寝室', 'ベッド', '枕', 'ナイトスタンド', 'マットレス'} 0.9 1.6
'マットレス' ∈ {'寝室', 'ベッド', '枕', 'ナイトスタンド', 'マットレス'} 0.7
浴室 'シャワー' ∈ {'浴室', 'シャワー', 'トイレ', 'バスタブ', '配管'} 0.3 0.3
キッチン 一致する項目はありません - -

検索アプリケーションのデプロイ

以下の手順では、次の操作を行います。

  • Node Package Manager(npm)を使用して、ウェブ フロントエンドで必要な Polymer ライブラリをインストールします。
  • 画像を保存するための Cloud Storage バケットを作成します。
  • ストレージ通知に対する Cloud Pub/Sub トピックとサブスクリプションを作成します。
  • 検索アプリケーションを App Engine にデプロイします。

この手順を開始する前に、始める前にセクションに示された前提条件を満たしていることを確認してください。

  1. Cloud Shell を開きます。

    Cloud Shell に移動

  2. npm を使用して、ベース検索アプリケーションが必要とする Polymer ライブラリをインストールします。

    npm install -g polymer-cli
  3. npm を使用して、必要な Polymer ウェブ コンポーネントをインストールするために必要な Bower をインストールします。

    npm install -g bower
  4. 後のコマンドで使用する環境変数を定義します。

    PROJECT=$(gcloud config list project --format "value(core.project)")
    
    GCS_IMAGE_BUCKET=${PROJECT}-images
    REGION=us-central1
    PUBSUB_TOPIC=image-topic
    PUBSUB_SUBSCRIPTION=image-notify
    PUSH_ENDPOINT=https://backend-dot-${PROJECT}.appspot.com/_ah/push-handlers/image
    
  5. 画像を保存するための Cloud Storage Regional Storage バケットを作成します。

    gsutil mb -c regional -l ${REGION} -p ${PROJECT} gs://${GCS_IMAGE_BUCKET}
  6. Cloud Pub/Sub のトピックを作成します。

    gcloud pubsub topics create ${PUBSUB_TOPIC} --project=${PROJECT}
  7. Cloud Pub/Sub サブスクリプションを作成します。

    gcloud pubsub subscriptions create ${PUBSUB_SUBSCRIPTION} \
        --topic=${PUBSUB_TOPIC} \
        --push-endpoint=${PUSH_ENDPOINT} \
        --project=${PROJECT}
    
  8. GitHub からチュートリアルのサンプルコードのクローンを作成します。

    cd ${HOME}
    git clone https://github.com/GoogleCloudPlatform/solutions-vision-search.git
    
  9. App Engine のウェブ フロントエンドの依存関係をインストールするには、次の手順に従います。

    1. Polymer ウェブ アプリケーションをフロントエンド ディレクトリにコピーします。

      cp -rv solutions-vision-search/third_party/polymer-starter/. solutions-vision-search/gae/frontend
      
    2. 必要な Polymer ウェブ コンポーネントをインストールします。

      cd solutions-vision-search/gae/frontend
      bower install
      
    3. Polymer ウェブ アプリケーションをビルドします。

      polymer build
      
  10. pip を使用して、App Engine バックエンド サービスの依存関係をインストールします。

    cd ${HOME}/solutions-vision-search
    pip install -r gae/backend/requirements.txt -t gae/backend/lib
    
  11. バックエンド サービスとフロントエンド サービスを App Engine にデプロイします。

    gcloud app deploy \
        gae/frontend/app.yaml \
        gae/backend/app.yaml \
        gae/dispatch.yaml \
        --project ${PROJECT}
    
  12. Cloud Storage バケットに通知構成を適用して、新しい画像が到着したときにバックエンド サービスに通知を送信します。

    gsutil notification create -f json -t projects/${PROJECT}/topics/${PUBSUB_TOPIC} gs://${GCS_IMAGE_BUCKET}
    
  13. App Engine サービスをデプロイしてから、テスト画像を Cloud Storage バケットにコピーします。

    gsutil -m cp -v ${HOME}/solutions-vision-search/sample-images/*.jpg gs://${GCS_IMAGE_BUCKET}
    
  14. 次のコマンドを入力してウェブブラウザを開き、画像検索のユーザー インターフェースを表示します。

    gcloud config set project ${PROJECT}
    gcloud app browse -s default
    

    [Search Facets] ペインで、[Image Label] に表示されるファセット値を使用して、検出されたラベル結果を絞り込めます。[Mapped Category] の値を使用すると、ラベルからカテゴリへの固定マッピングを使用して生成されたカテゴリによる絞り込みができます。

    ラベルからカテゴリへのマッピング

カテゴリ予測サービスのデプロイ

ラベルからカテゴリへの固定マッピングを使用した画像の分類は簡単ですが、特定のカテゴリに属する画像に対して返されるすべての可能な Cloud Vision ラベルを予想するのは困難です。返されるラベルは、アプリケーションが予想する値と正確には一致しないが意味的に関連していることがあります。

カテゴリ予測サービスの概要

画像を浴室キッチン寝室に分類するユースケースを考えます。画像の内容により、Cloud Vision API は検出されたラベル(「バスタブ」、「料理」、「寝具」など)を返す可能性があります。次の表は、検出されたラベルが「料理」である画像が、ラベルからカテゴリへのマッピングにその単語が含まれていないため、キッチン カテゴリに一致しないことを示しています。

カテゴリ ラベルからカテゴリへのマッピング カテゴリマッチ
キッチン '料理' ∈ {'キッチン', '食器洗い機', 'オーブン', 'シンク', 'ガスコンロ'} ×

この問題を解決するには、より複雑ではるかに効果的なアプローチをとることができます。このアプローチでは、単語埋め込みを使用して、画像ラベルと所定のカテゴリとの間の類似度スコアを計算します。これを達成するために、このチュートリアルでは GloVe の事前トレーニング単語埋め込みを使用して、ラベル(単語)を実数ベクトルに変換します。このような個々の単語ベクトルは、画像ごとおよびカテゴリごとのベクトルを計算するために使用されます。画像とカテゴリとの間の意味的類似度は、ベクトル間の関係、この場合はコサイン類似度として伝達されます。

この単純化したケースでは、画像ベクトルは単一の単語「料理」で構成され、これが実数ベクトルに変換されます。カテゴリ ベクトルは変換されたベクトルラベルの合計であり、キッチン カテゴリは「キッチン」、「食器洗い機」、「オーブン」、「シンク」、「ガスコンロ」から計算されます。次の表に、キッチン カテゴリの類似度スコアが cosine_similarity(image_vector, category_vector) としてどのように計算されるかを示します。

カテゴリ ラベルからカテゴリへの類似度 コサイン類似度
キッチン cosine_similarity(['-0.32068', '0.26405', '-1.071' ...], [-0.553273, 0.34074, -3.8644 ...]) 0.772

コサイン類似度スコアが最も高いカテゴリに画像を関連付けると、返された Cloud Vision ラベルがカテゴリ単語の所定のリストと正確に一致しなくても、各画像が分類されます。画像およびカテゴリ ベクトルの計算方法の詳細については、Cloud Vision API と AutoML Vision を使用する画像検索アプリケーションを参照してください。

カテゴリ予測サービスのデプロイ

このセクションでは、単語(ラベル)を GloVe の単語ベクトルに変換する TensorFlow モデルを作成し、画像とカテゴリ ベクトルの類似度を計算します。モデルを Cloud ML Engine にデプロイした後、検索アプリケーションは Cloud ML Engine のオンライン予測を更新して呼び出し、アップロードされた画像のカテゴリを予測します。

Cloud Shell で、次の手順に従ってカテゴリ予測サービスをデプロイします。

  1. 後のコマンドで使用する環境変数を定義します。

    PROJECT=$(gcloud config list project --format "value(core.project)")
    
    GCS_MODEL_BUCKET=${PROJECT}-ml-models
    GCS_STAGING_BUCKET=${PROJECT}-ml-staging
    MODEL_NAME=category_predictor
    MODEL_VERSION=v1
    MODEL_REGION=us-central1
    
  2. 予測モデルを保存する Cloud Storage Regional Storage バケットを作成します。

    gsutil mb -c regional -l ${MODEL_REGION} -p ${PROJECT} gs://${GCS_MODEL_BUCKET}
    
  3. トレーニング コードをステージングするための Cloud Storage Regional Storage バケットを作成します。

    gsutil mb -c regional -l ${MODEL_REGION} -p ${PROJECT} gs://${GCS_STAGING_BUCKET}
    
  4. Cloud ML Engine にトレーニング ジョブを送信します。

    cd ${HOME}/solutions-vision-search
    gcloud ml-engine jobs submit training my_job \ --module-name=trainer.task \ --package-path=categorizer/trainer \ --runtime-version=1.2 \ --project=${PROJECT} \ --region=us-central1 \ --staging-bucket=gs://${GCS_STAGING_BUCKET} -- \ --gcs_output_path=gs://${GCS_MODEL_BUCKET}

    トレーニング ジョブは通常 10 分以内で完了します。ログの出力をストリーミングすることによって、ジョブの進捗状況を検査できます。

    gcloud ml-engine jobs stream-logs my_job

    ジョブが完了すると、次のようなログが出力されます。

    INFO  2017-12-08 14:06:19 +1100    master-replica-0    Task completed successfully.
    INFO  2017-12-08 14:10:45 +1100    service             Job completed successfully.
    
  5. Cloud ML Engine で予測モデルを作成します。

    gcloud ml-engine models create $MODEL_NAME --regions=${MODEL_REGION} --project=${PROJECT}
    
  6. 予測モデルの新しいバージョン v1 を作成します。

    gcloud ml-engine versions create v1 \
        --model=$MODEL_NAME \
        --origin=gs://${GCS_MODEL_BUCKET}/model \
        --runtime-version=1.2 \
        --project=${PROJECT}
    
  7. 新しい画像が追加されたときにカテゴリ予測モデルを呼び出すように App Engine バックエンド サービス構成を更新します。

    Linux の場合:

    sed -i "s/USE_CATEGORY_PREDICTOR: false/USE_CATEGORY_PREDICTOR: true/" gae/backend/app.yaml
    

    macOS の場合:

    sed -i '' "s/USE_CATEGORY_PREDICTOR: false/USE_CATEGORY_PREDICTOR: true/" gae/backend/app.yaml
    
  8. バックエンド サービスを App Engine にデプロイします。

    gcloud app deploy gae/backend/app.yaml --project ${PROJECT}
  9. サンプル画像を削除して再読み込みし、Cloud Pub/Sub Notifications をトリガーし、カテゴリ予測サービスで画像を処理します。

    gsutil -m rm gs://${GCS_IMAGE_BUCKET}/*.jpg
    gsutil -m cp -v ${HOME}/solutions-vision-search/sample-images/*.jpg gs://${GCS_IMAGE_BUCKET}
    
  10. デプロイされたアプリケーションにウェブブラウザで移動します。

    gcloud config set project ${PROJECT}
    gcloud app browse -s default
    

検索アプリのテスト

デプロイされたアプリケーションを起動します。すべてが適切に機能している場合、[Search Facets] ペインの [Most Similar Category] セクションに追加ファセット値がリストされます。

最も類似したカテゴリ セクション

[Most Similar Category] セクションには、Cloud ML Engine マッチングの結果として、所定のカテゴリおよびカテゴリに関連付けられた画像の数が表示されます。

各カテゴリ値(動物など)に対して返された画像を比較すると、マップされたカテゴリと最も類似したカテゴリの違いがわかります。この例では、固定ラベル マッピングで取り逃した 5 つの画像を、カテゴリ予測サービスが自然界に 2 つ、車両に 2 つ、動物に 1 つ分類することに成功しています。この 5 つの画像から固定カテゴリラベルと正確には一致しないラベルが返されましたが、正確な Cloud ML Engine 分類には十分な意味的類似度が備わっていました。

AutoML Vision を使用するためのサンプル アプリケーションの拡張

AutoML Vision にはシンプルなグラフィカル ユーザー インターフェース(GUI)が備わっており、これを使用して、独自のデータに基づき、モデルをトレーニング、評価、改善、デプロイできます。Cloud Vision のラベル検出が目的のアプリケーションに適したラベルを返さない場合、ユーザー定義ラベルでカスタム画像モデルをトレーニングすることをおすすめします。トレーニングが終了したら、AutoML Vision API を使用して自分のモデルのクエリを行います。

AutoML Vision のカスタムラベル検出を使用すれば、ベース検索アプリケーションをさまざまな方法でさらに拡張できます。いくつかの例を以下に示します。

  • ファセット検索を拡張します。AutoML Vision モデルからユーザー定義ラベルを追加してファセット検索を拡張できます。このアプローチは、画像が特定のカテゴリではなく関連する複数のラベルを持つ可能性がある場合に最適です。カスタム画像ラベルと Cloud Vision ラベルを(たとえば単一の画像ラベル ファセットのもとで)結合したり、カスタムラベルを個別の検索ファセットとして提示したりすることで、サンプル アプリケーションを拡張できます。

    カスタムラベルを個別の検索ファセットとして提示する方法は、AutoML Vision モデルが特定の主題やトピック領域について特殊なラベルを返す場合に最適です。たとえば、可能なラベルとして「タンポポ」、「ヒナギク」、「チューリップ」を検出して返す特殊なモデルは、「花」検索ファセットとして分離できます。実際には、このアプローチはモデルのカスタム画像ラベルを含む「花」カテゴリを可能なカテゴリ値として作成することに似ています。

  • カスタムラベルを画像カテゴリとして使用します。AutoML Vision のカスタムラベル検出は、Cloud Vision API ラベルが適切でないときに、特殊な画像の分類に使用できます。このシナリオでは、トレーニング データセットの画像ラベルと検索に必要なカテゴリは同じです。モデルのカスタムラベルはユーザーによって定義されたものでアプリケーションによる予想が可能であるため、さまざまなラベルを特定のカテゴリにマッピングする必要はありません。

クリーンアップ

このチュートリアルで使用するリソースについて、Google Cloud Platform アカウントに課金されないようにする手順は次のとおりです。

チュートリアルが終了したら、GCP で作成したリソースについて料金が発生しないようにクリーンアップします。以降のセクションでは、このようなリソースを削除する方法を説明します。

  1. GCP Console で [プロジェクト] ページに移動します。

    プロジェクト ページに移動

  2. プロジェクト リストで、削除するプロジェクトを選択し、[削除] をクリックします。
  3. ダイアログでプロジェクト ID を入力し、[シャットダウン] をクリックしてプロジェクトを削除します。

次のステップ

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

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