使用 ONNX 格式的 scikit-learn 模型进行预测

概览

开放神经网络交换 (ONNX) 提供了一种用于表示任何机器学习框架的统一格式。BigQuery ML 对 ONNX 的支持让您可以:

  • 使用您偏好的框架训练模型。
  • 将模型转换为 ONNX 模型格式。如需了解详情,请参阅转换为 ONNX 格式
  • 将 ONNX 模型导入 BigQuery 并使用 BigQuery ML 进行预测。

本教程介绍如何将使用 scikit-learn 训练的 ONNX 模型导入 BigQuery 数据集,并使用它们通过 SQL 查询进行预测。您可以使用以下界面导入 ONNX 模型:

如需详细了解如何将 ONNX 模型导入 BigQuery,包括格式和存储要求,请参阅用于导入 ONNX 模型的 CREATE MODEL 语句

目标

在此教程中,您将学习以下操作:

  • 使用 scikit-learn 创建和训练模型。
  • 使用 sklearn-onnx 将模型转换为 ONNX 格式。
  • 将 ONNX 模型导入 BigQuery 并进行预测。

使用 scikit-learn 训练分类模型

基于 Iris 数据集创建和训练 scikit-learn 流水线

import numpy
from sklearn.datasets import load_iris
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.ensemble import RandomForestClassifier

data = load_iris()
X = data.data[:, :4]
y = data.target

ind = numpy.arange(X.shape[0])
numpy.random.shuffle(ind)
X = X[ind, :].copy()
y = y[ind].copy()

pipe = Pipeline([('scaler', StandardScaler()),
                ('clr', RandomForestClassifier())])
pipe.fit(X, y)

将模型转换为 ONNX 格式并保存

使用 sklearn-onnx 将 scikit-learn 流水线转换为名为 pipeline_rf.onnx 的 ONNX 模型:

from skl2onnx import convert_sklearn
from skl2onnx.common.data_types import FloatTensorType

# Disable zipmap as it is not supported in BigQuery ML.
options = {id(pipe): {'zipmap': False}}

# Define input features. scikit-learn does not store information about the
# training dataset. It is not always possible to retrieve the number of features
# or their types. That's why the function needs another argument called initial_types.
initial_types = [
   ('sepal_length', FloatTensorType([None, 1])),
   ('sepal_width', FloatTensorType([None, 1])),
   ('petal_length', FloatTensorType([None, 1])),
   ('petal_width', FloatTensorType([None, 1])),
]

# Convert the model.
model_onnx = convert_sklearn(
   pipe, 'pipeline_rf', initial_types=initial_types, options=options
)

# And save.
with open('pipeline_rf.onnx', 'wb') as f:
 f.write(model_onnx.SerializeToString())

将 ONNX 模型上传到 Cloud Storage

创建一个 Cloud Storage 存储桶来存储 ONNX 模型文件,然后将已保存的 ONNX 模型文件上传到您的 Cloud Storage 存储桶。如需了解详情,请参阅从文件系统上传对象

将 ONNX 模型导入 BigQuery

此步骤假定您已将 ONNX 模型上传到 Cloud Storage 存储桶。示例模型存储在 gs://cloud-samples-data/bigquery/ml/onnx/pipeline_rf.onnx

控制台

  1. 在 Google Cloud 控制台中,转到 BigQuery 页面。

    前往 BigQuery 页面

  2. 在查询编辑器中输入 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/pipeline_rf.onnx')
    

    上述查询会导入位于 gs://cloud-samples-data/bigquery/ml/onnx/pipeline_rf.onnx 的 ONNX 模型作为名为 imported_onnx_model 的 BigQuery 模型。

  3. 现在,您的新模型应显示在资源面板中。在展开项目中的每个数据集时,模型将与数据集中的其他 BigQuery 资源一起列出。模型由模型图标 模型图标 表示。

  4. 如果您在资源面板中选择该新模型,则模型相关信息将显示在查询编辑器下方。

    onnx 模型信息

bq

如需从 Cloud Storage 导入 ONNX 模型,请输入如下命令来运行批量查询:

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/pipeline_rf.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/*')"
}

使用导入的 ONNX 模型进行预测

控制台

  1. 在 Google Cloud 控制台中,转到 BigQuery 页面。

    前往 BigQuery 页面

  2. 在查询编辑器中,使用 ML.PREDICT 输入查询,如下所示:

     SELECT *
       FROM ML.PREDICT(MODEL example_dataset.imported_onnx_model,
         (
          SELECT * FROM bigquery-public-data.ml_datasets.iris
         )
     )
     

    上述查询使用前项目的 example_dataset 数据集中名为 imported_onnx_model 的模型,以便根据 iris 公共表中的输入数据进行预测,该公共表位于 bigquery-public-data 项目的 ml_datasets 数据集中。在本例中,ONNX 模型需要四个浮点输入:sepal_lengthsepal_widthpetal_lengthpetal_width,它们与步骤 2 中定义的 initial_types 匹配,因此子查询 SELECT 包含这 4 个输入列的整个 bigquery-public-data 表。

    模型会输出 labelprobabilities 列以及输入表中的列。

    • label 表示预测的类标签。
    • probabilities 是一个概率数组,表示每个类别的概率。

    查询结果如下所示:

    查询结果

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))'

例如:

bq query \
--use_legacy_sql=false \
'SELECT *
FROM ML.PREDICT(
  MODEL `example_dataset.imported_onnx_model`,
  (SELECT * FROM `bigquery-public-data.ml_datasets.iris`))'

API

插入新作业并填充 jobs#configuration.query 属性,如以下请求正文所示:

{
  "query": "SELECT * FROM ML.PREDICT(MODEL `my_project.my_dataset.my_model`, (SELECT * FROM input_data))"
}

后续步骤