Классификация данных изображений с помощью BigQuery ML

1. Введение

В этом практическом занятии мы обсудим пример использования BigQuery для хранения и анализа изображений поз йоги, а также реализацию модели классификации с помощью BigQuery ML для присвоения меток позам, используя только SQL-конструкции и никакой другой код.

BigQuery и BQML

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

До сих пор BigQuery был известен как полностью управляемое облачное хранилище данных, помогающее пользователям анализировать структурированные и полуструктурированные данные. Но,

  • BigQuery расширил свои возможности и теперь может выполнять все виды аналитики и машинного обучения, в том числе и для неструктурированных данных.
  • Мы можем использовать SQL-запросы для проведения глубокого анализа, аналитики и машинного обучения на изображениях, видео, аудио и т. д. в больших масштабах без необходимости написания дополнительного кода.
  • Мы можем объединять структурированные и неструктурированные данные, как если бы они все существовали вместе в таблице.

Мы обсудим это в нашем примере использования классификации поз йоги, который будет рассмотрен в следующем разделе.

Классификация изображений с помощью машинного обучения BigQuery

Возможность обрабатывать и анализировать изображения с помощью структурированных запросов, как если бы это были структурированные данные, — это первое в своем роде решение. Теперь мы даже можем прогнозировать результаты, используя модели классификации машинного обучения с помощью BigQuery ML. Для удобства понимания я разделил этот процесс на 5 шагов:

fe97945bce996e1.jpeg

Описанные выше шаги могут показаться сложными, если рассматривать их только как обозначения. Подробное описание каждого из задействованных компонентов, таких как набор данных 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. Требования

  • Браузер, например Chrome или Firefox.
  • Проект Google Cloud с включенной функцией выставления счетов, содержащий ваши сервисы BigQuery, Cloud Storage и BigLake Connection.
  • В следующем разделе приведен список шагов по созданию приложения для классификации изображений.

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 нажмите кнопку «Добавить данные»:

4cb42b1245bb0ba6.png Экран "Добавить внешние данные" в BigQuery

Нажмите «Подключения к внешним источникам данных» и выберите опцию «BigLake и удаленные функции»:

9ffec2b2bfcc3cd5.png Настройка подключения к внешнему источнику данных

Укажите идентификатор подключения и создайте соединение. Не забудьте записать идентификатор учетной записи службы, который отобразится на экране после создания соединения <<SERVICE_ACCOUNT>>. В нашем примере идентификатор подключения — «yoga-pose-conn». Не забудьте также указать регион.

4. Создайте сегмент Google Cloud Storage и предоставьте необходимые разрешения.

Мы будем использовать хранилище Google Cloud Storage (корзину) для хранения файлов изображений поз йоги, на основе которых мы хотим создать модель. Корзины — это контейнеры Cloud Storage для хранения изображений, которые мы будем анализировать.

а. Перейдите в 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 для доступа к неструктурированным данным в хранилище, используя созданное нами соединение. Выполните следующий 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"]);

Внешняя таблица создается, как показано ниже:

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-запросов, перейдем к следующему разделу — созданию модели классификации.

6. Создайте модель и загрузите её в Google Cloud Storage.

Для этой реализации мы будем использовать предварительно обученную модель ResNet 50 для выполнения вывода на основе только что созданной таблицы объектов. Модель ResNet 50 анализирует файлы изображений и выдает набор векторов, представляющих вероятность принадлежности изображения к соответствующему классу (логиты).

Прежде чем переходить к этому шагу, убедитесь, что у вас есть все необходимые разрешения . Затем выполните следующие действия:

  1. Загрузите модель по этой ссылке и сохраните её локально.
  2. После распаковки файл должен превратиться в saved_model.pb и папку variables.
  3. Загрузите эти два файла и папку в созданный нами ранее бакет.

2629ff3eda214946.png В хранилище 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.

435fa0919aeb57a6.png Список созданных моделей в наборе данных BigQuery.

б. Изучите модель, чтобы увидеть ее входные и выходные поля.

Разверните набор данных и щелкните по только что созданной модели "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. Сглаживание результата

Один из способов визуализации приведенного выше результата — преобразование значений поля 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;

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

71f580f41f0811f3.png

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

1c6df6ecd14fba1.png

Вы можете подробнее ознакомиться с моделью и применить логику, которая лучше всего подходит для ваших данных и результатов работы модели.

e. Визуализация вывода

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

68756e7e4b8d7a29.png

Изображение выше относится к позе йоги «Собака мордой вниз», которая является точно таким же тестовым входным значением, которое мы передали в запрос ML.PREDICT для классификации с использованием BQML!

8. Объединение структурированных и неструктурированных данных

Наконец, моя любимая часть этой реализации — это объединение полей из моей структурированной реляционной таблицы с этими неструктурированными данными изображений. Я создал структурированную таблицу BigQuery в том же наборе данных, что и внешняя таблица, для хранения позы и связанных с ней данных о состоянии здоровья.

125bdf848c86fbe.png Схема структурированной таблицы 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)];

Ниже приведён результат:

469bdfcffa9e19fd.png

Примечание: Все запросы, рассмотренные в этом блоге, можно выполнить непосредственно из вашего блокнота Python, используя команды BigQuery Magic .

9. Уборка

Чтобы избежать списания средств с вашего аккаунта Google Cloud за ресурсы, использованные в этой статье, выполните следующие действия.

  1. В консоли Google Cloud перейдите на страницу «Управление ресурсами» .
  2. В списке проектов выберите проект, который хотите удалить, и нажмите «Удалить».
  3. В диалоговом окне введите идентификатор проекта, а затем нажмите «Завершить», чтобы удалить проект.

10. Поздравляем!

Поздравляем! Вы успешно сохранили и запросили неструктурированные данные в BigQuery, создали модель классификации с использованием BQML и спрогнозировали тестовые позы йоги с помощью этой модели. Если вы хотите реализовать это на практике, начните работу над своим проектом в Google Cloud . Кроме того, если вы хотите узнать больше о базах данных или других комплексных решениях для приложений в Google Cloud, посетите мои блоги .