对图片对象表运行推断

本文档介绍如何使用 BigQuery ML 对图片对象表运行推断。

概览

您可以将对象表作为 ML.PREDICT 函数的输入来对图片数据运行推断。

为此,您必须先选择适当的模型,将其上传到 Cloud Storage,然后运行 CREATE MODEL 语句将其导入 BigQuery。您可以创建自己的模型,也可以从 TensorFlow Hub 下载一个模型。

限制

  • 只有对预留使用基于容量的价格时,才支持在对象表上使用 BigQuery ML 功能;不支持按需价格。
  • 与对象表关联的图片文件必须满足以下要求:
    • 大小不超过 20 MB。
    • 采用 JPEG、PNG 或 BMP 格式。
  • 与对象表关联的图片文件的总大小必须小于 1 TB。
  • 模型必须是以下模型中的一个:

  • 模型必须满足支持的输入中所述的输入要求和限制。

  • 模型的序列化大小必须小于 450 MB。

  • 模型的反序列化(内存)大小必须小于 1,000 MB。

  • 模型输入张量必须符合以下条件:

    • 数据类型为 tf.float32 且值为 [0, 1),或者数据类型为 tf.uint8 且值为 [0, 255)
    • 形状为 [batch_size, weight, height, 3],其中:
      • batch_size 必须为 -1None1
      • widthheight 必须大于 0。
  • 模型必须使用以下一个颜色空间中的图片进行训练:

    • RGB
    • HSV
    • YIQ
    • YUV
    • GRAYSCALE

    您可以使用 ML.CONVERT_COLOR_SPACE 函数将输入图片转换为训练模型所用的颜色空间。

示例模型

TensorFlow Hub 中的以下模型可与 BigQuery ML 和图片对象表搭配使用:

所需权限

  • 如需将模型上传到 Cloud Storage,您需要拥有 storage.objects.createstorage.objects.get 权限。
  • 如需将模型加载到 BigQuery ML 中,您需要以下权限:

    • bigquery.jobs.create
    • bigquery.models.create
    • bigquery.models.getData
    • bigquery.models.updateData
  • 如需运行推断,您需要以下权限:

    • 对象表的 bigquery.tables.getData 权限
    • 模型的 bigquery.models.getData 权限
    • bigquery.jobs.create

准备工作

  1. 登录您的 Google Cloud 账号。如果您是 Google Cloud 新手,请创建一个账号来评估我们的产品在实际场景中的表现。新客户还可获享 $300 赠金,用于运行、测试和部署工作负载。
  2. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  3. 确保您的 Google Cloud 项目已启用结算功能

  4. 启用 BigQuery and BigQuery Connection API API。

    启用 API

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

    Go to project selector

  6. 确保您的 Google Cloud 项目已启用结算功能

  7. 启用 BigQuery and BigQuery Connection API API。

    启用 API

将模型上传到 Cloud Storage

请按照以下步骤上传模型:

  1. 如果您已创建自己的模型,请将其保存在本地。如果您要使用 TensorFlow Hub 中的模型,请将模型下载到本地机器。如果您要使用 TensorFlow,则应该获得模型的 saved_model.pb 文件和 variables 文件夹。
  2. 如有必要,请创建 Cloud Storage 存储桶
  3. 将模型工件上传到该存储桶。

将模型加载到 BigQuery ML 中

加载适用于图片对象表的模型与加载适用于结构化数据的模型相同。请按照如下步骤将模型加载到 BigQuery ML 中:

CREATE MODEL `PROJECT_ID.DATASET_ID.MODEL_NAME`
OPTIONS(
  model_type = 'MODEL_TYPE',
  model_path = 'BUCKET_PATH');

请替换以下内容:

  • PROJECT_ID:您的项目 ID。
  • DATASET_ID:包含模型的数据集的 ID。
  • MODEL_NAME:模型的名称。
  • MODEL_TYPE:请使用下列其中一个值:
    • TENSORFLOW 适用于 TensorFlow 模型
    • ONNX 适用于 ONNX 格式的 PyTorch 模型
  • BUCKET_PATH:包含模型的 Cloud Storage 存储桶的路径,格式为 [gs://bucket_name/[folder_name/]*]

以下示例使用默认项目并将 TensorFlow 模型 my_vision_model 加载到 BigQuery ML 中(使用 gs://my_bucket/my_model_folder 中的 saved_model.pb 文件和 variables 文件夹):

CREATE MODEL `my_dataset.my_vision_model`
OPTIONS(
  model_type = 'TENSORFLOW',
  model_path = 'gs://my_bucket/my_model_folder/*');

检查模型

您可以检查上传的模型,以查看其输入和输出字段是什么。在对象表上运行推断时,您需要引用这些字段。

请按照以下步骤检查模型:

  1. 转到 BigQuery 页面。

    转到 BigQuery

  2. 探索器窗格中,展开您的项目,展开包含模型的数据集,然后展开模型节点。

  3. 点击该模型。

  4. 在打开的模型窗格中,点击架构标签页。

  5. 查看标签部分。这会标识模型输出的字段。

  6. 查看特征部分。这标识了必须输入模型的字段。您可以在 ML.DECODE_IMAGE 函数的 SELECT 语句中引用它们。

如需对 TensorFlow 模型进行更详细的检查(例如确定模型输入的形状),请安装 TensorFlow 并使用 saved_model_cli show 命令

预处理图片

您必须使用 ML.DECODE_IMAGE 函数将图片字节转换为多维 ARRAY 表示形式。您可以直接在 ML.PREDICT 函数中使用 ML.DECODE_IMAGE 输出,或者将 ML.DECODE_IMAGE 中的结果写入表列,然后在调用时 ML.PREDICT 引用该列。

以下示例将 ML.DECODE_IMAGE 函数的输出写入表中:

CREATE OR REPLACE TABLE mydataset.mytable AS (
  SELECT ML.DECODE_IMAGE(data) AS decoded_image FROM mydataset.object_table
  );

使用以下函数进一步处理图片,以便它们适合您的模型:

您可以在 ML.PREDICT 函数中使用这些函数,也可以对包含 ML.DECODE_IMAGE 输出的图片数据的表列运行这些函数。

运行推断

加载适当的模型并根据需要预处理图片数据后,您可以对图片数据运行推断。

如需运行推断,请使用以下代码:

SELECT *
FROM ML.PREDICT(
  MODEL `PROJECT_ID.DATASET_ID.MODEL_NAME`,
  (SELECT [other columns from the object table,] IMAGE_DATA AS MODEL_INPUT
  FROM PROJECT_ID.DATASET_ID.TABLE_NAME)
);

请替换以下内容:

  • PROJECT_ID:包含模型和对象表的项目的 ID。
  • DATASET_ID:包含模型和对象表的数据集的 ID。
  • MODEL_NAME:模型的名称。
  • IMAGE_DATA:图片数据,由 ML.DECODE_IMAGE 函数的输出,或者由 ML.DECODE_IMAGE 或其他图片处理函数输出的包含图片数据的表列表示。
  • MODEL_INPUT:模型的输入字段的名称。您可以通过检查模型并查看功能部分的字段名称找到此信息。
  • TABLE_NAME:对象表的名称。

示例

示例 1

以下示例直接在 ML.PREDICT 函数中使用 ML.DECODE_IMAGE 函数。它会返回输入字段为 input 且输出字段为 feature 的模型对于对象表中所有图片的推断结果:

SELECT * FROM
ML.PREDICT(
  MODEL `my_dataset.vision_model`,
  (SELECT uri, ML.RESIZE_IMAGE(ML.DECODE_IMAGE(data), 480, 480, FALSE) AS input
  FROM `my_dataset.object_table`)
);

示例 2

以下示例直接在 ML.PREDICT 函数中使用 ML.DECODE_IMAGE 函数,在 ML.PREDICT 函数中使用 ML.CONVERT_COLOR_SPACE 函数,将图片颜色空间从 RBG 转换为 YIQ。该示例还介绍了如何使用对象表字段过滤推断中包含的对象。 它会返回输入字段为 input 且输出字段为 feature 的模型对于对象表中所有 JPG 图片的推断结果:

SELECT * FROM
  ML.PREDICT(
    MODEL `my_dataset.vision_model`,
    (SELECT uri, ML.CONVERT_COLOR_SPACE(ML.RESIZE_IMAGE(ML.DECODE_IMAGE(data), 224, 280, TRUE), 'YIQ') AS input
    FROM `my_dataset.object_table`
    WHERE content_type = 'image/jpeg')
  );

示例 3

以下示例使用已写入表列但尚未进一步处理的 ML.DECODE_IMAGE 中的结果。它在 ML.PREDICT 函数中使用 ML.RESIZE_IMAGEML.CONVERT_IMAGE_TYPE 来处理图片数据。它会返回输入字段为 input 且输出字段为 feature 的模型对于解码图片表中所有图片的推断结果。

创建解码图片表:

CREATE OR REPLACE TABLE `my_dataset.decoded_images`
  AS (SELECT ML.DECODE_IMAGE(data) AS decoded_image
  FROM `my_dataset.object_table`);

对解码图片表运行推断:

SELECT * FROM
ML.PREDICT(
  MODEL`my_dataset.vision_model`,
  (SELECT uri, ML.CONVERT_IMAGE_TYPE(ML.RESIZE_IMAGE(decoded_image, 480, 480, FALSE)) AS input
  FROM `my_dataset.decoded_images`)
);

示例 4

以下示例使用已写入表列并使用 ML.RESIZE_IMAGE 预处理的 ML.DECODE_IMAGE 中的结果。它会返回输入字段为 input 且输出字段为 feature 的模型对于解码图片表中所有图片的推断结果。

创建表:

CREATE OR REPLACE TABLE `my_dataset.decoded_images`
  AS (SELECT ML.RESIZE_IMAGE(ML.DECODE_IMAGE(data) 480, 480, FALSE) AS decoded_image
  FROM `my_dataset.object_table`);

对解码图片表运行推断:

SELECT * FROM
ML.PREDICT(
  MODEL `my_dataset.vision_model`,
  (SELECT uri, decoded_image AS input
  FROM `my_dataset.decoded_images`)
);

示例 5

以下示例直接在 ML.PREDICT 函数中使用 ML.DECODE_IMAGE 函数。在此示例中,模型具有输出字段 embeddings 和两个输入字段:一个接受图片 f_img,另一个接受字符串 f_txt。图片输入来自对象表,字符串输入来自使用 uri 列与对象表联接的标准 BigQuery 表。

SELECT * FROM
  ML.PREDICT(
    MODEL `my_dataset.mixed_model`,
    (SELECT uri, ML.RESIZE_IMAGE(ML.DECODE_IMAGE(my_dataset.my_object_table.data), 224, 224, FALSE) AS f_img,
      my_dataset.image_description.description AS f_txt
    FROM `my_dataset.object_table`
    JOIN `my_dataset.image_description`
    ON object_table.uri = image_description.uri)
  );

后续步骤