1. Wprowadzenie
W tym ćwiczeniu z programowania omówimy przypadek użycia polegający na przechowywaniu i analizowaniu obrazów pozycji jogi w BigQuery oraz wdrażaniu modelu klasyfikacji za pomocą BigQuery ML w celu oznaczania pozycji tylko za pomocą konstrukcji SQL i bez użycia innych form kodu.
BigQuery i BQML
BigQuery to bezserwerowa, wielochmurowa hurtownia danych, która może skalować się od bajtów do petabajtów bezpłatnie operacyjnych. Dzięki temu doskonale nadaje się do przechowywania danych treningowych ML. Ponadto wbudowane uczenie maszynowe w BigQuery ( BQML) i funkcje analityczne umożliwiają tworzenie prognoz bez użycia kodu, tylko za pomocą zapytań SQL. Możesz też uzyskiwać dostęp do danych ze źródeł zewnętrznych za pomocą zapytań federacyjnych, co eliminuje potrzebę stosowania skomplikowanych potoków ETL. Więcej informacji o wszystkich możliwościach BigQuery znajdziesz na stronie BigQuery page.
Do tej pory BigQuery była znana jako w pełni zarządzana hurtownia danych w chmurze, która pomaga użytkownikom analizować dane uporządkowane i częściowo uporządkowane. Ale:
- BigQuery rozszerzyła się o możliwość przeprowadzania wszystkich analiz i uczenia maszynowego na danych nieuporządkowanych.
- Możemy używać zapytań SQL do przeprowadzania wnikliwych analiz, analiz i uczenia maszynowego na obrazach, filmach, dźwiękach itp. na dużą skalę bez konieczności pisania dodatkowego kodu.
- Możemy łączyć dane uporządkowane i nieuporządkowane tak, jakby wszystkie znajdowały się w jednej tabeli.
Omówimy to w przypadku użycia klasyfikacji pozycji jogi w następnej sekcji.
Klasyfikacja danych obrazów z użyciem BigQuery ML
Możliwość przetwarzania i analizowania obrazów za pomocą zapytań strukturalnych tak, jakby były to dane uporządkowane, jest pierwszą tego typu funkcją. Teraz możemy nawet przewidywać wyniki za pomocą modeli klasyfikacji uczenia maszynowego przy użyciu BigQuery ML. Aby ułatwić zrozumienie, podzieliłem etapy na 5 kroków:

Powyższe kroki mogą być skomplikowane, jeśli traktujemy je tylko jako etykiety. Szczegóły każdego z komponentów, takich jak zbiór danych BigQuery, Lakehouse for Apache Iceberg, zasobniki Cloud Storage (kontenery), tabela obiektów (zewnętrzne źródło danych), BQML itp., są zdefiniowane w sekcji implementacji. Nie zniechęcaj się więc, jeśli nie znasz jeszcze tych terminów.
Co utworzysz
Utworzysz model klasyfikacji danych obrazów za pomocą BQML, który będzie obejmować te elementy:
- zbiór danych BigQuery zawierający tabelę i komponenty modelu,
- zasobnik Google Cloud Storage (GCS) do przechowywania obrazów pozycji jogi na potrzeby modelu,
- tabela zewnętrzna umożliwiająca dostęp do obrazów w Cloud Storage,
- połączenie z Lakehouse na potrzeby tabeli zewnętrznej umożliwiające dostęp do obrazów w GCS,
- model ResNet w BigQuery ML,
- wnioskowanie z użyciem utworzonego modelu,
- BigQuery SQL do analizowania danych obrazów,
- BigQuery SQL do wspólnego wysyłania zapytań o dane uporządkowane i nieuporządkowane.
Czego się nauczysz
- Jak utworzyć zasobnik Cloud Storage i przechowywać w nim obrazy
- Jak utworzyć zbiór danych, tabelę i połączenie BigQuery
- Jak utworzyć model klasyfikacji danych obrazów za pomocą BQML
- Jak przewidywać wyniki za pomocą utworzonego modelu przy użyciu BigQuery ML
- Jak wysyłać zapytania o obrazy i łączyć je z danymi uporządkowanymi za pomocą BigQuery SQL
2. Wymagania
3. Tworzenie zbioru danych i połączenia z Lakehouse
W przypadku użycia wykrywania obrazów 5 pozycji jogi użyłem publicznie dostępnego zbioru danych, do którego możesz uzyskać dostęp z tego repozytorium. Pozycje jogi, które identyfikujemy, to pies z głową w dół, bogini, deska, drzewo i wojownik 2. Zanim zaczniesz tworzyć zbiór danych BigQuery, wybierz lub utwórz projekt Google Cloud i sprawdź, czy w projekcie są włączone rozliczenia. Włącz BigQuery API i BigQuery Connection API. Pamiętaj, że wszystkie usługi używane w tej implementacji powinny znajdować się w tym samym wybranym regionie.
a. Utwórz zbiór danych „yoga_set”, wykonując czynności opisane poniżej:
Otwórz edytor BigQuery i wpisz to polecenie:
CREATE SCHEMA `<<project_id>>.yoga_set`;
b. Połączenie z Lakehouse umożliwia nam łączenie się z zewnętrznym źródłem danych przy zachowaniu szczegółowej kontroli dostępu i bezpieczeństwa BigQuery, którym w naszym przypadku jest Cloud Storage na potrzeby danych obrazów. Użyjemy tego połączenia do odczytywania obiektów z Cloud Storage. Aby utworzyć połączenie z Lakehouse, wykonaj te czynności:
W panelu Eksplorator na stronie BigQuery kliknij DODAJ DANE:
Ekran „Dodaj dane zewnętrzne” w BigQuery
Kliknij Połączenia z zewnętrznymi źródłami danych i wybierz opcję Lakehouse i funkcje zdalne:
Konfigurowanie połączenia ze źródłem danych zewnętrznych
Podaj identyfikator połączenia i utwórz połączenie. Zapisz identyfikator konta usługi, który pojawi się na ekranie po utworzeniu połączenia <<SERVICE_ACCOUNT>>. W naszym przykładzie identyfikator połączenia to „yoga-pose-conn”. Pamiętaj, aby zapisać region.
4. Tworzenie zasobnika Google Cloud Storage i przyznawanie uprawnień
Użyjemy zasobnika Cloud Storage Google Cloud Storage do przechowywania plików obrazów pozycji jogi, na podstawie których chcemy utworzyć model. Zasobniki to kontenery Cloud Storage, w których znajdują się obrazy, które będziemy analizować.
a. Otwórz Google Cloud Storage, wyszukując go w konsoli, a następnie kliknij Zasobniki, aby przejść na stronę główną Zasobniki, i kliknij UTWÓRZ.
Strona zasobników Google Cloud Storage
b. Na stronie Utwórz zasobnik wpisz informacje o zasobniku (unikalną nazwę) i kontynuuj. Upewnij się, że znajduje się on w tym samym regionie co zbiór danych i połączenie omówione w poprzednich krokach, a następnie kliknij Utwórz.
Strona „Utwórz zasobnik” w Google Cloud Storage
Zanim przejdziesz do następnego kroku, zapisz konto usługi, nazwę zasobnika i ścieżkę.
c. Po utworzeniu zasobnika przechowuj obrazy (za pomocą konsoli, poleceń Cloud Shell lub programowo) i przyznaj niezbędne uprawnienia kontu usługi połączenia (które zostało zapisane wcześniej) do uzyskiwania dostępu do obrazów.
> export sa=<<"SERVICE_ACCOUNT">>
> gsutil iam ch serviceAccount:$sa:objectViewer "gs://<<bucket>>"
5. Tworzenie tabeli obiektów
Utwórz zewnętrzną tabelę obiektów w BigQuery, aby uzyskać dostęp do nieuporządkowanych danych w zasobniku za pomocą utworzonego połączenia. Uruchom poniższy kod SQL CREATE w edytorze 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"]);
Tabela zewnętrzna zostanie utworzona w sposób pokazany poniżej:

Szybko wyślij zapytanie o pozycję z nowo utworzonej tabeli zewnętrznej:
SELECT data , uri
FROM `yoga_set.yoga_poses`
WHERE REGEXP_CONTAINS(uri, 'gs://yoga_images/Downdog')
Limit 1;
Jak widać na zrzucie ekranu poniżej, możesz tworzyć nieuporządkowane obrazy i wykonywać na nich operacje tak, jakby były to dane strukturalne:

Teraz wyeksportujmy wynik zapytania z powyższego przykładu do małego fragmentu kodu w Pythonie, aby wizualizować wynik:
Aby wyeksportować wynik, kliknij ZAPISZ WYNIKI i wybierz opcję „CSV Localfile”. Następnie otwórz notatnik Colab (lub utwórz go) i wpisz poniższy kod.
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)
Uruchom, aby zobaczyć wynik jak poniżej:

Teraz, gdy utworzyliśmy tabelę zewnętrzną i uzyskaliśmy dostęp do obrazów z Cloud Storage tylko za pomocą zapytań SQL, przejdźmy do następnej sekcji, czyli tworzenia modelu klasyfikacji.
6. Tworzenie modelu i przesyłanie go do Google Cloud Storage
W tej implementacji użyjemy wstępnie wytrenowanego modelu ResNet 50 do wnioskowania na podstawie utworzonej przez nas tabeli obiektów. Model ResNet 50 analizuje pliki obrazów i generuje partię wektorów reprezentujących prawdopodobieństwo, że obraz należy do odpowiedniej klasy (logity).
Zanim przejdziesz do tego kroku, upewnij się, że masz wszystkie niezbędne uprawnienia na miejscu. Następnie wykonaj te czynności:
- Pobierz model z tej lokalizacji i zapisz go lokalnie.
- Powinien zostać rozpakowany do pliku saved_model.pb i folderu variables.
- Prześlij te 2 elementy (plik i folder) do zasobnika utworzonego w poprzedniej sekcji.
Zasobnik Cloud Storage Google Cloud Storage „yoga_images” z przesłanymi plikami modelu ResNet
Po wykonaniu tego kroku pliki związane z modelem powinny znajdować się w tym samym zasobniku co obrazy, jak widać na obrazie powyżej.
7. Wczytywanie modelu do BQML i wnioskowanie
W tym kroku wczytamy model do tego samego zbioru danych BigQuery co utworzona wcześniej tabela zewnętrzna i zastosujemy go do obrazów przechowywanych w Cloud Storage.
a. W edytorze BigQuery uruchom tę instrukcję SQL:
CREATE MODEL `<<Dataset>>.<<Model_Name>>`
OPTIONS(
model_type = 'TENSORFLOW',
model_path = 'gs://<<Bucket>>/*');
Po zakończeniu wykonywania (co może potrwać w zależności od zbioru danych) model pojawi się w sekcji zbioru danych w BigQuery.
Zbiór danych BigQuery z utworzonym modelem
b. Sprawdź model, aby zobaczyć jego pola wejściowe i wyjściowe.
Rozwiń zbiór danych i kliknij utworzony model „yoga_poses_resnet”. Kliknij kartę Schemat:
Karta Schemat definicji modelu BigQuery
W sekcji Etykiety zobaczysz pole „activation_49”, które reprezentuje pole wyjściowe. W sekcji Funkcje widać „input_1”, które reprezentuje pole, które ma być danymi wejściowymi modelu. W zapytaniu wnioskowania (lub zapytaniu prognozowania) odwołasz się do „input_1” jako pola, które przekazujesz na potrzeby danych „testowych”.
c. Wnioskuj o pozycję jogi!
Użyjmy utworzonego modelu do klasyfikowania danych obrazów testowych. Upewnij się, że masz obrazy testowe (pozycje jogi) zidentyfikowane w zasobniku Cloud Storage, które zostały dodane do tabeli zewnętrznej podczas jej tworzenia. Będziemy selektywnie wysyłać zapytania o te obrazy testowe w BigQuery, aby przeprowadzić wnioskowanie za pomocą utworzonego modelu BQML. Aby uruchomić test, użyj tego zapytania:
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')));
W powyższym zapytaniu wybieramy 1 obraz testowy, który zawiera określoną wartość URI (00000097.jpg) w tabeli zewnętrznej. Ponadto w części SELECT używamy konstrukcji ML.DECODE_IMAGE jako pola „input_1”, aby funkcja ML.PREDICT działała.
Po zakończeniu wykonywania zobaczysz wynik jak poniżej:

Osobom, które dobrze znają model ResNet, powinno to pomóc w zrozumieniu klasyfikacji. W przeciwnym razie napiszmy mały fragment kodu, aby wizualnie zrozumieć klasyfikację.
d. Spłaszczanie wyniku
Jednym ze sposobów wizualizacji powyższych danych wyjściowych jest spłaszczenie wartości pola activation_49 za pomocą konstrukcji UNNEST w BigQuery SQL. Aby spłaszczyć wynik z poprzedniego kroku, zapoznaj się z zapytaniem poniżej. Jeśli chcesz dodatkowo oznaczyć tekstowo wynikową klasę, możesz wprowadzić logikę w miejscu symbolu zastępczego <<LABEL_LOGIC>> w zapytaniu (odkomentuj, gdy używasz).
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;
Bez logiki oznaczania klasy poniżej znajdziesz dane wyjściowe zapytania:

W moim przypadku zastosowałem jednak przykładową logikę, a wynik jest taki:

Możesz dowiedzieć się więcej o modelu i zastosować logikę, która najlepiej sprawdza się w przypadku Twoich danych i danych wyjściowych modelu.
e. Wizualizacja wnioskowania
Na koniec krótki fragment kodu w Pythonie, który wizualizuje wynik klasyfikacji. Wyeksportuj wynik powyższego zapytania do pliku CSV i odwołaj się do niego w kodzie w Pythonie.

Obraz powyżej przedstawia pozycję jogi „Pies z głową w dół”, która jest dokładnie tym samym testowym danym wejściowym, które przekazaliśmy do zapytania ML.PREDICT na potrzeby klasyfikacji za pomocą BQML.
8. Łączenie danych uporządkowanych i nieuporządkowanych
Na koniec moja ulubiona część tej implementacji – łączenie pól z uporządkowanej tabeli relacyjnej z tymi nieuporządkowanymi danymi obrazów. W tym samym zbiorze danych co tabela zewnętrzna utworzyłem uporządkowaną tabelę BigQuery, w której znajdują się dane dotyczące pozycji i jej wpływu na zdrowie.
Schemat uporządkowanej tabeli BigQuery „yoga_health”
Obraz powyżej przedstawia schemat tabeli danych uporządkowanych o nazwie „yoga_health”. Pola to pose, focus, health_benefit i breath. Zapytanie poniżej łączy dane uporządkowane i nieuporządkowane:
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)];
Oto wynik:

Uwaga: wszystkie zapytania omówione w tym poście można uruchamiać bezpośrednio z notatnika w Pythonie za pomocą poleceń magicznych BigQuery.
9. Zwalnianie miejsca
Aby uniknąć obciążenia konta Google Cloud opłatami za zasoby zużyte w tym poście, wykonaj te czynności.
- W konsoli Google Cloud otwórz stronę Zarządzanie zasobami.
- Z listy projektów wybierz projekt do usunięcia, a potem kliknij Usuń.
- W oknie wpisz identyfikator projektu i kliknij Wyłącz, aby usunąć projekt.
10. Gratulacje
Gratulacje! Udało Ci się przechowywać i wysyłać zapytania o dane nieuporządkowane w BigQuery, utworzyć model klasyfikacji za pomocą BQML i przewidywać testowe pozycje jogi za pomocą modelu. Jeśli chcesz to wdrożyć, zacznij od projektu Google Cloud. Jeśli chcesz dowiedzieć się więcej o bazach danych lub innych implementacjach aplikacji kompleksowych w Google Cloud, przeczytaj moje blogi.