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

Описанные выше шаги могут показаться сложными, если рассматривать их только как обозначения. Подробное описание каждого из задействованных компонентов, таких как набор данных BigQuery, подключение к BigLake, контейнеры облачного хранилища (Cloud Storage Buckets), объектная таблица (внешний источник данных), BQML и т. д., определено в разделе реализации. Поэтому не расстраивайтесь, если вы еще не знакомы с этими терминами.
Что вы построите
Вам предстоит создать модель классификации изображений с использованием BQML, охватывающую следующие параметры:
- Набор данных BigQuery, содержащий компоненты таблицы и модели.
- Для хранения изображений йоги для модели используется хранилище Google Cloud Storage (GCS) в виде корзины.
- Внешняя таблица для доступа к образам облачного хранилища.
- Подключение к BigLake для внешнего стола, чтобы получить доступ к изображениям в GCS.
- Модель ResNet в машинном обучении BigQuery
- Выводы с использованием созданной модели
- BigQuery SQL для анализа данных изображений
- BigQuery SQL позволяет выполнять запросы одновременно к структурированным и неструктурированным данным.
Что вы узнаете
- Как создать хранилище в Cloud Storage и хранить в нём изображения.
- Как создать набор данных, таблицу и подключение к BigQuery
- Как создать модель классификации изображений с использованием BQML
- Как выполнить прогнозирование с помощью созданной модели, используя BigQuery ML
- Как запрашивать изображения и объединять их со структурированными данными с помощью SQL-запросов BigQuery.
2. Требования
3. Создайте набор данных и подключитесь к BigLake.
Для нашего примера использования — распознавания изображений 5 поз йоги — я использовал общедоступный набор данных , к которому можно получить доступ из этого репозитория . Мы распознаём только следующие позы йоги: собака мордой вниз, богиня, планка, дерево и воин 2. Прежде чем приступить к созданию набора данных BigQuery, убедитесь, что вы выбрали или создали проект Google Cloud и проверили, включена ли оплата за использование проекта. Включите BigQuery API и BigQuery Connection API. Обратите внимание, что все сервисы, используемые в этой реализации, должны находиться в одном и том же регионе.
а. Создайте набор данных "yoga_set", выполнив следующие шаги:
Перейдите в редактор BigQuery и введите команду:
CREATE SCHEMA `<<project_id>>.yoga_set`;
b. Подключение BigLake позволяет нам подключиться к внешнему источнику данных, сохраняя при этом детальный контроль доступа и безопасность BigQuery, в нашем случае это Cloud Storage для данных изображений. Мы будем использовать это подключение для чтения объектов из Cloud Storage. Выполните следующие шаги для создания подключения BigLake.
В панели «Проводник» на странице BigQuery нажмите кнопку «Добавить данные»:
Экран "Добавить внешние данные" в BigQuery
Нажмите «Подключения к внешним источникам данных» и выберите опцию «BigLake и удаленные функции»:
Настройка подключения к внешнему источнику данных
Укажите идентификатор подключения и создайте соединение. Не забудьте записать идентификатор учетной записи службы, который отобразится на экране после создания соединения <<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, посетите мои блоги .