5
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【BigQuery】画像から類似画像を検索!マルチモーダルエンベディングの簡単解説

Posted at

はじめに

Google CloudのBigQueryでマルチモーダルエンベディングが導入されています。
例としてテキストから画像検索が挙がっていましたが、画像から画像検索がなかったのでPythonを駆使して試してみました。

前準備

検索するためのデータベースをBigQuery上に事前に作成しておきます。

画像の用意

検索したい画像をCloud Storageにアップロードします。
今回はImagen3に作ってもらった10枚の画像を使用してみます。

image.png

BigQueryの外部接続の作成

「外部データソースへの接続」から「Vertex AI リモートモデル、リモート関数、BigLake(Cloud リソース)」を選び、接続IDを入力します。
image.png

image.png

オブジェクトテーブルの作成

BigQueryのオブジェクトテーブルを使用することで、非構造データを扱うことができるようになります。
以下のクエリを実行します。

CREATE OR REPLACE EXTERNAL TABLE
 `DATASET.object-table`
WITH CONNECTION `LOCATION.CONNNECTION_ID`
OPTIONS
( object_metadata = 'SIMPLE',
   uris = ['gs://BUCKET_NAME/*']
);

実行が完了すると、検索したい画像のオブジェクトテーブルが作成されます。

接続のサービスアカウントに権限付与

作成された外部接続の詳細を開くと、サービスアカウントIDが記載されています。
このサービスアカウントIDに対して、以下のロールを付与します。

  • Vertex AI ユーザー
  • Storage オブジェクト閲覧者

エンベディングモデルの追加

multimodalembedding@001エンドポイントを使用する BigQuery モデルを作成します。
以下のクエリを実行します。

CREATE OR REPLACE MODEL
 DATASET.multimodal_embedding_model REMOTE
WITH CONNECTION `LOCATION.CONNNECTION_ID`
OPTIONS (endpoint = 'multimodalembedding@001')

エンベディングの生成

ML.GENERATE_EMBEDDING 関数を使用することで、エンベディングを生成できます。
以下のクエリを実行します。

CREATE OR REPLACE TABLE `DATASET.object-table_embeddings`
AS
SELECT * FROM ML.GENERATE_EMBEDDING(
  MODEL `DATASET.multimodal_embedding_model`,
  TABLE `DATASET.object-table`)
WHERE content_type = 'image/jpeg'

実行が完了すると、DATASET.object-table_embeddingsテーブルができています。
プレビューで中身を見てみると、画像のエンベディングされた結果が格納されています。

image.png

画像で画像を検索する

検索したい画像

以下の画像に似た画像を検索してみたいと思います。

検索

Pythonを使用します。
まず画像をマルチモーダルエンベディングでエンベディングに変換します。

import vertexai
from vertexai.vision_models import Image, MultiModalEmbeddingModel

vertexai.init(project=PROJECT_ID, location=LOCATION)

model = MultiModalEmbeddingModel.from_pretrained("multimodalembedding@001")
image = Image.load_from_file("/path/image.png")

embeddings = model.get_embeddings(
    image=image,
    dimension=1408,
)

その後、BigQueryのVECTOR_SEARCH関数を使用したクエリをPython上から実行します。
BigQuery上で画像を読み込むには、オブジェクトテーブルをまた作成する必要があります。
今回はSQLクエリ上にエンベディング結果を埋め込むことで、別途オブジェクトテーブルを用意しないようにしました。

from google.cloud import bigquery

client = bigquery.Client()
client = bigquery.Client(project=PROJECT_ID)

query = f'''
CREATE OR REPLACE TABLE `DATASET.vector_search_results` AS
WITH search AS(
  SELECT {embeddings.image_embedding} as ml_generate_embedding_result
)
SELECT base.uri AS gcs_uri, distance
FROM
  VECTOR_SEARCH(
    TABLE `DATASET.object-table_embeddings`,
    'ml_generate_embedding_result',
    TABLE search,
    'ml_generate_embedding_result',
    top_k => 3);
'''

result = client.query(query)

この実行が終わると、BigQuery上に検索結果のテーブルが作成されます。
そのテーブルに対して、検索結果を表示するコードを実行します。

import io
from PIL import Image
import matplotlib.pyplot as plt
import tensorflow as tf

def printImages(results):
    image_results_list = list(results)
    amt_of_images = len(image_results_list)

    fig, axes = plt.subplots(nrows=amt_of_images, ncols=2, figsize=(20, 20))
    fig.tight_layout()
    fig.subplots_adjust(hspace=0.5)
    for i in range(amt_of_images):
    gcs_uri = image_results_list[i][0]
    text = image_results_list[i][1]
    f = tf.io.gfile.GFile(gcs_uri, 'rb')
    stream = io.BytesIO(f.read())
    img = Image.open(stream)
    axes[i, 0].axis('off')
    axes[i, 0].imshow(img)
    axes[i, 1].axis('off')
    axes[i, 1].text(0, 0, text, fontsize=10)
    plt.show()

query = """
  SELECT * FROM `DATASET.vector_search_results`
  ORDER BY distance;
"""

printImages(client.query(query))

検索画像とそのベクトルの距離が表示されます。
ベクトルの距離が近いほど、入力画像と近いものを指しています。
一番上に色味と形状が似ている画像がきていて、靴という共通点で検索の上位に来ていることが分かります!

image.png

おわりに

今回BigQueryのマルチモーダルエンベディングを使用して、画像から画像検索を試してみました。
検索用のオブジェクトテーブルを使わないで、SQLのWITH句とPythonを駆使して実現させました。
BigQueryでマルチモーダルのベクトル検索が簡単に行えるので、クロスモダリティの検索の幅が広がりそうです!

5
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?