Vertex AI Workbench: TensorFlow-Modell mit Daten aus BigQuery trainieren

1. Übersicht

In diesem Lab erfahren Sie, wie Sie Vertex AI Workbench für die Datenexploration und das ML-Modelltraining verwenden.

Lerninhalte

Die folgenden Themen werden behandelt:

  • Vertex AI Workbench-Instanz erstellen und konfigurieren
  • Vertex AI Workbench BigQuery-Connector verwenden
  • Modell mit einem Vertex AI Workbench-Kernel trainieren

Die Gesamtkosten für die Ausführung dieses Labs in Google Cloud betragen etwa 1$.

2. Einführung in Vertex AI

In diesem Lab wird das neueste KI-Produkt von Google Cloud verwendet. Vertex AI vereint die ML-Angebote von Google Cloud in einer nahtlosen Entwicklungsumgebung. Bisher musste auf mit AutoML trainierte und benutzerdefinierte Modelle über verschiedene Dienste zugegriffen werden. Das neue Angebot kombiniert diese und weitere, neue Produkte zu einer einzigen API. Sie können auch vorhandene Projekte zu Vertex AI migrieren.

Vertex AI umfasst viele verschiedene Produkte zur Unterstützung von End-to-End-ML-Workflows. In diesem Lab geht es um Vertex AI Workbench.

Mit Vertex AI Workbench können Nutzer durch die enge Integration mit Datendiensten wie Dataproc, Dataflow, BigQuery und Dataplex sowie mit Vertex AI schnell End-to-End-Notebook-basierte Workflows erstellen. Damit können Data Scientists eine Verbindung zu GCP-Datendiensten herstellen, Datasets analysieren, mit verschiedenen Modellierungstechniken experimentieren, trainierte Modelle in der Produktion bereitstellen und MLOps über den gesamten Modelllebenszyklus hinweg verwalten.

3. Übersicht über Anwendungsfälle

In diesem Lab untersuchen Sie das Dataset Fahrradvermietung in London. Diese Daten enthalten Informationen zu Fahrradfahrten aus dem öffentlichen Bike-Sharing-Programm in London seit 2011. Zuerst sehen Sie sich diesen Datensatz in BigQuery über den Vertex AI Workbench BigQuery-Connector an. Anschließend laden Sie die Daten mit Pandas in ein Jupyter-Notebook und trainieren ein TensorFlow-Modell, um die Dauer einer Fahrradtour basierend auf dem Zeitpunkt der Tour und der zurückgelegten Strecke vorherzusagen.

In diesem Lab werden Keras-Vorverarbeitungsebenen verwendet, um die Eingabedaten für das Modelltraining zu transformieren und vorzubereiten. Mit dieser API können Sie die Vorverarbeitung direkt in den TensorFlow-Modellgraphen einbauen. So wird das Risiko von Abweichungen zwischen Training und Bereitstellung verringert, da Trainings- und Bereitstellungsdaten identischen Transformationen unterzogen werden. Diese API ist ab TensorFlow 2.6 stabil. Wenn Sie eine ältere Version von TensorFlow verwenden, müssen Sie das experimentelle Symbol importieren.

4. Umgebung einrichten

Für dieses Codelab benötigen Sie ein Google Cloud Platform-Projekt mit aktivierter Abrechnung. Folgen Sie dieser Anleitung, um ein Projekt zu erstellen.

Schritt 1: Compute Engine API aktivieren

Rufen Sie Compute Engine auf und wählen Sie Aktivieren aus, falls die API noch nicht aktiviert ist.

Schritt 2: Vertex AI API aktivieren

Rufen Sie den Vertex AI-Bereich Ihrer Cloud Console auf und klicken Sie auf Vertex AI API aktivieren.

Vertex AI-Dashboard

Schritt 3: Vertex AI Workbench-Instanz erstellen

Klicken Sie in der Cloud Console im Bereich „Vertex AI“ auf „Workbench“:

Vertex AI-Menü

Aktivieren Sie die Notebooks API, falls sie noch nicht aktiviert ist.

Notebook_api

Klicken Sie nach der Aktivierung auf VERWALTETE NOTEBOOKS:

Notebooks_UI

Wählen Sie dann NEUES NOTEBOOK aus.

new_notebook

Geben Sie Ihrem Notebook einen Namen und wählen Sie unter Berechtigung die Option Dienstkonto aus.

service_account

Wählen Sie Erweiterte Einstellungen aus.

Wählen Sie unter Sicherheit die Option „Terminal aktivieren“ aus, falls sie noch nicht aktiviert ist.

enable_terminal

Alle anderen erweiterten Einstellungen können Sie unverändert lassen.

Klicken Sie auf Erstellen.

Nachdem die Instanz erstellt wurde, klicken Sie auf JUPYTERLAB ÖFFNEN.

enable_terminal

5. Dataset in BigQuery untersuchen

Klicken Sie in der Vertex AI Workbench-Instanz auf der linken Seite auf den Connector BigQuery in Notebooks.

BQ-Connector

Mit dem BigQuery-Connector können Sie BigQuery-Datasets ganz einfach untersuchen und abfragen. Zusätzlich zu den Datasets in Ihrem Projekt können Sie Datasets in anderen Projekten aufrufen, indem Sie auf die Schaltfläche Projekt hinzufügen klicken.

anpinnen

In diesem Lab verwenden Sie Daten aus den öffentlichen BigQuery-Datasets. Scrollen Sie nach unten, bis Sie das Dataset london_bicycles finden. Dieses Dataset enthält zwei Tabellen: cycle_hire und cycle_stations. Sehen wir uns die einzelnen Optionen genauer an.

london_bike_ds

Doppelklicken Sie zuerst auf die Tabelle cycle_hire. Die Tabelle wird auf einem neuen Tab geöffnet. Dort sehen Sie das Tabellenschema sowie Metadaten wie die Anzahl der Zeilen und die Größe.

cycle_hire_ds

Wenn Sie auf den Tab Vorschau klicken, sehen Sie eine Stichprobe der Daten. Wir führen eine einfache Abfrage aus, um die beliebtesten Routen zu ermitteln. Klicken Sie zuerst auf die Schaltfläche Abfragetabelle.

cycle_hire_preview_ds

Fügen Sie dann Folgendes in den SQL-Editor ein und klicken Sie auf Abfrage senden.

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

Aus den Abfrageergebnissen geht hervor, dass Fahrten mit dem Fahrrad zur und von der Station Hyde Park Corner am beliebtesten waren.

journey_query_results

Doppelklicken Sie als Nächstes auf die Tabelle cycle_stations, die Informationen zu jeder Station enthält.

Wir möchten die Tabellen cycle_hire und cycle_stations zusammenführen. Die Tabelle cycle_stations enthält die Breiten- und Längengrade für jede Station. Anhand dieser Informationen schätzen Sie die zurückgelegte Strecke jeder Fahrradtour, indem Sie die Entfernung zwischen der Start- und der Endstation berechnen.

Für diese Berechnung verwenden Sie BigQuery-Geografiefunktionen. Dazu wandeln Sie jeden String mit Breiten- und Längengrad in einen ST_GEOGPOINT um und berechnen mit der Funktion ST_DISTANCE die Luftlinie zwischen den beiden Punkten in Metern. Sie verwenden diesen Wert als Proxy für die zurückgelegte Strecke bei jeder Fahrradtour.

Kopieren Sie die folgende Abfrage in Ihren SQL-Editor und klicken Sie dann auf „Abfrage senden“. Beachten Sie, dass die JOIN-Bedingung drei Tabellen enthält, da die Tabelle „stations“ zweimal verknüpft werden muss, um die Breiten- und Längengrade für die Start- und Endstation des Fahrrads zu erhalten.

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. ML-Modell mit einem TensorFlow-Kernel trainieren

Vertex AI Workbench verfügt über eine Compute-Kompatibilitätsebene, mit der Sie Kernel für TensorFlow, PySpark, R usw. über eine einzelne Notebook-Instanz starten können. In diesem Lab erstellen Sie ein Notebook mit dem TensorFlow-Kernel.

DataFrame erstellen

Klicken Sie nach der Ausführung der Abfrage auf „Code für DataFrame kopieren“. So können Sie Python-Code in ein Notebook einfügen, das eine Verbindung zum BigQuery-Client herstellt und diese Daten als Pandas-DataFrame extrahiert.

copy_for_df

Kehren Sie als Nächstes zum Launcher zurück und erstellen Sie ein TensorFlow 2-Notebook.

tf_kernel

Fügen Sie den aus dem Abfrageeditor kopierten Code in die erste Zelle des Notebooks ein. Die Ausgabe sollte so aussehen:

# 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()

Für dieses Lab beschränken wir das Dataset auf 700.000, um die Trainingszeit zu verkürzen. Sie können die Abfrage aber gern ändern und mit dem gesamten Dataset experimentieren.

Als Nächstes importieren Sie die erforderlichen Bibliotheken.

from datetime import datetime
import pandas as pd
import tensorflow as tf

Führen Sie den folgenden Code aus, um einen reduzierten DataFrame zu erstellen, der nur die Spalten enthält, die für den ML-Teil dieser Übung erforderlich sind.

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()

Die Spalte „start_date“ ist ein Python-datetime. Anstatt datetime direkt im Modell zu verwenden, erstellen Sie zwei neue Features, die den Wochentag und die Uhrzeit der Fahrradtour angeben.

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'])

Konvertieren Sie zum Schluss die Spalte „Dauer“ von Sekunden in Minuten, damit sie leichter verständlich ist.

data['duration'] = data['duration'].apply(lambda x:float(x / 60))

Sehen Sie sich die ersten Zeilen des formatierten DataFrames an. Für jede Radtour sind jetzt Daten zum Wochentag und zur Uhrzeit der Tour sowie zur zurückgelegten Distanz verfügbar. Anhand dieser Informationen versuchen Sie, die Dauer der Reise vorherzusagen.

data.head()

data_head

Bevor Sie das Modell erstellen und trainieren können, müssen Sie die Daten in Trainings- und Validierungs-Datasets aufteilen.

# 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:]

TensorFlow-Modell erstellen

Sie erstellen ein TensorFlow-Modell mit der Keras Functional API. Zum Vorverarbeiten der Eingabedaten verwenden Sie die Keras-API für Vorverarbeitungsebenen.

Mit der folgenden Hilfsfunktion wird ein tf.data.Dataset aus dem Pandas-DataFrame erstellt.

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

Verwenden Sie die obige Funktion, um zwei tf.data.Datasets zu erstellen, eines für das Training und eines für die Validierung. Möglicherweise werden einige Warnungen angezeigt, die Sie ignorieren können.

train_dataset = df_to_dataset(train_data, 'duration')
validation_dataset = df_to_dataset(val_data, 'duration')

Sie verwenden die folgenden Vorverarbeitungsebenen im Modell:

  • Normalisierungsebene: Führt eine merkmalsweise Normalisierung der Eingabemerkmale durch.
  • IntegerLookup-Ebene: Wandelt kategoriale Ganzzahlwerte in Ganzzahlindexe um.
  • CategoryEncoding-Ebene: Wandelt kategoriale Integer-Merkmale in dichte One-Hot-, Multi-Hot- oder TF-IDF-Darstellungen um.

Diese Ebenen können nicht trainiert werden. Stattdessen legen Sie den Status der Vorverarbeitungsebene fest, indem Sie sie über die Methode adapt() Trainingsdaten aussetzen.

Mit der folgenden Funktion wird eine Normalisierungsebene erstellt, die Sie für die Distanzfunktion verwenden können. Sie legen den Status vor dem Anpassen des Modells fest, indem Sie die Methode adapt() für die Trainingsdaten verwenden. Damit werden der Mittelwert und die Varianz für die Normalisierung berechnet. Wenn Sie das Validierungs-Dataset später an das Modell übergeben, werden die Validierungsdaten mit demselben Mittelwert und derselben Varianz skaliert, die für die Trainingsdaten berechnet wurden.

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

Mit der folgenden Funktion wird eine Kategoriecodierung erstellt, die Sie für die Merkmale „hour“ (Stunde) und „weekday“ (Wochentag) verwenden.

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))

Als Nächstes erstellen Sie den Vorverarbeitungsabschnitt des Modells. Erstellen Sie zuerst für jedes der Features einen tf.keras.Input-Layer.

# 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')

Erstellen Sie dann die Normalisierungs- und Kategoriecodierungsebenen und speichern Sie sie in einer Liste.

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)

Nachdem Sie die Vorverarbeitungsebenen definiert haben, können Sie den Rest des Modells definieren. Sie verketten alle Eingabe-Features und übergeben sie an eine Dense-Ebene. Die Ausgabeschicht besteht aus einer einzelnen Einheit, da es sich um ein Regressionsproblem handelt.

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)

Kompilieren Sie das Modell.

model.compile(optimizer = tf.keras.optimizers.Adam(0.001),
              loss='mean_squared_logarithmic_error')

Nachdem Sie das Modell definiert haben, können Sie die Architektur visualisieren.

tf.keras.utils.plot_model(model, show_shapes=True, rankdir="LR")

keras_model

Dieses Modell ist für diesen einfachen Datensatz relativ kompliziert. Es dient zu Demonstrationszwecken.

Wir trainieren nur eine Epoche lang, um zu bestätigen, dass der Code ausgeführt wird.

model.fit(train_dataset, validation_data = validation_dataset, epochs = 1)

Modell mit einer GPU trainieren

Als Nächstes trainieren Sie das Modell länger und verwenden den Hardware-Switcher, um das Training zu beschleunigen. Mit Vertex AI Workbench können Sie die Hardware ändern, ohne die Instanz herunterzufahren. Wenn Sie die GPU nur bei Bedarf hinzufügen, können Sie die Kosten senken.

Wenn Sie das Hardwareprofil ändern möchten, klicken Sie rechts oben auf den Maschinentyp und wählen Sie Hardware ändern aus.

modify_hardware

Wählen Sie „GPUs anhängen“ und dann eine NVIDIA T4 Tensor Core-GPU aus.

add_gpu

Die Konfiguration der Hardware dauert etwa fünf Minuten. Wenn der Vorgang abgeschlossen ist, trainieren wir das Modell noch etwas länger. Sie werden feststellen, dass jede Epoche jetzt weniger Zeit in Anspruch nimmt.

model.fit(train_dataset, validation_data = validation_dataset, epochs = 5)

🎉 Das wars! 🎉

Sie haben gelernt, wie Sie Vertex AI Workbench für folgende Aufgaben verwenden:

  • Daten in BigQuery analysieren
  • BigQuery-Client zum Laden von Daten in Python verwenden
  • TensorFlow-Modell mit Keras-Vorverarbeitungsebenen und einer GPU trainieren

Weitere Informationen zu den verschiedenen Bereichen von Vertex AI finden Sie in der Dokumentation.

7. Bereinigen

Da wir das Notebook so konfiguriert haben, dass es nach 60 Minuten Inaktivität ein Zeitlimit erreicht, müssen wir uns keine Gedanken über das Herunterfahren der Instanz machen. Wenn Sie die Instanz manuell herunterfahren möchten, klicken Sie im Bereich „Vertex AI Workbench“ der Console auf die Schaltfläche „Beenden“. Wenn Sie das Notebook vollständig löschen möchten, klicken Sie auf die Schaltfläche „Löschen“.

Löschen