コンテンツに移動
データ分析

BigQuery ML を利用して画像データの分類モデルを構築する

2023年6月13日
Google Cloud Japan Team

※この投稿は米国時間 2023 年 6 月 2 日に、Google Cloud blog に投稿されたものの抄訳です。

非構造化画像データの取得、保存、分類には、数え切れないほどの活用事例があります。例を挙げると、行方不明者を探すためのソーシャル メディア分析や、交通状況を監視するための画像分析、e コマースでおすすめ商品を表示するためのメディア分析などです。多くの企業が完全なデータドリブンを実現できていないのは、生成されるデータの大半が構造化されておらず、データの種類と形式を複数扱う大規模分析では、エンタープライズ アプリケーションにいくつかの制約が存在するためです。1)データの保存と管理、2)インフラストラクチャの管理、3)データ サイエンスのリソースの確保といった面が制約となります。このたび、BigQuery に新しい非構造化データ分析機能が追加され、非構造化データの保存、処理、分析、モデル化、予測が可能になりました。また、非構造化データと構造化データと組み合わせてクエリに使用することもできます。そして何より、このすべてをコードなしで、SQL のみで行うことができます。

このブログでは、ヨガのポーズの画像を BigQuery に保存し分析するという事例を取り上げ、BigQuery ML で分類モデルを実装し、SQL コンストラクトのみでポーズにラベルを付けていきます。

BigQuery と BQML

BigQuery はサーバーレスのマルチクラウド データ ウェアハウスで、運用上のオーバーヘッドを発生させずにバイトからペタバイトまでスケーリングできます。そのため、ML トレーニング データの保存に最適です。さらに、組み込みの BigQuery ML(BQML)と種々の分析機能により、コードを使用せずに SQL クエリのみを使って予測を作成できます。また、連携クエリを使用して外部ソースからデータにアクセスできるため、複雑な ETL パイプラインが不要になります。BigQuery が提供する機能については、BigQuery ページで詳しくご紹介しています。

現在のところ BigQuery は、ユーザーが構造化データと半構造化データを分析することを支援する、フルマネージドのクラウド データ ウェアハウスとして知られています。しかし、機能はそれだけではありません。

  1. BigQuery は、非構造化データに対してもあらゆる分析と ML を実行できるように拡張されてきました。
  2. 特別なコードを書くことなく、SQL クエリを使用して画像や動画、オーディオなどに対して、インサイトを得るための分析および ML を大規模に実行できます。
  3. 構造化データと非構造化データを、まるで 1 つのテーブルにすべて存在しているかのように組み合わせることが可能です。

次のセクションでは、ヨガのポーズの分類の事例を使って、これらについて説明します。

BigQuery ML による画像データの分類

画像データに関連する「構造化」クエリの機能がこのたび初めて導入され、BigQuery ML の機械学習による分類モデルを結果の予測に使用できるようになりました。わかりやすいように、関連するステージを 5 つのステップに分類しました。

https://storage.googleapis.com/gweb-cloudblog-publish/images/01-20230613ja.max-1100x1100.png

1. データセットと BigLake の接続を作成する

5 種類のヨガポーズの画像検出を目指すこの事例では、一般公開されているデータセットを使用しました。そのデータセットには、このリポジトリからアクセスできます。検出するヨガポーズは、ダウンドッグのポーズ、女神のポーズ、板のポーズ、木のポーズ、戦士のポーズ 2 です。

BigQuery のデータセットの作成を開始する前に、Google Cloud プロジェクトを選択または作成し、そのプロジェクトで課金が有効になっているかどうかを確認してください。BigQuery API と BigQuery Connection API を有効にします。

a. 以下のステップで、データセット「yoga_set」を作成します。

https://storage.googleapis.com/gweb-cloudblog-publish/images/02-20230613ja.max-1600x1600.png

b. BigLake 接続によって、きめ細かい BigQuery アクセス制御とセキュリティを保ったまま、外部のデータソースに接続できます。この事例では Cloud Storage に接続し、画像データをオブジェクトとして読み込みます。以下のステップに従って、BigLake 接続を作成します。

BigQuery ページの [エクスプローラ] ペインで [追加] をクリックします。

https://storage.googleapis.com/gweb-cloudblog-publish/images/03-20230613ja.max-2100x2100.png

[外部データソースへの接続] をクリックして、[BigLake とリモート関数] を選択します。

https://storage.googleapis.com/gweb-cloudblog-publish/images/04-20230613ja.max-2000x2000.png

接続名を入力して、接続を作成します。このプロセスで作成されるサービス アカウント ID を忘れずにメモしておいてください。

2. Cloud Storage バケットを作成し、アクセス権限を付与する

Cloud Storage バケットを使用して、モデルを作りたいヨガポーズの画像ファイルを格納します。

a. Cloud Storage バケットのページで、[作成] をクリックします。

https://storage.googleapis.com/gweb-cloudblog-publish/images/05-20230613ja.max-1500x1500.png

b. [バケットの作成] ページで、バケットの情報を入力し、[続行] をクリックします。そして、バケットが前のステップで説明したデータセットおよび接続と同じリージョンにあることを確認して、[作成] をクリックします。

https://storage.googleapis.com/gweb-cloudblog-publish/images/06-20230613ja.max-1200x1200.png

c. バケットが作成されたら、(コンソールか Cloud Shell コマンドで、またはプログラマティックな方法で)画像を保存し、接続のサービス アカウント(先ほど ID を書き留めたもの)に画像にアクセスするうえで必要な権限を付与します。

> export sa="yourServiceAccountId@email.address"

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

3. オブジェクト テーブルを作成する

BigQuery から、作成した接続を使用してバケット内の非構造化データにアクセスするための外部オブジェクト テーブルを作成します。BigQuery エディタから以下の CREATE SQL を実行します。

読み込んでいます...

以下に示すように外部テーブルが作成されます。

https://storage.googleapis.com/gweb-cloudblog-publish/images/07-20230613ja.max-1100x1100.png

さっそく、新しく作成したテーブルからヨガポーズを抽出するクエリを作成してみましょう。

読み込んでいます...

以下のスクリーンショットからわかるように、非構造化データをそれが構造化データであるかのように作成し、操作できます。

https://storage.googleapis.com/gweb-cloudblog-publish/images/08-20230613ja.max-1200x1200.png

上記のクエリの結果を小さな Python スニペットにエクスポートして、結果を可視化してみましょう。

https://storage.googleapis.com/gweb-cloudblog-publish/images/09-20230613ja.max-1400x1400.png

これで、SQL クエリだけを使用して、Cloud Storage から外部テーブルを作成し、画像にアクセスすることができました。それでは次のセクションに進みましょう。次のセクションでは分類モデルを作成します。

4. モデルを作成し、Cloud Storage にアップロードする

トレーニング済みの ResNet 50 モデルを使用して、先ほど作成したオブジェクト テーブルに対して推論を実行します。ResNet 50 モデルは、画像ファイルを解析し、ある画像が対応するクラスに属する可能性を表す一連のベクトル(ロジット)を出力します。

このステップに移る前に、必要な権限がすべて付与されていることを確認してください。確認できたら、以下の手順で操作してください。

a. この場所からモデルをダウンロードして、ローカルに保存します。

b. ダウンロードしたものを解凍すると、saved_model.pb と variables フォルダがあります。

c. これら 2 つ(ファイルとフォルダ)を、先ほどのセクションで作成したバケットにアップロードします。

https://storage.googleapis.com/gweb-cloudblog-publish/images/10-20230613ja.max-1900x1900.png

このステップが完了すると、モデルに関連したファイルが、上の画像に表示されているものと同じバケット内に存在しているはずです。

5. BQML にモデルを読み込み、推論を実行する

このステップでは、先ほど作成した外部テーブルと同じ BigQuery データセットにモデルを読み込み、Cloud Storage に保存した画像に適用します。

a. BigQuery エディタから、次の SQL ステートメントを実行します。

読み込んでいます...

実行が完了すると、BigQuery 内のデータセットのセクションにモデルが表示されます。

https://storage.googleapis.com/gweb-cloudblog-publish/images/11-20230613ja.max-2100x2100.png

b. モデルを調べて、その入力フィールドと出力フィールドを確認します。データセットを開き、先ほど作成したモデル「yoga_poses_resnet」を選択して、[スキーマ] タブをクリックします。

https://storage.googleapis.com/gweb-cloudblog-publish/images/12-20230613ja.max-1500x1500.png

[ラベル] セクションに、出力フィールドを表す「activation_49」というフィールド名が表示されています。[機能] セクションには「input_1」と表示されています。このフィールドをモデルに入力します。推論クエリ(または予測クエリ)で、「test」データに渡すフィールドとして「input_1」を参照します。

c. ヨガポーズの推論を実行します。

作成したモデルを使用して、テスト画像データを分類してみましょう。外部テーブルの作成時に外部テーブルに変換された Cloud Storage バケットに、テスト画像(ヨガのポーズ)があることを確認してください。これから、BigQuery 内のテスト画像から選択してクエリを行い、私たちが作成した BQML モデルを使用して推論を実行します。以下のクエリを使用して、テストをトリガーします。

読み込んでいます...

上記のクエリでは、外部テーブルで特定の URI 値(00000097.jpg)を含むテスト画像を 1 枚選択しています。また SELECT の部分は、ML.PREDICT 関数が動作するように、ML.DECODE_IMAGE コンストラクトをフィールド「input_1」として使用しています。

実行が完了すると、以下に示すように結果が表示されます。

https://storage.googleapis.com/gweb-cloudblog-publish/images/13-20230613ja.max-2200x2200.png

ResNet モデルについて詳しく知っている方は、これで分類が理解できるはずです。そうでない方は、視覚的に分類を理解するために、スニペットを作成しましょう。

d. 結果をフラット化する

上記の出力を可視化する方法の一つとして、BigQuery SQL の UNNEST コンストラクトを使用して activation_49 フィールドの値をフラット化する方法があります。前のステップで得た結果のフラット化について、以下のクエリを参照してください。結果のクラスにさらにテキストラベルを付けたい場合は、クエリ内のプレースホルダ <<LABEL_LOGIC>> をロジックに置き換えます(使用時にコメント化解除)。

読み込んでいます...

クラスのラベル付けロジックがない場合、クエリの出力は以下のようになります。

https://storage.googleapis.com/gweb-cloudblog-publish/images/14-20230613ja.max-2200x2200.png
https://storage.googleapis.com/gweb-cloudblog-publish/images/15-20230613ja.max-2200x2200.png

モデルについてさらに読み、ご自分のデータとモデルの出力に最適なロジックを適用してください。

e. 推論を可視化する

最後に、簡単な Python スニペットで分類の結果を可視化しましょう。上記のクエリの結果を CSV ファイルにエクスポートして、Python コード内で参照します。

https://storage.googleapis.com/gweb-cloudblog-publish/images/16-20230613ja.max-1900x1900.png

上記の画像出力は、ヨガのポーズである「ダウンドッグ」を表すものです。これは、BQML を使用した分類のために、ML.PREDICT クエリに渡したテスト入力とまったく同じものです。

BigQuery で構造化データと非構造化データを一つに扱う

この実装で私が気に入っているのは、構造化リレーショナル テーブルのフィールドと、非構造化画像データを統合するところです。ポーズとその健康関連のデータを格納するために、外部テーブルと同じデータセット内に構造化 BigQuery テーブルを作成しました。

https://storage.googleapis.com/gweb-cloudblog-publish/images/17-20230613ja.max-1300x1300.png

上の画像は、「yoga_health」と名付けられた構造化データテーブルのスキーマです。各フィールドは、pose、focus、health_benefit、breath となっています。そして以下のクエリで、構造化データと非構造化データを結合します。

読み込んでいます...

以下に結果を示します。

https://storage.googleapis.com/gweb-cloudblog-publish/images/18-20230613ja.max-1700x1700.png

: このブログで扱ったクエリはすべて、BigQuery のマジック コマンドを使用して、Python のノートブックから直接実行できます。

お試しください

いかがでしたか。このブログでは、BigQuery での非構造化データの保存とクエリの実行、BQML を使用した分類モデルの作成、そのモデルとヨガポーズの画像を使った予測のテストを行うことができました。ご自身の Google Cloud プロジェクトで、Codelab の解説に沿って実装することができます。また、Google Cloud におけるデータベースやその他のエンド ツー エンド アプリケーションの実装について詳しく知りたい方は、私のブログにアクセスしてみてください。フィードバックやご質問は、こちらまでお寄せください。

- Google、デベロッパー アドボケイト Abirami Sukumaran

投稿先