透過 BigQuery ML 將圖片資料分類

1. 簡介

在本程式碼研究室中,我們將討論在 BigQuery 中儲存及分析瑜珈姿勢圖片的用途,並使用 BigQuery ML 實作分類模型,只使用 SQL 建構函式標記姿勢,不使用其他形式的程式碼。

BigQuery 和 BQML

BigQuery 是無伺服器的多雲端資料倉儲,可從位元組擴充至 PB 級,且完全不需要作業管理。因此非常適合儲存機器學習訓練資料。此外,您還能使用內建的 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 Bucket 並儲存圖片
  • 如何建立 BigQuery 資料集、資料表和連線
  • 如何使用 BQML 建立圖片資料分類模型
  • 如何使用 BigQuery ML,透過建立的模型進行預測
  • 如何查詢圖片並使用 BigQuery SQL 合併結構化資料

2. 需求條件

  • ChromeFirefox 瀏覽器
  • 已啟用計費功能的 Google Cloud 雲端專案,其中包含 BigQuery、Cloud Storage 和 BigLake Connection 服務
  • 下一節列出建立圖片資料分類應用程式的步驟

3. 建立資料集和 BigLake 連線

在本應用範例中,我們使用公開的資料集偵測 5 種瑜珈姿勢的圖片,您可以從這個 repo 存取資料集。我們目前只會辨識下犬式、女神式、平板式、樹式和戰士 2 式。開始建立 BigQuery 資料集之前,請務必選取或建立 Google Cloud 專案,並檢查專案是否已啟用帳單啟用 BigQuery API 和 BigQuery Connection API。請注意,這項實作作業中使用的所有服務都應位於所選區域。

a. 按照下列步驟建立「yoga_set」資料集:

前往 BigQuery 編輯器,然後輸入指令:

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

b. BigLake 連線可讓我們連結外部資料來源,同時保留精細的 BigQuery 存取控管和安全性,在本例中,這是指圖片資料的 Cloud Storage。我們會使用這個連線從 Cloud Storage 讀取物件。請按照下列步驟建立 BigLake 連線。

在 BigQuery 頁面的「Explorer」窗格中,按一下「新增資料」:

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,然後按一下「Buckets」前往 Buckets 首頁,並點選「CREATE」

a6f6b26cffb53ae0.pngGoogle Cloud Storage 值區頁面

b. 在「建立 Bucket」頁面中,輸入 Bucket 資訊 (唯一名稱) 並繼續,確認 Bucket 與上述步驟中討論的資料集和連線位於相同區域,然後按一下「建立」

1280366a42b7bdf6.pngGoogle Cloud Storage 建立 bucket 頁面

前往下一個步驟前,請務必記下服務帳戶、bucket 名稱和路徑。

c. 建立 bucket 後,請儲存圖片 (透過控制台、Cloud Shell 指令或以程式輔助方式),並授予連線服務帳戶 (先前儲存的帳戶) 存取圖片的必要權限。

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

5. 建立物件資料表

從 BigQuery 建立外部物件資料表,透過我們建立的連線存取 bucket 中的非結構化資料。在 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 本機檔案」選項,即可匯出結果。然後開啟 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. 將這兩個項目 (檔案和資料夾) 上傳到我們在前一節建立的 bucket

2629ff3eda214946.png已上傳 ResNet 模型檔案的 Google Cloud Storage Bucket「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.pngBigQuery 資料集,列出已建立的模型

b. 檢查模型,查看其輸入和輸出欄位。

展開資料集,然後按一下我們剛建立的「yoga_poses_resnet」模型。按一下「結構定義」分頁標籤:

e88928764f10f6ff.png「BigQuery 模型定義結構定義」分頁

在「標籤」部分中,您會看到代表輸出欄位的「activation_49」欄位。在「特徵」部分中,您會看到「input_1」,代表預期輸入模型的欄位。您會在推論查詢 (或預測查詢) 中,將「input_1」做為傳遞「測試」資料的欄位。

c. 推斷瑜珈姿勢!

現在要使用剛建立的模型,分類測試圖片資料。請確認您已從 Cloud Storage Bucket 中找出一些測試圖片 (瑜珈姿勢),並在建立外部資料表時將這些圖片納入其中。我們將在 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

上圖輸出內容是指瑜珈姿勢「下犬式」,這與我們傳遞至 ML.PREDICT 查詢的測試輸入內容完全相同,可使用 BQML 進行分類!

8. 整合結構化和非結構化資料

最後,我最喜歡的實作部分是將結構化關聯式資料表中的欄位,與這項非結構化圖片資料合併。我在與外部資料表相同的資料集中,建立了結構化 BigQuery 資料表,用來存放姿勢和健康相關資料。

125bdf848c86fbe.pngBigQuery 結構化資料表「yoga_health」結構定義

上圖代表名為「yoga_health」的結構化資料表結構定義,欄位包括體位、重點、健康益處和呼吸。以下查詢會聯結結構化和非結構化資料:

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 中的其他端對端應用程式實作方式,請前往我的網誌