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
  • BigQuery-Connector von Vertex AI Workbench verwenden
  • Modell auf einem Vertex AI Workbench-Kernel trainieren

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

2. Einführung in Vertex AI

In diesem Lab wird das neueste KI-Angebot von Google Cloud verwendet. Vertex AI integriert die ML-Angebote in Google Cloud für eine nahtlose Entwicklung. Bisher waren mit AutoML trainierte und benutzerdefinierte Modelle über separate Dienste zugänglich. Das neue Angebot kombiniert beide zusammen mit anderen neuen Produkten in 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 liegt der Schwerpunkt auf Vertex AI Workbench.

Mit Vertex AI Workbench können Nutzer schnell End-to-End-Notebook-basierte Workflows erstellen, da die Datendienste wie Dataproc, Dataflow, BigQuery und Dataplex sowie Vertex AI tief integriert sind. Damit können Data Scientists eine Verbindung zu GCP-Datendiensten herstellen, Datensätze analysieren, mit verschiedenen Modellierungstechniken experimentieren, trainierte Modelle in der Produktion bereitstellen und MLOps während des gesamten Modelllebenszyklus verwalten.

3. Anwendungsfall – Übersicht

In diesem Lab untersuchen Sie das Dataset Fahrradvermietung in London. Diese Daten enthalten Informationen über Radtouren des öffentlichen Bike-Sharing-Programms in London seit 2011. Sie beginnen damit, diesen Datensatz in BigQuery über den BigQuery-Connector von Vertex AI Workbench zu untersuchen. Anschließend laden Sie die Daten mit Pandas in ein Jupyter-Notebook und trainieren ein TensorFlow-Modell, um die Dauer einer Fahrradfahrt anhand des Zeitpunkts und der zurückgelegten Strecke vorherzusagen.

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

4. Umgebung einrichten

Sie benötigen ein Google Cloud-Projekt mit aktivierter Abrechnung, um dieses Codelab ausführen zu können. Eine Anleitung zum Erstellen eines Projekts finden Sie hier.

Schritt 1: Compute Engine API aktivieren

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

Schritt 2: Vertex AI API aktivieren

Rufen Sie den Bereich „Vertex AI“ der 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 noch nicht geschehen.

Notebook_api

Klicken Sie nach der Aktivierung auf VERWALTETE NOTEBOOKS:

Notebooks_UI

Wählen Sie dann NEUES NOTIZBUCH aus.

new_notebook

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

service_account

Wähle Erweiterte Einstellungen aus.

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

enable_terminal

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

Klicken Sie dann auf Erstellen.

Nachdem die Instanz erstellt wurde, wählen Sie OPEN JUPYTERLAB (JUPYTERLAB ÖFFNEN) aus.

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 analysieren und abfragen. Neben den Datasets in Ihrem Projekt können Sie auch Datasets in anderen Projekten untersuchen. Klicken Sie dazu auf die Schaltfläche Projekt hinzufügen.

anpinnen

In diesem Lab verwenden Sie Daten aus den öffentlichen Datasets in BigQuery. Scrollen Sie nach unten zum Dataset london_bicycles. Dieses Dataset enthält zwei Tabellen: cycle_hire und cycle_stations. Sehen wir uns diese genauer an.

london_bike_ds

Doppelklicken Sie zuerst auf die Tabelle cycle_hire. Die Tabelle wird in einem neuen Tab mit dem Schema der Tabelle und Metadaten wie der Anzahl der Zeilen und der Größe geöffnet.

cycle_hire_ds

Wenn Sie auf den Tab Vorschau klicken, sehen Sie eine Stichprobe der Daten. Führen wir eine einfache Abfrage aus, um die beliebtesten Strecken zu ermitteln. Klicken Sie zuerst auf die Schaltfläche Tabelle abfragen.

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

In den Abfrageergebnissen sehen Sie, dass Radfahrten zur und von der Haltestelle Hyde Park Corner am beliebtesten waren.

journey_query_results

Klicken Sie dann doppelt auf die Tabelle cycle_stations, die Informationen zu den einzelnen Stationen enthält.

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

Dazu verwenden Sie die geografischen Funktionen von BigQuery. Dazu wandeln Sie jeden Breiten-/Längengrad-String in einen ST_GEOGPOINT um und berechnen mit der Funktion ST_DISTANCE die gerade Entfernung in Metern zwischen den beiden Punkten. Sie verwenden diesen Wert als Proxy für die zurückgelegte Strecke bei jeder Radfahrt.

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 wir die Tabelle „stations“ zweimal zusammenführen müssen, um die Koordinaten sowohl für die Start- als auch für die Endstation des Fahrradwegs 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 auf einem TensorFlow-Kernel trainieren

Vertex AI Workbench hat eine Computing-Kompatibilitätsebene, mit der Sie Kernel für TensorFlow, PySpark, R usw. über eine einzige Notebookinstanz 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. Sie 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 auch ändern und mit dem gesamten Datensatz experimentieren.

Importieren Sie als Nächstes 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 diese datetime direkt im Modell zu verwenden, erstellen Sie zwei neue Funktionen, die den Wochentag und die Uhrzeit der Fahrradfahrt 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'])

Wandeln Sie schließlich die Spalte „Dauer“ von Sekunden in Minuten um, damit Sie sie leichter verstehen.

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

Sehen Sie sich die ersten Zeilen des formatierten DataFrames an. Für jede Radfahrt haben Sie jetzt Daten zum Wochentag und zur Uhrzeit der Fahrt sowie zur zurückgelegten Strecke. Anhand dieser Informationen versuchen Sie, vorherzusagen, wie lange die Fahrt gedauert hat.

data.head()

data_head

Bevor Sie das Modell erstellen und trainieren können, müssen Sie die Daten in Trainings- und Validierungssätze 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. Zur Vorverarbeitung der Eingabedaten verwenden Sie die Keras Preprocessing Layers API.

Die folgende Dienstfunktion erstellt eine tf.data.Dataset aus dem pandas-DataFrame.

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, eine für das Training und eine 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 im Modell die folgenden Schichten für die Vorverarbeitung:

  • Normalisierungsschicht: Führt eine merkmalsspezifische Normalisierung der Eingabemerkmale durch.
  • IntegerLookup-Ebene: Wandelt kategorische Ganzzahlwerte in Ganzzahlindexe um.
  • CategoryEncoding-Ebene: Wandelt kategorische Ganzzahlmerkmale in One-Hot-, Multi-Hot- oder TF-IDF-dichte Darstellungen um.

Diese Schichten sind nicht trainierbar. Stattdessen legen Sie den Status der Vorverarbeitungsebene fest, indem Sie sie mithilfe der Methode adapt() für Trainingsdaten freigeben.

Mit der folgenden Funktion wird eine Normalisierungsebene erstellt, die Sie auf die Entfernungsfunktion anwenden können. Sie legen den Status vor dem Anpassen des Modells fest, indem Sie die Methode adapt() auf die Trainingsdaten anwenden. Dadurch werden Mittelwert und Varianz berechnet, die für die Normalisierung verwendet werden. Wenn Sie das Validierungs-Dataset später an das Modell übergeben, werden dieselben Mittelung und Abweichung, die anhand der Trainingsdaten berechnet wurden, verwendet, um die Validierungsdaten zu skalieren.

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 Kategorisierung erstellt, die Sie für die Merkmale „Stunde“ und „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 Vorverarbeitungsteil des Modells. Erstellen Sie zuerst für jedes Element eine tf.keras.Input-Ebene.

# 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 Schichten für die Vorverarbeitung definiert haben, können Sie den Rest des Modells definieren. Sie konkatenieren alle Eingabemerkmale und übergeben sie an eine dichte Schicht. 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 schließlich 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

Beachten Sie, dass dieses Modell für diesen einfachen Datensatz ziemlich kompliziert ist. Es dient nur zu Demonstrationszwecken.

Trainieren wir eine Epoche, 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-Schalter, um das Training zu beschleunigen. Mit Vertex AI Workbench können Sie die Hardware ändern, ohne die Instanz herunterzufahren. Wenn Sie die GPU nur hinzufügen, wenn Sie sie benötigen, 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. Trainieren wir das Modell noch etwas länger, sobald der Vorgang abgeschlossen ist. Sie werden feststellen, dass jede Epoche jetzt weniger Zeit in Anspruch nimmt.

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

🎉 Glückwunsch! 🎉

Sie haben gelernt, wie Sie mit Vertex AI Workbench Folgendes tun:

  • Daten in BigQuery untersuchen
  • Daten mit dem BigQuery-Client in Python laden
  • TensorFlow-Modell mit Keras-Vorverarbeitungsschichten und einer GPU trainieren

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

7. Bereinigen

Da wir das Notebook so konfiguriert haben, dass nach 60 Minuten Inaktivität eine Zeitüberschreitung auftritt, müssen wir uns nicht um das Herunterfahren der Instanz kümmern. Wenn Sie die Instanz manuell herunterfahren möchten, klicken Sie in der Console im Bereich „Vertex AI Workbench“ auf die Schaltfläche „Beenden“. Wenn Sie das Notizbuch vollständig löschen möchten, klicken Sie auf die Schaltfläche „Löschen“.

Löschen