ONNX 形式の PyTorch モデルを使用して予測を行う
Open Neural Network Exchange(ONNX)は、ML フレームワークを統一された形式で表現するためのフォーマットです。ONNX に対する BigQuery ML サポートにより、次のことが可能になります。
- 使い慣れたフレームワークを使用してモデルをトレーニングします。
- モデルを ONNX 形式に変換します。詳細については、ONNX 形式への変換をご覧ください。
- ONNX モデルを BigQuery にインポートし、BigQuery ML を使用して予測を行います。
このチュートリアルでは、PyTorch でトレーニングされた ONNX モデルを BigQuery データセットにインポートし、SQL クエリから予測を行う方法について説明します。ONNX モデルのインポートに使用できるインターフェースは次のとおりです。
- Google Cloud コンソール
- bq コマンドライン ツールの
bq query
コマンド - BigQuery API
形式やストレージの要件など、ONNX モデルを BigQuery にインポートする方法については、ONNX モデルをインポートする CREATE
MODEL
ステートメントをご覧ください。
目標
このチュートリアルの内容は次のとおりです。
- PyTorch を使用してモデルの作成とトレーニングを行います。
- torch.onnx を使用してモデルを ONNX 形式に変換します。
- ONNX モデルを BigQuery にインポートして予測を行います。
画像分類用の 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 ビジョンモデルを resnet18.onnx
という名前の 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 にアップロードする
ONNX モデルファイルを保存する Cloud Storage バケットを作成し、保存した ONNX モデルファイルを Cloud Storage バケットにアップロードします。詳細については、ファイル システムからオブジェクトをアップロードするをご覧ください。
ONNX モデルを BigQuery にインポートする
この手順では、ONNX モデルが Cloud Storage バケットにアップロードされていることを前提としています。サンプルのモデルは gs://cloud-samples-data/bigquery/ml/onnx/resnet18.onnx
に保存されています。
コンソール
Google Cloud コンソールで [BigQuery] ページに移動します。
クエリエディタで、次のような
CREATE MODEL
ステートメントを入力します。CREATE OR REPLACE MODEL `mydataset.mymodel` OPTIONS (MODEL_TYPE='ONNX', MODEL_PATH='gs://bucket/path/to/onnx_model/*')
例:
CREATE OR REPLACE MODEL `example_dataset.imported_onnx_model` OPTIONS (MODEL_TYPE='ONNX', MODEL_PATH='gs://cloud-samples-data/bigquery/ml/onnx/resnet18.onnx')
上記のクエリでは、
gs://cloud-samples-data/bigquery/ml/onnx/resnet18.onnx
にある ONNX モデルをimported_onnx_model
という BigQuery モデルとしてインポートします。新しいモデルが [リソース] パネルに表示されます。プロジェクト内の各データセットを展開すると、データセット内の他の BigQuery リソースとともに、モデルが一覧表示されます。モデルにはモデルアイコン がついています。
[リソース] パネルで新しいモデルを選択すると、そのモデルに関する情報がクエリエディタの下に表示されます。
bq
ONNX モデルを Cloud Storage からインポートするには、次のようなコマンドを入力して、バッチクエリを実行します。
bq query \
--use_legacy_sql=false \
"CREATE MODEL
`mydataset.mymodel`
OPTIONS
(MODEL_TYPE='ONNX',
MODEL_PATH='gs://bucket/path/to/onnx_model/*')"
例:
bq query --use_legacy_sql=false \
"CREATE OR REPLACE MODEL
`example_dataset.imported_onnx_model`
OPTIONS
(MODEL_TYPE='ONNX',
MODEL_PATH='gs://cloud-samples-data/bigquery/ml/onnx/resnet18.onnx')"
モデルをインポートすると、bq ls [dataset_name]
の出力に表示されます。
$ bq ls example_dataset
tableId Type Labels Time Partitioning
--------------------- ------- -------- -------------------
imported_onnx_model MODEL
API
新しいジョブを挿入し、次に示すリクエストの本文のように jobs#configuration.query プロパティに値を入力します。
{
"query": "CREATE MODEL `project_id:mydataset.mymodel` OPTIONS(MODEL_TYPE='ONNX' MODEL_PATH='gs://bucket/path/to/onnx_model/*')"
}
BigQuery で画像データにアクセスするオブジェクト テーブルを作成する
BigQuery で非構造化データにアクセスするには、オブジェクト テーブルを作成する必要があります。詳しい手順については、オブジェクト テーブルの作成をご覧ください。
gs://mybucket/goldfish.jpg
に保存された goldfish イメージに、goldfish_image_table
という名前のオブジェクト テーブルを作成します。
CREATE EXTERNAL TABLE `example_dataset.goldfish_image_table`
WITH CONNECTION `us.my-connection`
OPTIONS(
object_metadata = 'SIMPLE',
uris = ['gs://mybucket/goldfish.jpg'],
max_staleness = INTERVAL 1 DAY,
metadata_cache_mode = 'AUTOMATIC');
インポートした ONNX モデルを使用して予測を行う
コンソール
Google Cloud コンソールで [BigQuery] ページに移動します。
クエリエディタで、次のように
ML.PREDICT
を使用してクエリを入力します。SELECT class_label FROM ML.PREDICT(MODEL
example_dataset.imported_onnx_model
, ( SELECT ML.RESIZE_IMAGE(ML.DECODE_IMAGE(DATA), 224, 224, FALSE) AS input FROM example_dataset.goldfish_image_table) )上記のクエリでは、現在のプロジェクトのデータセット
example_dataset
にあるimported_onnx_model
というモデルを使用して、入力オブジェクト テーブルgoldfish_image_table
にある画像データから予測を行います。ML.PREDICT
で解釈できるように画像データをデコードするには、ML.DECODE_IMAGE
関数が必要です。さらにML.RESIZE_IMAGE
関数を呼び出して、モデルの入力サイズ(224*224)に合わせて画像のサイズを変更します。画像オブジェクト テーブルで推論を実行する方法については、画像オブジェクト テーブルで推論を実行するをご覧ください。このクエリは、ImageNet ラベル辞書に基づいて入力画像の予測クラスラベルを出力します。
bq
テーブル input_data
の入力データから予測を行うには、インポートした ONNX モデル my_model
を使用して、次のようなコマンドを入力します。
bq query \
--use_legacy_sql=false \
'SELECT *
FROM ML.PREDICT(
MODEL `my_project.my_dataset.my_model`,
(SELECT * FROM input_data))'
API
新しいジョブを挿入し、次に示すリクエストの本文のように jobs#configuration.query プロパティに値を入力します。
{
"query": "SELECT * FROM ML.PREDICT(MODEL `my_project.my_dataset.my_model`, (SELECT * FROM input_data))"
}
次のステップ
- ONNX モデルのインポートの詳細については、ONNX モデルの
CREATE MODEL
ステートメントをご覧ください。 - 利用可能な ONNX コンバータとチュートリアルの詳細については、ONNX 形式への変換をご覧ください。
- BigQuery ML の概要で BigQuery ML の概要を確認する。
- BigQuery ML の使用を開始するには、BigQuery ML で機械学習モデルを作成するをご覧ください。
- モデルの操作の詳細については、次のリソースをご覧ください。