ONNX 形式の PyTorch モデルを使用して予測を行う


Open Neural Network Exchange(ONNX)は、ML フレームワークを統一された形式で表現するためのフォーマットです。ONNX に対する BigQuery ML サポートにより、次のことが可能になります。

  • 使い慣れたフレームワークを使用してモデルをトレーニングする。
  • モデルを ONNX 形式に変換する。
  • ONNX モデルを BigQuery にインポートし、BigQuery ML を使用して予測を行う。

このチュートリアルでは、PyTorch でトレーニングされた ONNX モデルを BigQuery データセットにインポートし、SQL クエリから予測を行う方法について説明します。

目標

  • PyTorch を使用して事前トレーニング済みモデルをインポートする。
  • torch.onnx を使用してモデルを ONNX 形式に変換する
  • CREATE MODEL ステートメントを使用して ONNX モデルを BigQuery にインポートする。
  • インポートした ONNX モデルで ML.PREDICT 関数を使用して予測を行う。

費用

このドキュメントでは、課金対象である次の Google Cloudコンポーネントを使用します。

料金計算ツールを使うと、予想使用量に基づいて費用の見積もりを生成できます。 新規の Google Cloud ユーザーは無料トライアルをご利用いただける場合があります。

このドキュメントに記載されているタスクの完了後、作成したリソースを削除すると、それ以上の請求は発生しません。詳細については、クリーンアップをご覧ください。

始める前に

  1. Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
  2. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  3. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  4. Make sure that billing is enabled for your Google Cloud project.

  5. Enable the BigQuery, BigQuery Connection, and Cloud Storage APIs.

    Enable the APIs

  6. このドキュメントのタスクを実行するために必要な権限が付与されていることを確認します。

必要なロール

新しいプロジェクトを作成すると、そのプロジェクトのオーナーになり、このチュートリアルを完了するために必要な Identity and Access Management(IAM)の権限がすべて付与されます。

既存のプロジェクトを使用している場合は、次の操作を行います。

Make sure that you have the following role or roles on the project:

Check for the roles

  1. In the Google Cloud console, go to the IAM page.

    Go to IAM
  2. Select the project.
  3. In the Principal column, find all rows that identify you or a group that you're included in. To learn which groups you're included in, contact your administrator.

  4. For all rows that specify or include you, check the Role column to see whether the list of roles includes the required roles.

Grant the roles

  1. In the Google Cloud console, go to the IAM page.

    [IAM] に移動
  2. プロジェクトを選択します。
  3. [ アクセスを許可] をクリックします。
  4. [新しいプリンシパル] フィールドに、ユーザー ID を入力します。 これは通常、Google アカウントのメールアドレスです。

  5. [ロールを選択] リストでロールを選択します。
  6. 追加のロールを付与するには、 [別のロールを追加] をクリックして各ロールを追加します。
  7. [保存] をクリックします。

BigQuery における IAM 権限の詳細については、IAM 権限をご覧ください。

省略可: モデルをトレーニングして ONNX 形式に変換する

次のコードサンプルは、事前トレーニング済みの分類モデルを PyTorch にインポートする方法と、生成されたモデルを ONNX 形式に変換する方法を示しています。このチュートリアルでは、gs://cloud-samples-data/bigquery/ml/onnx/resnet18.onnx に保存されている事前構築済みのサンプルモデルを使用します。サンプルモデルを使用する場合は、これらの手順を完了する必要はありません。

画像分類用の PyTorch ビジョンモデルを作成する

次のコードサンプルを使用して、BigQuery ML の ML.DECODE_IMAGE 関数と ML.RESIZE_IMAGE 関数から返された、デコードされた画像データを受け入れる PyTorch の事前トレーニング済み resnet18 モデルをインポートします。

import torch
import torch.nn as nn

# Define model input format to match the output format of
# ML.DECODE_IMAGE function: [height, width, channels]
dummy_input = torch.randn(1, 224, 224, 3, device="cpu")

# Load a pretrained pytorch model for image classification
model = torch.hub.load('pytorch/vision:v0.10.0', 'resnet18', pretrained=True)

# Reshape input format from [batch_size, height, width, channels]
# to [batch_size, channels, height, width]
class ReshapeLayer(nn.Module):
    def __init__(self):
        super().__init__()

    def forward(self, x):
        x = x.permute(0, 3, 1, 2)  # reorder dimensions
        return x

class ArgMaxLayer(nn.Module):
    def __init__(self):
        super().__init__()

    def forward(self, x):
       return torch.argmax(x, dim=1)

final_model = nn.Sequential(
    ReshapeLayer(),
    model,
    nn.Softmax(),
    ArgMaxLayer()
)

モデルを ONNX 形式に変換する

次のサンプルを使用して、torch.onnx で PyTorch ビジョンモデルをエクスポートします。エクスポートされた ONNX ファイルの名前は resnet18.onnx です。

torch.onnx.export(final_model,            # model being run
                  dummy_input,            # model input
                  "resnet18.onnx",        # where to save the model
                  opset_version=10,       # the ONNX version to export the model to
                  input_names = ['input'],         # the model's input names
                  output_names = ['class_label'])  # the model's output names

ONNX モデルを Cloud Storage にアップロードする

モデルを保存したら、次の操作を行います。

データセットを作成する

ML モデルを保存する BigQuery データセットを作成します。

コンソール

  1. Google Cloud コンソールで [BigQuery] ページに移動します。

    [BigQuery] ページに移動

  2. [エクスプローラ] ペインで、プロジェクト名をクリックします。

  3. 「アクションを表示」> [データセットを作成] をクリックします。

    [データセットを作成] のメニュー オプション。

  4. [データセットを作成] ページで、次の操作を行います。

    • [データセット ID] に「bqml_tutorial」と入力します。

    • [ロケーション タイプ] で [マルチリージョン] を選択してから、[US (米国の複数のリージョン)] を選択します。

    一般公開データセットは US マルチリージョンに保存されています。わかりやすくするため、データセットを同じロケーションに保存します。

    • 残りのデフォルトの設定は変更せず、[データセットを作成] をクリックします。

    値が入力された [データセットを作成] ページ。

bq

新しいデータセットを作成するには、--location フラグを指定した bq mk コマンドを使用します。使用可能なパラメータの一覧については、bq mk --dataset コマンドのリファレンスをご覧ください。

  1. データのロケーションが US に設定され、BigQuery ML tutorial dataset という説明の付いた、bqml_tutorial という名前のデータセットを作成します。

    bq --location=US mk -d \
     --description "BigQuery ML tutorial dataset." \
     bqml_tutorial

    このコマンドでは、--dataset フラグの代わりに -d ショートカットを使用しています。-d--dataset を省略した場合、このコマンドはデフォルトでデータセットを作成します。

  2. データセットが作成されたことを確認します。

    bq ls

API

定義済みのデータセット リソースを使用して datasets.insert メソッドを呼び出します。

{
  "datasetReference": {
     "datasetId": "bqml_tutorial"
  }
}

ONNX モデルを BigQuery にインポートする

次の手順では、CREATE MODEL ステートメントを使用して、サンプル ONNX モデルを Cloud Storage からデータセットにインポートする方法について説明します。

コンソール

  1. Google Cloud コンソールで [BigQuery Studio] ページに移動します。

    BigQuery Studio に移動

  2. クエリエディタで次の CREATE MODEL ステートメントを入力します。

    CREATE OR REPLACE MODEL `bqml_tutorial.imported_onnx_model`
     OPTIONS (MODEL_TYPE='ONNX',
      MODEL_PATH='BUCKET_PATH')

    BUCKET_PATH は、Cloud Storage にアップロードしたモデルのパスに置き換えます。サンプルモデルを使用する場合は、BUCKET_PATH を値 gs://cloud-samples-data/bigquery/ml/onnx/resnet18.onnx に置き換えます。

    処理が完了すると、「Successfully created model named imported_onnx_model」のようなメッセージが表示されます。

    新しいモデルが [リソース] パネルに表示されます。モデルにはモデルアイコン [リソース] パネルのモデルアイコン。 がついています。[リソース] パネルで新しいモデルを選択すると、そのモデルに関する情報がクエリエディタの横に表示されます。

    imported_onnx_model の情報パネル。

bq

  1. 次の CREATE MODEL ステートメントを入力して Cloud Storage から ONNX モデルをインポートします。

    bq query --use_legacy_sql=false \
    "CREATE OR REPLACE MODEL
      `bqml_tutorial.imported_onnx_model`
    OPTIONS
      (MODEL_TYPE='ONNX',
       MODEL_PATH='BUCKET_PATH')"

    BUCKET_PATH は、Cloud Storage にアップロードしたモデルのパスに置き換えます。サンプルモデルを使用している場合は、BUCKET_PATHgs://cloud-samples-data/bigquery/ml/onnx/resnet18.onnx に置き換えます。

  2. モデルをインポートしたら、モデルがデータセットに表示されていることを確認します。

    bq ls bqml_tutorial

    出力は次のようになります。

    tableId               Type
    --------------------- -------
    imported_onnx_model  MODEL

形式やストレージの要件など、BigQuery への ONNX モデルのインポートの詳細については、ONNX モデルをインポートする CREATE MODEL ステートメントをご覧ください。

画像データを分析するオブジェクト テーブルを BigQuery で作成する

オブジェクト テーブルは、Cloud Storage 内にある非構造化データ オブジェクトの読み取り専用テーブルです。オブジェクト テーブルを使用すると、BigQuery の非構造化データを分析できます。

このチュートリアルでは、ML.PREDICT 関数を使用して、Cloud Storage バケットに保存されている入力画像の予測クラスラベルを出力します。

オブジェクト テーブルを作成するには、次のことを行う必要があります。

  • Cloud Storage バケットを作成し、金魚の画像をアップロードする。
  • オブジェクト テーブルへのアクセスに使用する Cloud リソース接続を作成する。
  • リソース接続のサービス アカウントへのアクセス権を付与する。

バケットを作成して画像をアップロードする

次の手順で Cloud Storage バケットを作成し、金魚の画像をアップロードします。

コンソール

  1. Google Cloud コンソールで、Cloud Storage の [バケット] ページに移動します。

    [バケット] に移動

  2. [ 作成] をクリックします。

  3. [バケットの作成] ページでユーザーのバケット情報を入力します。

    1. [始める] セクションで、次の操作を行います。

      1. ボックスに bqml_images を入力します。

      2. [続行] をクリックします。

    2. [データの保存場所の選択] セクションで、次の操作を行います。

      1. [ロケーション タイプ] で [マルチリージョン] を選択します。

      2. ロケーション タイプのメニューから、[US(米国の複数のリージョン)] を選択します。

      3. [続行] をクリックします。

    3. [データのストレージ クラスを選択する] セクションで、次の操作を行います。

      1. [デフォルトのクラスを設定する] を選択します。

      2. [標準] を選択します。

      3. [続行] をクリックします。

    4. 残りのセクションはデフォルト値のままにします。

  4. [作成] をクリックします。

コマンドライン

次の gcloud storage buckets create コマンドを入力します。

gcloud storage buckets create gs://bqml_images --location=us

リクエストが成功すると、コマンドから次のメッセージが返されます。

Creating gs://bqml_images/...

画像を Cloud Storage バケットにアップロードします。

バケットが作成されたら、金魚の画像をダウンロードして Cloud Storage バケットにアップロードします。

画像をアップロードする手順は次のとおりです。

コンソール

  1. Google Cloud コンソールで、Cloud Storage の [バケット] ページに移動します。

    [バケット] に移動

  2. バケットのリストで bqml_images をクリックします。

  3. バケットのオブジェクト タブで、次のいずれかを行います。

    • デスクトップまたはファイル マネージャーから Google Cloud コンソールのメインペインにファイルをドラッグします。

    • [アップロード] > [ファイルをアップロード] をクリックし、表示されたダイアログでアップロードする画像ファイルを選択してから、[開く] をクリックします。

コマンドライン

次の gcloud storage cp コマンドを入力します。

gcloud storage cp OBJECT_LOCATION gs://bqml_images/IMAGE_NAME

次のように置き換えます。

  • OBJECT_LOCATION: 画像ファイルのローカルパス。例: Desktop/goldfish.jpg
  • IMAGE_NAME: 画像の名前。例: goldfish.jpg

成功すると、レスポンスは次のようになります。

Completed files 1/1 | 164.3kiB/164.3kiB

BigQuery クラウド リソース接続を作成する

このチュートリアルの後半で作成するオブジェクト テーブルに接続するには、Cloud リソース接続が必要です。

Cloud リソース接続を使用すると、BigQuery の外部に保存されているデータをクエリできます。たとえば、Cloud Storage や Spanner などの Google Cloud サービス、または AWS や Azure などのサードパーティ ソースにあるデータです。これらの外部接続では、BigQuery Connection API を使用します。

Cloud リソース接続を作成する手順は次のとおりです。

コンソール

  1. [BigQuery Studio] ページに移動します。

    BigQuery Studio に移動

  2. 接続を作成するには、[追加] をクリックし、続いて [外部データソースへの接続] をクリックします。

  3. [接続タイプ] リストで、[Vertex AI リモートモデル、リモート関数、BigLake(Cloud リソース)] を選択します。

  4. [接続 ID] フィールドに「bqml_tutorial」と入力します。

  5. [マルチリージョン - US] が選択されていることを確認します。

  6. [接続を作成] をクリックします。

  7. ウィンドウの下部にある [接続に移動] をクリックします。または、[エクスプローラ] ペインで [外部接続] を開き、[us.bqml_tutorial] をクリックします。

  8. [接続情報] ペインで、サービス アカウント ID をコピーします。この ID は、接続の権限を構成するときに必要になります。接続リソースを作成すると、BigQuery は、一意のシステム サービス アカウントを作成し、それを接続に関連付けます。

bq

  1. 接続を作成するには:

    bq mk --connection --location=US --project_id=PROJECT_ID \
        --connection_type=CLOUD_RESOURCE bqml_tutorial

    PROJECT_ID は、実際の Google Cloud プロジェクト ID に置き換えます。--project_id パラメータは、デフォルト プロジェクトをオーバーライドします。

    接続リソースを作成すると、BigQuery は、一意のシステム サービス アカウントを作成し、それを接続に関連付けます。

    トラブルシューティング: 次の接続エラーが発生した場合は、Google Cloud SDK を更新します。

    Flags parsing error: flag --connection_type=CLOUD_RESOURCE: value should be one of...
    
  2. 後の手順で使用するため、サービス アカウント ID を取得してコピーします。

    bq show --connection PROJECT_ID.us.bqml_tutorial

    出力は次のようになります。

    name                          properties
    1234.REGION.CONNECTION_ID {"serviceAccountId": "connection-1234-9u56h9@gcp-sa-bigquery-condel.iam.gserviceaccount.com"}
    

接続アクセスを設定する

Cloud リソース接続のサービス アカウントに Storage オブジェクト管理者ロールを付与します。このロールは、リモートモデル エンドポイントを作成したプロジェクトで付与する必要があります。

ロールを付与する手順は次のとおりです。

  1. [IAM と管理] ページに移動します。

    [IAM と管理] に移動

  2. [アクセス権を付与] をクリックします。

  3. [新しいプリンシパル] フィールドに、前にコピーした Cloud リソース接続のサービス アカウント ID を入力します。

  4. [ロールを選択] フィールドで、[Cloud Storage] を選択し、続いて [Storage オブジェクト管理者] を選択します。

  5. [保存] をクリックします。

オブジェクト テーブルを作成する

Cloud Storage にアップロードした金魚の画像を使用して、goldfish_image_table という名前のオブジェクト テーブルを作成する手順は次のとおりです。

コンソール

  1. [BigQuery Studio] ページに移動します。

    BigQuery Studio に移動

  2. クエリエディタで、次のクエリを入力してオブジェクト テーブルを作成します。

    CREATE EXTERNAL TABLE `bqml_tutorial.goldfish_image_table`
    WITH CONNECTION `us.bqml_tutorial`
    OPTIONS(
    object_metadata = 'SIMPLE',
    uris = ['gs://bqml_images/IMAGE_NAME'],
    max_staleness = INTERVAL 1 DAY,
    metadata_cache_mode = 'AUTOMATIC');

    IMAGE_NAME は、画像ファイルの名前に置き換えます(例: goldfish.jpg)。

    オペレーションが完了すると、This statement created a new table named goldfish_image_table のようなメッセージが表示されます。

bq

  1. 次の CREATE EXTERNAL TABLE ステートメントを入力して、オブジェクト テーブルを作成します。

    bq query --use_legacy_sql=false \
    "CREATE EXTERNAL TABLE `bqml_tutorial.goldfish_image_table`
    WITH CONNECTION `us.bqml_tutorial`
    OPTIONS(
    object_metadata = 'SIMPLE',
    uris = ['gs://bqml_images/IMAGE_NAME'],
    max_staleness = INTERVAL 1 DAY,
    metadata_cache_mode = 'AUTOMATIC')"

    IMAGE_NAME は、画像ファイルの名前に置き換えます(例: goldfish.jpg)。

  2. オブジェクト テーブルを作成したら、データセットに表示されることを確認します。

    bq ls bqml_tutorial

    出力は次のようになります。

    tableId               Type
    --------------------- --------
    goldfish_image_table  EXTERNAL

詳細については、オブジェクト テーブルを作成するをご覧ください。

インポートした ONNX モデルを使用して予測を行う

ML.PREDICT 関数を含む次のクエリを使用して、入力オブジェクト テーブル goldfish_image_table の画像データから予測を行います。このクエリは、ImageNet ラベル辞書に基づいて入力画像の予測クラスラベルを出力します。

クエリでは、ML.PREDICT で解釈できるように画像データをデコードするために ML.DECODE_IMAGE 関数が必要です。ML.RESIZE_IMAGE 関数を呼び出して、モデルの入力サイズ(224*224)に合わせて画像のサイズを変更します。

画像オブジェクト テーブルで推論を実行する方法については、画像オブジェクト テーブルで推論を実行するをご覧ください。

画像データから予測を行う手順は次のとおりです。

コンソール

  1. [BigQuery Studio] ページに移動します。

    BigQuery Studio に移動

  2. クエリエディタで、次の ML.PREDICT クエリを入力します。

     SELECT
       class_label
     FROM
       ML.PREDICT(MODEL bqml_tutorial.imported_onnx_model,
         (
         SELECT
           ML.RESIZE_IMAGE(ML.DECODE_IMAGE(DATA),
             224,
             224,
             FALSE) AS input
         FROM
           bqml_tutorial.goldfish_image_table))
     

    クエリ結果は次のようになります。

    ML.PREDICT クエリの結果

bq

次の bq query コマンドを入力します。

bq query --use_legacy_sql=false \
'SELECT
  class_label
FROM
  ML.PREDICT(MODEL `bqml_tutorial.imported_onnx_model`,
    (
    SELECT
      ML.RESIZE_IMAGE(ML.DECODE_IMAGE(DATA),
        224,
        224,
        FALSE) AS input
    FROM
      bqml_tutorial.goldfish_image_table))'

クリーンアップ

このチュートリアルで使用したリソースについて、Google Cloud アカウントに課金されないようにするには、リソースを含むプロジェクトを削除するか、プロジェクトを維持して個々のリソースを削除します。

プロジェクトを削除する

コンソール

  1. In the Google Cloud console, go to the Manage resources page.

    Go to Manage resources

  2. In the project list, select the project that you want to delete, and then click Delete.
  3. In the dialog, type the project ID, and then click Shut down to delete the project.

gcloud

    Delete a Google Cloud project:

    gcloud projects delete PROJECT_ID

リソースを個別に削除する

または、このチュートリアルで使用したリソースを個別に削除するには、次の操作を行います。

  1. インポートしたモデルを削除します。

  2. (省略可)データセットを削除します。

  3. Cloud リソース接続を削除します

  4. Cloud Storage バケットを削除します

次のステップ