使用 BigQuery ML 进行图片数据分类

1. 简介

在此 Codelab 中,我们将讨论在 BigQuery 中存储和分析瑜伽姿势图片的使用场景,并使用 BigQuery ML 实现分类模型,以便仅使用 SQL 结构(而不是其他形式的代码)标记姿态。

BigQuery 和 BQML

BigQuery 是一种无服务器的多云数据仓库,能从字节扩容到拍字节,且不会产生运维开销。这使其成为存储机器学习训练数据的绝佳选择。此外,内置的 BigQuery 机器学习 (BQML) 和分析功能可让您仅使用 SQL 查询创建无代码预测。您还可以通过联合查询从外部来源访问数据,从而无需复杂的 ETL 流水线。您可以在 BigQuery 页面详细了解 BigQuery 提供的所有功能。

到目前为止,我们知道 BigQuery 是一个全代管式云数据仓库,可帮助用户分析结构化和半结构化数据。但是,

  • BigQuery 也已扩展,可对非结构化数据执行所有分析和机器学习
  • 我们可以使用 SQL 查询大规模地对图片、视频和音频等执行富有见解的分析、分析和机器学习,而无需编写额外的代码
  • 我们能够将结构化数据和非结构化数据组合在一起,就像它们一起存在于同一个表中

我们将在下一部分介绍瑜伽姿势分类用例。

使用 BigQuery ML 进行图片数据分类

能够使用结构化查询处理和分析图片,就像它们是结构化数据一样。现在,我们甚至可以使用 BigQuery ML 通过机器学习分类模型来预测结果。为便于理解,我已将相关阶段缩减为 5 个步骤:

fe97945bce996e1.jpeg

如果只将它们作为标签,上述步骤可能会很复杂。 实施部分定义了每个相关组件的详细信息,例如 BigQuery 数据集、BigLake 连接、Cloud Storage 存储桶(容器)、对象表(外部数据源)、BQML 等。因此,如果您还不熟悉这些术语,请不要气馁。

您将构建的内容

您将使用 BQML 创建一个涵盖以下内容的图片数据分类模型:

  • 包含表和模型组件的 BigQuery 数据集
  • 为模型存储瑜伽图片的 Google Cloud Storage (GCS) 存储桶
  • 用于访问 Cloud Storage 图片的外部表
  • 外部表的 BigLake 连接,用于访问 GCS 中的图片
  • BigQuery ML 中的 ResNet 模型
  • 使用创建的模型进行推断
  • 用于分析图片数据的 BigQuery SQL
  • 用于同时查询结构化数据和非结构化数据的 BigQuery SQL

学习内容

  • 如何创建 Cloud Storage 存储桶和存储图片
  • 如何创建 BigQuery 数据集、表和连接
  • 如何使用 BQML 创建图片数据分类模型
  • 如何使用 BigQuery ML 根据所创建的模型进行预测
  • 如何使用 BigQuery SQL 查询图片并将其与结构化数据结合使用

2. 要求

  • 一个浏览器,例如 ChromeFirefox
  • 启用了结算功能的 Google Cloud 项目,其中包含您的 BigQuery、Cloud Storage 和 BigLake Connection 服务
  • 下一部分列出了创建图片数据分类应用的步骤

3. 创建数据集和 BigLake 连接

针对 5 种瑜伽姿势的图片检测用例,我使用了公开提供的数据集,您可以从此代码库访问该数据集。我们识别的瑜伽姿势仅限于 Downdog、Goddess、Plank、Tree 和 Warrior2。在开始创建 BigQuery 数据集之前,请务必选择或创建 Google Cloud 项目,并检查该项目是否启用了结算功能。启用 BigQuery API 和 BigQuery Connection API。请注意,此实现中使用的所有服务应该位于同一区域。

a.按照以下步骤创建数据集“yoga_set”:

转到 BigQuery 编辑器并输入命令:

CREATE SCHEMA `<<project_id>>.yoga_set`;

b. 借助 BigLake Connection,我们可以连接外部数据源,同时保留精细的 BigQuery 访问权限控制和安全性(在本例中为存储图片数据的 Cloud Storage)。我们将使用此连接从 Cloud Storage 中读取对象。请按照以下步骤创建 BigLake 连接。

在 BigQuery 页面的“探索器”窗格中点击“添加数据”:

4cb42b1245bb0ba6.pngBigQuery“添加外部数据”屏幕

点击与外部数据源的连接,然后选择 BigLake 和远程函数选项:

9ffec2b2bfcc3cd5.png配置外部数据源连接

提供连接 ID 并创建连接。请记下创建连接后将显示在屏幕上的服务帐号 ID <<SERVICE_ACCOUNT>>。在此示例中,连接 ID 为“yoga-pose-conn”。请务必记下区域。

4. 创建 Google Cloud Storage 存储桶并授予权限

我们将使用 Google Cloud Storage 存储桶来包含我们将在其上创建模型的瑜伽姿势的图片文件。存储桶是 Cloud Storage 容器,用于存储我们要分析的图片。

a.转到 Google Cloud Storage(方法是在控制台中进行搜索),再点击“存储桶”以转到“存储桶”首页,然后点击“创建”

a6f6b26cffb53ae0.png Google Cloud Storage 存储桶页面

b. 在“创建存储桶”页面上,输入您的存储桶信息(唯一名称),然后继续操作,确保它与上述步骤中讨论的数据集和连接位于同一区域,然后点击“创建”

1280366a42b7bdf6.png Google Cloud Storage 创建存储桶页面

在执行下一步之前,请确保您已记录了服务帐号、存储桶名称和路径。

c.创建存储桶后,请存储您的图片(通过控制台或 Cloud Shell 命令存储,或以编程方式存储),然后为连接的服务帐号(我们之前保存的服务帐号)授予访问图片所需的权限

> export sa=<<"SERVICE_ACCOUNT">>
> gsutil iam ch serviceAccount:$sa:objectViewer "gs://<<bucket>>"

5. 创建对象表

通过 BigQuery 创建外部对象表,以使用我们创建的连接访问存储桶中的非结构化数据。从 BigQuery 编辑器运行以下 CREATE SQL:

CREATE OR REPLACE EXTERNAL TABLE `<<dataset>>.<<table_name>>`
WITH CONNECTION `us.<<connection-name>>`
OPTIONS(
object_metadata="SIMPLE", uris=["gs://<<bucket>>/<<folder_if_exists>>/*.jpg"]);

创建外部表,如下所示:

bda48f566e0c292f.png

让我们从新创建的外部表中快速查询姿势:

SELECT data , uri
FROM `yoga_set.yoga_poses`
WHERE REGEXP_CONTAINS(uri, 'gs://yoga_images/Downdog')
Limit 1;

如下面的屏幕截图所示,您可以创建和处理非结构化图片,就像它们是结构化数据一样:

7d1784122b5013f.png

现在,我们将上述查询结果导出到小型 Python 代码段中,以直观呈现结果:

点击“保存结果”,然后选择“CSV Localfile”选项以导出结果。然后,打开您的 Colab 笔记(或创建一个),并输入以下代码

from IPython.display import display
from PIL import Image
import io
import pandas as pd
import base64
df = pd.read_csv('/content/sample_data/<<your_csv>>')
imgdata = base64.b64decode(str(df.data[0]))
image = Image.open(io.BytesIO(imgdata))
display(image)

执行以查看如下所示的结果:

b8edd68cb281786a.png

现在我们已经创建了外部表,并只使用 SQL 查询访问 Cloud Storage 中的图片,接下来我们讨论创建分类模型的下一部分。

6. 创建模型并将其上传到 Google Cloud Storage

对于此实现,我们将使用预训练的 ResNet 50 模型对我们刚刚创建的对象表进行推断。ResNet 50 模型会分析图片文件并输出一批向量,这些向量代表图片属于相应类别的可能性 (logits)。

在执行此步骤之前,请确保您已具备所有必要的权限。然后按以下步骤操作:

  1. 从此位置下载模型并将其保存到本地
  2. 应将此文件解压缩到 saved_model.pb 和变量文件夹中
  3. 将这两项(文件和文件夹)上传到我们在上一部分中创建的存储桶

2629ff3eda214946.png 上传了 ResNet 模型文件的 Google Cloud Storage 存储桶“yoga_images”

完成此步骤后,您的模型相关文件应该存在于您的图片所在的存储桶中(如上图所示)。

7. 将模型加载到 BQML 和推断中

在此步骤中,我们会将模型加载到我们之前创建的外部表所在的 BigQuery 数据集中,并将其应用于我们存储在 Cloud Storage 中的图片。

a.在 BigQuery 编辑器中,运行以下 SQL 语句

CREATE MODEL `<<Dataset>>.<<Model_Name>>`
OPTIONS(
model_type = 'TENSORFLOW',
model_path = 'gs://<<Bucket>>/*');

执行完成后(这可能需要一段时间,具体取决于您的数据集),您将看到 BigQuery 的“数据集”部分中列出了该模型。

435fa0919aeb57a6.png 列出已创建模型的 BigQuery 数据集

b. 检查模型以查看其输入和输出字段。

展开数据集,然后点击我们刚刚创建的模型“yoga_poses_resnet”。点击“架构”标签页:

e88928764f10f6ff.png BigQuery 模型定义架构标签页

在“标签”部分,您会看到表示输出字段的“activation_49”字段。在“特征”部分中,您可以看到表示预期要输入到模型中的字段的“input_1”。您将在推断查询(或预测查询)中将“input_1”引用为您为“测试”数据传入的字段。

c.推断您的瑜伽姿势!

我们使用刚刚创建的模型对测试图片数据进行分类。确保您有一些从您的 Cloud Storage 存储桶中识别出的测试图片(瑜伽姿势),这些图片在我们创建外部表后保存到了其中。我们将在 BigQuery 中有选择地查询这些测试图片,以使用我们刚刚创建的 BQML 模型进行推理。使用以下查询触发测试。

SELECT *
FROM ML.PREDICT(
MODEL yoga_set.yoga_poses_resnet,
(SELECT uri, ML.DECODE_IMAGE(data) AS input_1
FROM yoga_set.yoga_poses where REGEXP_CONTAINS(uri,
'gs://yoga_images/Downdog/00000097.jpg')));

在上面的查询中,我们选择了一张被识别为在外部表中包含特定 URI 值的测试图片 (00000097.jpg)。此外,SELECT 部分使用 ML.DECODE_IMAGE 构造作为字段“input_1”,以便 ML.PREDICT 函数正常运行。

执行完成后,您会看到如下所示的结果:

867018993845e943.png

现在,对于深入了解 ResNet 模型的人员,这应该有助于理解分类。否则,我们可以编写一小段代码,直观地了解分类。

d. 展平结果

上述输出结果的一种可视化方法是使用 BigQuery SQL 的 UNNEST 结构展平 activation_49 字段值。请参阅下方的查询,了解如何展平上一步中的结果。如果您想进一步对生成的类添加文本标签,则可以引入逻辑来代替查询中的占位符 <<LABEL_LOGIC>>(请在使用时取消备注)。

with predictions as (
SELECT
Uri, data, SPLIT(uri, "/")[OFFSET(ARRAY_LENGTH(SPLIT(uri, "/")) - 1)] as img,
i as label_i,
<<LABEL_LOGIC>> label,
Score
FROM ML.PREDICT(
MODEL yoga_set.yoga_poses_resnet,
(SELECT data, uri, ML.DECODE_IMAGE(data) AS input_1
FROM yoga_set.yoga_poses
WHERE
REGEXP_CONTAINS(uri,'gs://yoga_images/Goddess/00000007.jpg'))),
UNNEST(activation_49) as score WITH OFFSET i)
SELECT * FROM predictions
ORDER BY score DESC
LIMIT  5;

如果没有类标签逻辑,查询的输出如下所示:

71f580f41f0811f3.png

不过,在本例中,我应用了示例逻辑,结果如下:

1c6df6ecd14fba1.png

您可以进一步了解该模型,并应用最适合您的数据和模型输出的逻辑。

e。 直观呈现推断

最后,您需要编写一个简短的 Python 代码段来直观呈现分类结果!将上述查询结果导出为 CSV 文件,并在 Python 代码中引用。

68756e7e4b8d7a29.png

上面的图片输出引用了瑜伽姿势“Downward Dog”,它与我们传入 ML.PREDICT 查询以使用 BQML 进行分类的测试输入完全相同。

8. 统一结构化数据和非结构化数据

最后,此实现中我最喜欢的部分是将我的结构化关系表中的字段与此非结构化图片数据统一起来。我在与外部表相同的数据集中创建了一个结构化 BigQuery 表,用于存放姿势及其健康相关数据。

125bdf848c86fbe.png BigQuery 结构化表“yoga_health”架构

上图显示了名为“yoga_health”的结构化数据表的架构,这些字段包括“姿势”“焦点”“health_benefit”和“呼吸”。以下查询会联接结构化数据和非结构化数据:

SELECT SPLIT(uri, "/")[OFFSET(ARRAY_LENGTH(SPLIT(uri, "/")) - 2)] as pose,
a.health_benefit, breath, focus, data
FROM `abis-345004.yoga_set.yoga_health` a, yoga_set.yoga_poses b
WHERE a.pose = SPLIT(uri, "/")[OFFSET(ARRAY_LENGTH(SPLIT(uri, "/")) - 2)];

结果如下:

469bdfcffa9e19fd.png

注意:本博客中提到的所有查询都可以使用 BigQuery Magic 命令直接从 Python 笔记本运行。

9. 清理

为避免系统因本博文中使用的资源向您的 Google Cloud 帐号收取费用,请按照以下步骤操作。

  1. 在 Google Cloud 控制台中,进入管理资源页面
  2. 在项目列表中,选择要删除的项目,然后点击“删除”
  3. 在对话框中输入项目 ID,然后点击“关停”以删除项目

10. 恭喜

恭喜!您已在 BigQuery 中成功存储、查询了非结构化数据、使用 BQML 创建了分类模型,并使用模型预测了测试瑜伽姿势。如果您想实现此功能,请着手您的 Google Cloud 项目。此外,如果您想详细了解 Google Cloud 中的数据库或其他端到端应用实现,请转到我的博客