1. Введение
В этом практическом занятии мы обсудим пример использования BigQuery для хранения и анализа изображений поз йоги, а также реализацию модели классификации с помощью BigQuery ML для присвоения меток позам, используя только SQL-конструкции и никакой другой код.
BigQuery и BQML
BigQuery — это бессерверное многооблачное хранилище данных, масштабируемое от байтов до петабайтов без каких-либо операционных затрат. Это делает его отличным выбором для хранения обучающих данных для машинного обучения. Кроме того, встроенные возможности BigQuery Machine Learning ( BQML ) и аналитики позволяют создавать прогнозы без написания кода, используя только SQL-запросы. А доступ к данным из внешних источников можно получить с помощью федеративных запросов, что исключает необходимость в сложных ETL-конвейерах. Подробнее обо всех возможностях BigQuery можно узнать на странице BigQuery.
До сих пор BigQuery был известен как полностью управляемое облачное хранилище данных, помогающее пользователям анализировать структурированные и полуструктурированные данные. Но,
- BigQuery расширил свои возможности и теперь может выполнять все виды аналитики и машинного обучения, в том числе и для неструктурированных данных.
- Мы можем использовать SQL-запросы для проведения глубокого анализа, аналитики и машинного обучения на изображениях, видео, аудио и т. д. в больших масштабах без необходимости написания дополнительного кода.
- Мы можем объединять структурированные и неструктурированные данные, как если бы они все существовали вместе в таблице.
Мы обсудим это в нашем примере использования классификации поз йоги, который будет рассмотрен в следующем разделе.
Классификация изображений с помощью машинного обучения BigQuery
Возможность обрабатывать и анализировать изображения с помощью структурированных запросов, как если бы это были структурированные данные, — это первое в своем роде решение. Теперь мы даже можем прогнозировать результаты, используя модели классификации машинного обучения с помощью BigQuery ML. Для удобства понимания я разделил этот процесс на 5 шагов:

Описанные выше шаги могут показаться сложными, если рассматривать их только как обозначения. Подробное описание каждого из задействованных компонентов, таких как набор данных BigQuery, подключение Lakehouse для Apache Iceberg, контейнеры Cloud Storage, объектная таблица (внешний источник данных), BQML и т. д., определено в разделе реализации. Поэтому не расстраивайтесь, если вы еще не знакомы с этими терминами.
Что вы построите
Вам предстоит создать модель классификации изображений с использованием BQML, охватывающую следующие параметры:
- Набор данных BigQuery, содержащий компоненты таблицы и модели.
- Для хранения изображений йоги для модели используется хранилище Google Cloud Storage (GCS) в виде корзины.
- Внешняя таблица для доступа к образам облачного хранилища.
- Подключение Lakehouse для внешнего стола, обеспечивающего доступ к изображениям в GCS.
- Модель ResNet в машинном обучении BigQuery
- Выводы с использованием созданной модели
- BigQuery SQL для анализа изображений.
- BigQuery SQL позволяет выполнять запросы одновременно к структурированным и неструктурированным данным.
Что вы узнаете
- Как создать хранилище в Cloud Storage и хранить в нём изображения.
- Как создать набор данных, таблицу и подключение к BigQuery
- Как создать модель классификации изображений с использованием BQML
- Как выполнить прогнозирование с помощью созданной модели, используя BigQuery ML
- Как запрашивать изображения и объединять их со структурированными данными с помощью SQL-запросов BigQuery.
2. Требования
3. Создайте набор данных и подключитесь к Lakehouse.
Для нашего примера использования — распознавания изображений 5 поз йоги — я использовал общедоступный набор данных , к которому можно получить доступ из этого репозитория . Мы распознаём только следующие позы йоги: собака мордой вниз, богиня, планка, дерево и воин 2. Прежде чем приступить к созданию набора данных BigQuery, убедитесь, что вы выбрали или создали проект Google Cloud и проверили, включена ли оплата за использование проекта. Включите BigQuery API и BigQuery Connection API. Обратите внимание, что все сервисы, используемые в этой реализации, должны находиться в одном и том же регионе.
а. Создайте набор данных "yoga_set", выполнив следующие шаги:
Перейдите в редактор BigQuery и введите команду:
CREATE SCHEMA `<<project_id>>.yoga_set`;
b. Подключение к Lakehouse позволяет нам подключиться к внешнему источнику данных, сохраняя при этом детальный контроль доступа и безопасность BigQuery, в нашем случае это Cloud Storage для данных изображений. Мы будем использовать это подключение для чтения объектов из Cloud Storage. Выполните следующие шаги для создания подключения к Lakehouse.
В панели «Проводник» на странице BigQuery нажмите кнопку «Добавить данные»:
Экран "Добавить внешние данные" в BigQuery
Нажмите «Подключения к внешним источникам данных» и выберите опцию «Функции Lakehouse и удаленного доступа»:
Настройка подключения к внешнему источнику данных
Укажите идентификатор подключения и создайте соединение. Не забудьте записать идентификатор учетной записи службы, который отобразится на экране после создания соединения <<SERVICE_ACCOUNT>>. В нашем примере идентификатор подключения — «yoga-pose-conn». Не забудьте также указать регион.
4. Создайте сегмент Google Cloud Storage и предоставьте необходимые разрешения.
Мы будем использовать хранилище Google Cloud Storage (корзину) для хранения файлов изображений поз йоги, на основе которых мы хотим создать модель. Корзины — это контейнеры Cloud Storage для хранения изображений, которые мы будем анализировать.
а. Перейдите в Google Cloud Storage, найдя его в консоли, затем нажмите «Корзины», чтобы попасть на главную страницу «Корзин», и нажмите «СОЗДАТЬ».
Страница хранилищ Google Cloud Storage
b. На странице «Создать корзину» введите информацию о вашей корзине (уникальное имя) и продолжите. Убедитесь, что она находится в том же регионе, что и набор данных и подключение, описанные в предыдущих шагах, и нажмите «Создать».
Страница создания корзины в Google Cloud Storage
Прежде чем перейти к следующему шагу, убедитесь, что вы записали свою учетную запись службы, имя корзины и путь к ней.
c. После создания хранилища сохраните изображения (с помощью команд консоли или Cloud Shell, или программно) и предоставьте необходимые разрешения учетной записи службы подключения (которую мы сохранили ранее) для доступа к изображениям.
> export sa=<<"SERVICE_ACCOUNT">>
> gsutil iam ch serviceAccount:$sa:objectViewer "gs://<<bucket>>"
5. Создайте таблицу объектов.
Создайте внешнюю объектную таблицу в BigQuery для доступа к неструктурированным данным в хранилище, используя созданное нами соединение. Выполните следующий SQL-запрос CREATE из редактора BigQuery:
CREATE OR REPLACE EXTERNAL TABLE `<<dataset>>.<<table_name>>`
WITH CONNECTION `us.<<connection-name>>`
OPTIONS(
object_metadata="SIMPLE", uris=["gs://<<bucket>>/<<folder_if_exists>>/*.jpg"]);
Внешняя таблица создается, как показано ниже:

Давайте быстро запросим позу из только что созданной внешней таблицы:
SELECT data , uri
FROM `yoga_set.yoga_poses`
WHERE REGEXP_CONTAINS(uri, 'gs://yoga_images/Downdog')
Limit 1;
Как видно на скриншоте ниже, вы можете создавать неструктурированные изображения и работать с ними так же, как если бы они были структурированными данными:

Теперь давайте экспортируем результат запроса, полученный выше, в небольшой фрагмент кода на 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)
Выполните команду, чтобы увидеть результат, как показано ниже:

Теперь, когда мы создали внешнюю таблицу и получили доступ к изображениям из облачного хранилища только с помощью SQL-запросов, перейдем к следующему разделу — созданию модели классификации.
6. Создайте модель и загрузите её в Google Cloud Storage.
Для этой реализации мы будем использовать предварительно обученную модель ResNet 50 для выполнения вывода на основе только что созданной таблицы объектов. Модель ResNet 50 анализирует файлы изображений и выдает набор векторов, представляющих вероятность принадлежности изображения к соответствующему классу (логиты).
Прежде чем переходить к этому шагу, убедитесь, что у вас есть все необходимые разрешения . Затем выполните следующие действия:
- Загрузите модель по этой ссылке и сохраните её локально.
- После распаковки файл должен быть сохранен в папку saved_model.pb и папку variables.
- Загрузите эти два файла и папку в созданный нами ранее бакет.
В хранилище Google Cloud Storage находится "yoga_images", куда загружены файлы модели ResNet.
После завершения этого шага файлы, относящиеся к вашей модели, должны находиться в том же хранилище, что и изображения, как показано на изображении выше.
7. Загрузите модель в BQML и выполните вывод.
На этом этапе мы загрузим модель в тот же набор данных BigQuery, что и внешнюю таблицу, созданную ранее, и применим её к изображениям, хранящимся в облачном хранилище.
а. В редакторе BigQuery выполните следующий SQL-запрос.
CREATE MODEL `<<Dataset>>.<<Model_Name>>`
OPTIONS(
model_type = 'TENSORFLOW',
model_path = 'gs://<<Bucket>>/*');
После завершения выполнения (что может занять некоторое время в зависимости от вашего набора данных) вы увидите модель в разделе «Набор данных» в BigQuery.
Список созданных моделей в наборе данных BigQuery.
б. Изучите модель, чтобы увидеть ее входные и выходные поля.
Разверните набор данных и щелкните по только что созданной модели "yoga_poses_resnet". Перейдите на вкладку "Схема":
Вкладка «Схема определения модели 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 могла работать.
После завершения выполнения вы увидите результат, показанный ниже:

Для тех, кто хорошо знаком с моделью ResNet, это должно помочь понять классификацию. В противном случае, давайте напишем небольшой фрагмент кода, чтобы наглядно продемонстрировать классификацию.
d. Сглаживание результата
Один из способов визуализации приведенного выше результата — преобразование значений поля activation_49 в плоскую структуру с помощью конструкции UNNEST в SQL-запросе BigQuery. См. запрос ниже для преобразования результата предыдущего шага в плоскую структуру. Если вы хотите дополнительно текстово пометить результирующий класс, вы можете добавить логику вместо заполнителя <<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;
Без учета логики присвоения меток класса, ниже приведен результат выполнения запроса:

Однако в моем случае я применил примерную логику, и вот результат:

Вы можете подробнее ознакомиться с моделью и применить логику, которая лучше всего подходит для ваших данных и результатов работы модели.
e. Визуализация вывода
Наконец, небольшой фрагмент кода на Python для визуализации результатов классификации! Экспортируйте результаты запроса в CSV-файл и используйте его в коде Python.

Изображение выше относится к позе йоги «Собака мордой вниз», которая является точно таким же тестовым входным значением, которое мы передали в запрос ML.PREDICT для классификации с использованием BQML!
8. Объединение структурированных и неструктурированных данных
Наконец, моя любимая часть этой реализации — это объединение полей из моей структурированной реляционной таблицы с этими неструктурированными данными изображений. Я создал структурированную таблицу BigQuery в том же наборе данных, что и внешняя таблица, для хранения позы и связанных с ней данных о состоянии здоровья.
Схема структурированной таблицы BigQuery "yoga_health"
Изображение выше представляет собой схему структурированной таблицы данных под названием "yoga_health", поля которой — pose, focus, health_benefit и breath. Приведенный ниже запрос объединяет структурированные и неструктурированные данные:
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)];
Ниже приведён результат:

Примечание: Все запросы, рассмотренные в этом блоге, можно выполнить непосредственно из вашего блокнота Python, используя команды BigQuery Magic .
9. Уборка
Чтобы избежать списания средств с вашего аккаунта Google Cloud за ресурсы, использованные в этой статье, выполните следующие действия.
- В консоли Google Cloud перейдите на страницу «Управление ресурсами» .
- В списке проектов выберите проект, который хотите удалить, и нажмите «Удалить».
- В диалоговом окне введите идентификатор проекта, а затем нажмите «Завершить», чтобы удалить проект.
10. Поздравляем!
Поздравляем! Вы успешно сохранили и запросили неструктурированные данные в BigQuery, создали модель классификации с использованием BQML и спрогнозировали тестовые позы йоги с помощью этой модели. Если вы хотите реализовать это на практике, начните работу над своим проектом в Google Cloud . Кроме того, если вы хотите узнать больше о базах данных или других комплексных решениях для приложений в Google Cloud, посетите мои блоги .