1. Przegląd
W tym laboratorium dowiesz się, jak używać Vertex AI Workbench do eksplorowania danych i trenowania modeli ML.
Czego się dowiesz
Poznasz takie zagadnienia jak:
- Tworzenie i konfigurowanie instancji Vertex AI Workbench
- Korzystanie z oprogramowania sprzęgającego BigQuery w Vertex AI Workbench
- Trenowanie modelu w jądrze Vertex AI Workbench
Całkowity koszt ukończenia tego laboratorium w Google Cloud wynosi około 1 USD.
2. Wprowadzenie do Vertex AI
W tym module wykorzystujemy najnowszą ofertę produktów AI dostępną w Google Cloud. Vertex AI integruje oferty ML w Google Cloud, zapewniając płynne środowisko programistyczne. Wcześniej modele wytrenowane za pomocą AutoML i modele niestandardowe były dostępne w ramach osobnych usług. Nowa oferta łączy je w jeden interfejs API wraz z innymi nowymi usługami. Możesz też przeprowadzić migrację istniejących projektów do Vertex AI.
Vertex AI obejmuje wiele różnych usług, które obsługują kompleksowe przepływy pracy związane z uczeniem maszynowym. Ten moduł dotyczy głównie Vertex AI Workbench.
Vertex AI Workbench pomaga użytkownikom szybko tworzyć kompleksowe przepływy pracy oparte na notatnikach dzięki ścisłej integracji z usługami danych (takimi jak Dataproc, Dataflow, BigQuery i Dataplex) oraz Vertex AI. Umożliwia ona badaczom danych łączenie się z usługami danych GCP, analizowanie zbiorów danych, eksperymentowanie z różnymi technikami modelowania, wdrażanie wytrenowanych modeli w środowisku produkcyjnym i zarządzanie MLOps w całym cyklu życia modelu.
3. Omówienie przypadku użycia
W tym module zapoznasz się ze zbiorem danych London Bicycles Hire. Te dane zawierają informacje o wycieczkach rowerowych w ramach londyńskiego programu rowerów publicznych od 2011 r. Zaczniesz od zbadania tego zbioru danych w BigQuery za pomocą łącznika BigQuery w Vertex AI Workbench. Następnie wczytasz dane do notatnika Jupyter za pomocą biblioteki pandas i wytrenujesz model TensorFlow, aby przewidywać czas trwania wycieczki rowerowej na podstawie tego, kiedy się odbyła i jak długo trwała.
W tym module wykorzystasz warstwy wstępnego przetwarzania Keras do przekształcania i przygotowywania danych wejściowych do trenowania modelu. Ten interfejs API umożliwia wbudowanie wstępnego przetwarzania bezpośrednio w graf modelu TensorFlow, co zmniejsza ryzyko rozbieżności między trenowaniem a udostępnianiem, ponieważ dane treningowe i dane do udostępniania przechodzą identyczne przekształcenia. Pamiętaj, że od TensorFlow 2.6 ten interfejs API jest stabilny. Jeśli używasz starszej wersji TensorFlow, musisz zaimportować symbol eksperymentalny.
4. Konfigurowanie środowiska
Aby wykonać to ćwiczenie, musisz mieć projekt w Google Cloud Platform z włączonymi płatnościami. Aby utworzyć projekt, postępuj zgodnie z instrukcjami.
Krok 1. Włącz interfejs Compute Engine API
Przejdź do Compute Engine i kliknij Włącz, jeśli nie jest jeszcze włączona.
Krok 2. Włącz interfejs Vertex AI API
Otwórz sekcję Vertex AI w konsoli Cloud i kliknij Włącz interfejs Vertex AI API.

Krok 3. Tworzenie instancji Vertex AI Workbench
W sekcji Vertex AI w konsoli Cloud kliknij Workbench:

Włącz interfejs Notebooks API, jeśli nie jest jeszcze włączony.

Po włączeniu kliknij ZARZĄDZANE NOTATNIKI:

Następnie wybierz NOWY NOTEBOOK.

Nadaj nazwę notatnikowi, a w sekcji Uprawnienia wybierz Konto usługi.

Kliknij Ustawienia zaawansowane.
W sekcji Zabezpieczenia wybierz „Włącz terminal”, jeśli nie jest jeszcze włączony.

Wszystkie pozostałe ustawienia zaawansowane możesz pozostawić bez zmian.
Następnie kliknij Utwórz.
Po utworzeniu instancji kliknij OTWÓRZ JUPYTERLAB.

5. Przeglądanie zbioru danych w BigQuery
W instancji Vertex AI Workbench po lewej stronie kliknij złącze BigQuery w Notatnikach.

Oprogramowanie sprzęgające BigQuery umożliwia łatwe przeglądanie zbiorów danych BigQuery i wysyłanie do nich zapytań. Oprócz zbiorów danych w projekcie możesz też przeglądać zbiory danych w innych projektach, klikając przycisk Dodaj projekt.

W tym laboratorium użyjesz danych z publicznych zbiorów danych BigQuery. Przewiń w dół, aż znajdziesz zbiór danych london_bicycles. Ten zbiór danych zawiera 2 tabele: cycle_hire i cycle_stations. Przyjrzyjmy się każdemu z nich.

Najpierw kliknij dwukrotnie tabelę cycle_hire. Tabela otworzy się na nowej karcie ze schematem tabeli oraz metadanymi, takimi jak liczba wierszy i rozmiar.

Jeśli klikniesz kartę Podgląd, zobaczysz próbkę danych. Uruchommy proste zapytanie, aby sprawdzić, jakie są popularne ścieżki. Najpierw kliknij przycisk Zapytanie dotyczące tabeli.

Następnie wklej poniższy kod do edytora SQL i kliknij Prześlij zapytanie.
SELECT
start_station_name,
end_station_name,
IF(start_station_name = end_station_name,
TRUE,
FALSE) same_station,
AVG(duration) AS avg_duration,
COUNT(*) AS total_rides
FROM
`bigquery-public-data.london_bicycles.cycle_hire`
GROUP BY
start_station_name,
end_station_name,
same_station
ORDER BY
total_rides DESC
Z wyników zapytania wynika, że najpopularniejsze były przejazdy rowerem do i ze stacji Hyde Park Corner.

Następnie kliknij dwukrotnie tabelę cycle_stations, która zawiera informacje o każdej stacji.
Chcemy połączyć tabele cycle_hire i cycle_stations. Tabela cycle_stations zawiera współrzędne geograficzne każdej stacji. Te informacje posłużą Ci do oszacowania odległości pokonanej podczas każdej przejażdżki rowerem, ponieważ możesz obliczyć odległość między stacją początkową a końcową.
Aby to obliczyć, użyjesz funkcji geograficznych BigQuery. Każdy ciąg znaków z szerokością i długością geograficzną przekonwertujesz na typ ST_GEOGPOINT, a następnie użyjesz funkcji ST_DISTANCE, aby obliczyć odległość w metrach w linii prostej między dwoma punktami. Tej wartości użyjesz jako serwera proxy dla odległości pokonanej podczas każdej przejażdżki rowerem.
Skopiuj poniższe zapytanie do edytora SQL, a następnie kliknij Prześlij zapytanie. Zwróć uwagę, że w warunku złączenia znajdują się 3 tabele, ponieważ musimy połączyć tabelę stacji 2 razy, aby uzyskać szerokość i długość geograficzną zarówno stacji początkowej, jak i końcowej.
WITH staging AS (
SELECT
STRUCT(
start_stn.name,
ST_GEOGPOINT(start_stn.longitude, start_stn.latitude) AS POINT,
start_stn.docks_count,
start_stn.install_date
) AS starting,
STRUCT(
end_stn.name,
ST_GEOGPOINT(end_stn.longitude, end_stn.latitude) AS point,
end_stn.docks_count,
end_stn.install_date
) AS ending,
STRUCT(
rental_id,
bike_id,
duration, --seconds
ST_DISTANCE(
ST_GEOGPOINT(start_stn.longitude, start_stn.latitude),
ST_GEOGPOINT(end_stn.longitude, end_stn.latitude)
) AS distance, --meters
start_date,
end_date
) AS bike
FROM `bigquery-public-data.london_bicycles.cycle_stations` AS start_stn
LEFT JOIN `bigquery-public-data.london_bicycles.cycle_hire` as b
ON start_stn.id = b.start_station_id
LEFT JOIN `bigquery-public-data.london_bicycles.cycle_stations` AS end_stn
ON end_stn.id = b.end_station_id
LIMIT 700000)
SELECT * from STAGING
6. Trenowanie modelu ML w jądrze TensorFlow
Vertex AI Workbench ma warstwę zgodności obliczeniowej, która umożliwia uruchamianie jąder dla TensorFlow, PySpark, R itp. z jednej instancji notatnika. W tym laboratorium utworzysz notatnik z użyciem jądra TensorFlow.
Tworzenie ramki danych
Po wykonaniu zapytania kliknij Kopiuj kod dla obiektu DataFrame. Dzięki temu możesz wkleić do notatnika kod Pythona, który łączy się z klientem BigQuery i wyodrębnia te dane jako ramkę danych pandas.

Następnie wróć do Launchera i utwórz notatnik TensorFlow 2.

Wklej kod skopiowany z Edytora zapytań do pierwszej komórki notatnika. Powinien on wyglądać tak:
# The following two lines are only necessary to run once.
# Comment out otherwise for speed-up.
from google.cloud.bigquery import Client, QueryJobConfig
client = Client()
query = """WITH staging AS (
SELECT
STRUCT(
start_stn.name,
ST_GEOGPOINT(start_stn.longitude, start_stn.latitude) AS POINT,
start_stn.docks_count,
start_stn.install_date
) AS starting,
STRUCT(
end_stn.name,
ST_GEOGPOINT(end_stn.longitude, end_stn.latitude) AS point,
end_stn.docks_count,
end_stn.install_date
) AS ending,
STRUCT(
rental_id,
bike_id,
duration, --seconds
ST_DISTANCE(
ST_GEOGPOINT(start_stn.longitude, start_stn.latitude),
ST_GEOGPOINT(end_stn.longitude, end_stn.latitude)
) AS distance, --meters
start_date,
end_date
) AS bike
FROM `bigquery-public-data.london_bicycles.cycle_stations` AS start_stn
LEFT JOIN `bigquery-public-data.london_bicycles.cycle_hire` as b
ON start_stn.id = b.start_station_id
LEFT JOIN `bigquery-public-data.london_bicycles.cycle_stations` AS end_stn
ON end_stn.id = b.end_station_id
LIMIT 700000)
SELECT * from STAGING"""
job = client.query(query)
df = job.to_dataframe()
Na potrzeby tego modułu ograniczamy zbiór danych do 700 tys. elementów, aby skrócić czas trenowania. Możesz jednak zmodyfikować zapytanie i przeprowadzić eksperyment na całym zbiorze danych.
Następnie zaimportuj niezbędne biblioteki.
from datetime import datetime
import pandas as pd
import tensorflow as tf
Aby utworzyć zredukowaną strukturę DataFrame, która zawiera tylko kolumny potrzebne do części tego ćwiczenia związanej z uczeniem maszynowym, uruchom ten kod:
values = df['bike'].values
duration = list(map(lambda a: a['duration'], values))
distance = list(map(lambda a: a['distance'], values))
dates = list(map(lambda a: a['start_date'], values))
data = pd.DataFrame(data={'duration': duration, 'distance': distance, 'start_date':dates})
data = data.dropna()
Kolumna start_date jest obiektem Python datetime. Zamiast używać tego atrybutu datetime bezpośrednio w modelu, utworzysz 2 nowe cechy, które będą wskazywać dzień tygodnia i godzinę, w której odbyła się wycieczka rowerowa.
data['weekday'] = data['start_date'].apply(lambda a: a.weekday())
data['hour'] = data['start_date'].apply(lambda a: a.time().hour)
data = data.drop(columns=['start_date'])
Na koniec przekonwertuj kolumnę czasu trwania z sekund na minuty, aby ułatwić jej zrozumienie.
data['duration'] = data['duration'].apply(lambda x:float(x / 60))
Sprawdź kilka pierwszych wierszy sformatowanej struktury DataFrame. W przypadku każdej przejażdżki rowerem masz teraz dane o dniu tygodnia i godzinie, w której się odbyła, a także o przebytym dystansie. Na podstawie tych informacji spróbujesz przewidzieć, ile czasu zajęła podróż.
data.head()

Zanim utworzysz i wytrenujesz model, musisz podzielić dane na zbiory treningowe i weryfikacyjne.
# Use 80/20 train/eval split
train_size = int(len(data) * .8)
print ("Train size: %d" % train_size)
print ("Evaluation size: %d" % (len(data) - train_size))
# Split data into train and test sets
train_data = data[:train_size]
val_data = data[train_size:]
Tworzenie modelu TensorFlow
Utworzysz model TensorFlow za pomocą interfejsu Keras Functional API. Do wstępnego przetwarzania danych wejściowych użyjesz interfejsu API warstw wstępnego przetwarzania Keras.
Ta funkcja użytkowa utworzy z obiektu DataFrame biblioteki pandas obiekt tf.data.Dataset.
def df_to_dataset(dataframe, label, shuffle=True, batch_size=32):
dataframe = dataframe.copy()
labels = dataframe.pop(label)
ds = tf.data.Dataset.from_tensor_slices((dict(dataframe), labels))
if shuffle:
ds = ds.shuffle(buffer_size=len(dataframe))
ds = ds.batch(batch_size)
ds = ds.prefetch(batch_size)
return ds
Użyj powyższej funkcji, aby utworzyć 2 zbiory danych tf.data.Dataset – jeden do trenowania, a drugi do walidacji. Możesz zobaczyć ostrzeżenia, ale możesz je zignorować.
train_dataset = df_to_dataset(train_data, 'duration')
validation_dataset = df_to_dataset(val_data, 'duration')
W modelu użyjesz tych warstw przetwarzania wstępnego:
- Warstwa normalizacji: przeprowadza normalizację cech wejściowych na poziomie poszczególnych cech.
- Warstwa IntegerLookup: zamienia całkowite wartości kategorialne na indeksy całkowite.
- Warstwa CategoryEncoding: przekształca kategorialne cechy liczbowe w gęste reprezentacje typu one-hot, multi-hot lub TF-IDF.
Pamiętaj, że tych warstw nie można trenować. Zamiast tego ustawiasz stan warstwy przetwarzania wstępnego, udostępniając jej dane treningowe za pomocą metody adapt().
Ta funkcja utworzy warstwę normalizacji, której możesz użyć w przypadku funkcji odległości. Stan ustawisz przed dopasowaniem modelu za pomocą metody adapt() na danych treningowych. Obliczy to średnią i wariancję, które będą używane do normalizacji. Później, gdy przekażesz do modelu zbiór danych weryfikacyjnych, do skalowania tych danych zostaną użyte te same średnia i wariancja obliczone na podstawie danych treningowych.
def get_normalization_layer(name, dataset):
# Create a Normalization layer for our feature.
normalizer = tf.keras.layers.Normalization(axis=None)
# Prepare a Dataset that only yields our feature.
feature_ds = dataset.map(lambda x, y: x[name])
# Learn the statistics of the data.
normalizer.adapt(feature_ds)
return normalizer
Podobnie poniższa funkcja tworzy kodowanie kategorii, które będzie używane w przypadku funkcji godziny i dnia tygodnia.
def get_category_encoding_layer(name, dataset, dtype, max_tokens=None):
index = tf.keras.layers.IntegerLookup(max_tokens=max_tokens)
# Prepare a Dataset that only yields our feature
feature_ds = dataset.map(lambda x, y: x[name])
# Learn the set of possible values and assign them a fixed integer index.
index.adapt(feature_ds)
# Create a Discretization for our integer indices.
encoder = tf.keras.layers.CategoryEncoding(num_tokens=index.vocabulary_size())
# Apply one-hot encoding to our indices. The lambda function captures the
# layer so we can use them, or include them in the functional model later.
return lambda feature: encoder(index(feature))
Następnie utwórz część modelu odpowiedzialną za przetwarzanie wstępne. Najpierw utwórz warstwę tf.keras.Input dla każdej funkcji.
# Create a Keras input layer for each feature
numeric_col = tf.keras.Input(shape=(1,), name='distance')
hour_col = tf.keras.Input(shape=(1,), name='hour', dtype='int64')
weekday_col = tf.keras.Input(shape=(1,), name='weekday', dtype='int64')
Następnie utwórz warstwy normalizacji i kodowania kategorii i zapisz je na liście.
all_inputs = []
encoded_features = []
# Pass 'distance' input to normalization layer
normalization_layer = get_normalization_layer('distance', train_dataset)
encoded_numeric_col = normalization_layer(numeric_col)
all_inputs.append(numeric_col)
encoded_features.append(encoded_numeric_col)
# Pass 'hour' input to category encoding layer
encoding_layer = get_category_encoding_layer('hour', train_dataset, dtype='int64')
encoded_hour_col = encoding_layer(hour_col)
all_inputs.append(hour_col)
encoded_features.append(encoded_hour_col)
# Pass 'weekday' input to category encoding layer
encoding_layer = get_category_encoding_layer('weekday', train_dataset, dtype='int64')
encoded_weekday_col = encoding_layer(weekday_col)
all_inputs.append(weekday_col)
encoded_features.append(encoded_weekday_col)
Po zdefiniowaniu warstw przetwarzania wstępnego możesz zdefiniować pozostałą część modelu. Połączysz wszystkie cechy wejściowe i przekażesz je do warstwy gęstej. Warstwa wyjściowa jest pojedynczą jednostką, ponieważ jest to problem regresji.
all_features = tf.keras.layers.concatenate(encoded_features)
x = tf.keras.layers.Dense(64, activation="relu")(all_features)
output = tf.keras.layers.Dense(1)(x)
model = tf.keras.Model(all_inputs, output)
Na koniec skompiluj model.
model.compile(optimizer = tf.keras.optimizers.Adam(0.001),
loss='mean_squared_logarithmic_error')
Po zdefiniowaniu modelu możesz wizualizować architekturę.
tf.keras.utils.plot_model(model, show_shapes=True, rankdir="LR")

Pamiętaj, że w przypadku tego prostego zbioru danych ten model jest dość skomplikowany. Służy ona wyłącznie do celów demonstracyjnych.
Przeprowadzimy 1 epokę trenowania, aby sprawdzić, czy kod działa.
model.fit(train_dataset, validation_data = validation_dataset, epochs = 1)
Trenowanie modelu za pomocą GPU
Następnie będziesz trenować model dłużej i użyjesz przełącznika sprzętu, aby przyspieszyć trenowanie. Vertex AI Workbench umożliwia zmianę sprzętu bez wyłączania instancji. Dodając GPU tylko wtedy, gdy jest potrzebny, możesz obniżyć koszty.
Aby zmienić profil sprzętu, w prawym górnym rogu kliknij typ maszyny i wybierz Modyfikuj sprzęt.

Wybierz „Podłącz GPU” i wybierz GPU NVIDIA T4 Tensor Core.

Konfiguracja sprzętu zajmie około 5 minut. Po zakończeniu procesu potrenujmy model jeszcze przez chwilę. Zauważysz, że każda epoka trwa teraz krócej.
model.fit(train_dataset, validation_data = validation_dataset, epochs = 5)
🎉 Gratulacje! 🎉
Wiesz już, jak używać Vertex AI Workbench do:
- Przeglądanie danych w BigQuery
- Używanie klienta BigQuery do wczytywania danych do Pythona
- Trenowanie modelu TensorFlow za pomocą warstw przetwarzania wstępnego Keras i procesora graficznego
Więcej informacji o poszczególnych częściach Vertex AI znajdziesz w dokumentacji.
7. Czyszczenie
Skonfigurowaliśmy notatnik tak, aby po 60 minutach bezczynności przekraczał limit czasu, więc nie musimy się martwić o zamykanie instancji. Jeśli chcesz ręcznie wyłączyć instancję, kliknij przycisk Zatrzymaj w sekcji Vertex AI Workbench w konsoli. Jeśli chcesz całkowicie usunąć notatnik, kliknij przycisk Usuń.
