1. Panoramica
In questo lab imparerai a utilizzare Vertex AI Workbench per l'esplorazione dei dati e l'addestramento di modelli ML.
Cosa imparerai
Al termine del corso sarai in grado di:
- Crea e configura un'istanza di Vertex AI Workbench
- Utilizzare il connettore BigQuery di Vertex AI Workbench
- Addestrare un modello su un kernel Vertex AI Workbench
Il costo totale per eseguire questo lab su Google Cloud è di circa 1$.
2. Introduzione a Vertex AI
Questo lab utilizza la più recente offerta di prodotti AI disponibile su Google Cloud. Vertex AI integra le offerte ML di Google Cloud in un'esperienza di sviluppo fluida. In precedenza, i modelli addestrati con AutoML e i modelli personalizzati erano accessibili tramite servizi separati. La nuova offerta combina entrambi in un'unica API, insieme ad altri nuovi prodotti. Puoi anche migrare progetti esistenti su Vertex AI.
Vertex AI include molti prodotti diversi per supportare i flussi di lavoro ML end-to-end. Questo lab si concentrerà su Vertex AI Workbench.
Vertex AI Workbench aiuta gli utenti a creare rapidamente flussi di lavoro end-to-end basati su notebook tramite un'integrazione profonda con i servizi di dati (come Dataproc, Dataflow, BigQuery e Dataplex) e Vertex AI. Consente ai data scientist di connettersi ai servizi dati di Google Cloud, analizzare i set di dati, sperimentare diverse tecniche di modellazione, eseguire il deployment dei modelli addestrati in produzione e gestire MLOps durante il ciclo di vita del modello.
3. Panoramica del caso d'uso
In questo lab esplorerai il set di dati London Bicycles Hire. Questi dati contengono informazioni sui viaggi in bicicletta del programma pubblico di bike sharing di Londra dal 2011. Inizierai esplorando questo set di dati in BigQuery tramite il connettore BigQuery di Vertex AI Workbench. Quindi caricherai i dati in un blocco note Jupyter utilizzando Pandas e addestrerai un modello TensorFlow per prevedere la durata di una corsa in ciclo in base a quando si è verificato il viaggio e a quanto tempo ha percorso la persona.
Questo lab utilizza gli strati di pre-elaborazione di Keras per trasformare e preparare i dati di input per l'addestramento del modello. Questa API ti consente di creare la pre-elaborazione direttamente nel grafico del modello TensorFlow, riducendo il rischio di asimmetria di addestramento/pubblicazione garantendo che i dati di addestramento e di pubblicazione subiscano trasformazioni identiche. Tieni presente che, a partire da TensorFlow 2.6, questa API è stabile. Se utilizzi una versione precedente di TensorFlow, dovrai importare il simbolo sperimentale.
4. Configura l'ambiente
Per eseguire questo codelab, devi avere un progetto Google Cloud con la fatturazione abilitata. Per creare un progetto, segui le istruzioni riportate qui.
Passaggio 1: abilita l'API Compute Engine
Vai a Compute Engine e seleziona Attiva se non è già abilitato.
Passaggio 2: attiva l'API Vertex AI
Vai alla sezione Vertex AI della console Cloud e fai clic su Abilita API Vertex AI.
Passaggio 3: crea un'istanza di Vertex AI Workbench
Nella sezione Vertex AI della console Cloud, fai clic su Workbench:
Se non l'hai ancora fatto, abilita l'API Notebooks.
Dopo averla attivata, fai clic su NOTEBOOK GESTITI:
Quindi seleziona NUOVO NOTEBOOK.
Assegna un nome al notebook e in Autorizzazione seleziona Account di servizio.
Seleziona Impostazioni avanzate.
In Sicurezza, seleziona "Abilita terminale" se non è già attivato.
Puoi lasciare invariate tutte le altre impostazioni avanzate.
Poi, fai clic su Crea.
Una volta creata l'istanza, seleziona APRI JUPYTERLAB.
5. Esplorare il set di dati in BigQuery
Nell'istanza di Vertex AI Workbench, vai a sinistra e fai clic sul connettore BigQuery in Notebooks.
Il connettore BigQuery ti consente di esplorare ed eseguire query sui set di dati BigQuery con facilità. Oltre ai set di dati nel tuo progetto, puoi esplorare quelli in altri progetti facendo clic sul pulsante Aggiungi progetto.
Per questo lab utilizzerai i dati dei set di dati pubblici di BigQuery. Scorri verso il basso fino a trovare il set di dati london_bicycles. Vedrai che questo set di dati contiene due tabelle, cycle_hire e cycle_stations. Vediamoli uno per uno.
Innanzitutto, fai doppio clic sulla tabella cycle_hire. La tabella si apre in una nuova scheda con lo schema della tabella e metadati come il numero di righe e le dimensioni.
Se fai clic sulla scheda Anteprima, puoi visualizzare un campione dei dati. Eseguiamo una semplice query per vedere quali sono i percorsi più frequenti. Innanzitutto, fai clic sul pulsante Query table (Esegui query sulla tabella).
Poi, incolla quanto segue nell'editor SQL e fai clic su Invia query.
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
Dai risultati della query, vedrai che i viaggi in bicicletta da e verso la stazione Hyde Park Corner sono stati i più apprezzati.
Quindi, fai doppio clic sulla tabella cycle_stations, che fornisce informazioni su ciascuna stazione.
Vogliamo unire le tabelle cycle_hire e cycle_stations. La tabella cycle_stations contiene lat/lon per ogni stazione. Potrai utilizzare queste informazioni per stimare la distanza percorsa in ogni viaggio in bici calcolando la distanza tra le stazioni di partenza e di arrivo.
Per eseguire questo calcolo, utilizzerai le funzioni geografiche di BigQuery. Nello specifico, convertirai ogni stringa lat/lon in un ST_GEOGPOINT e utilizzerai la funzione ST_DISTANCE per calcolare la distanza in linea retta in metri tra i due punti. Utilizzerai questo valore come sostituto della distanza percorsa in ogni viaggio in bicicletta.
Copia la seguente query nell'editor SQL e fai clic su Invia query. Tieni presente che nella condizione JOIN sono presenti tre tabelle perché dobbiamo unire la tabella stazioni due volte per ottenere lat/lon sia per la stazione di partenza che per quella di arrivo del ciclo.
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. Addestra un modello ML su un kernel TensorFlow
Vertex AI Workbench dispone di un livello di compatibilità di calcolo che ti consente di avviare kernel per TensorFlow, PySpark, R e così via, il tutto da una singola istanza di notebook. In questo lab creerai un notebook utilizzando il kernel TensorFlow.
Crea DataFrame
Dopo l'esecuzione della query, fai clic su Copia codice per DataFrame. In questo modo potrai incollare il codice Python in un blocco note che si connette al client BigQuery ed estrae questi dati come DataFrame pandas.
Torna al programma di avvio e crea un blocco note TensorFlow 2.
Nella prima cella del blocco note, incolla il codice copiato dall'Editor di query. Dovrebbe avere il seguente aspetto:
# 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()
Ai fini di questo lab, limitiamo il set di dati a 700.000 per ridurre il tempo di addestramento. Tuttavia, non esitare a modificare la query ed eseguire esperimenti sull'intero set di dati.
Importa poi le librerie necessarie.
from datetime import datetime
import pandas as pd
import tensorflow as tf
Esegui questo codice per creare un dataframe ridotto che contenga solo le colonne necessarie per la parte ML di questo esercizio.
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()
La colonna start_date è un datetime
di Python. Anziché utilizzare direttamente questo datetime
nel modello, creerai due nuove funzionalità che indicano il giorno della settimana e l'ora del giorno in cui si è verificato il viaggio in bicicletta.
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'])
Infine, converti la colonna della durata da secondi a minuti per facilitarne la comprensione.
data['duration'] = data['duration'].apply(lambda x:float(x / 60))
Esamina le prime righe del DataFrame formattato. Per ogni viaggio in bici ora disponi dei dati sul giorno della settimana, sull'ora del giorno in cui si è verificato il viaggio e sulla distanza percorsa. Da queste informazioni, dovrai prevedere la durata del viaggio.
data.head()
Prima di poter creare e addestrare il modello, devi suddividere i dati in set di addestramento e convalida.
# 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:]
Crea un modello TensorFlow
Creerai un modello TensorFlow utilizzando l'API Keras Functional. Per pre-elaborare i dati di input, utilizzerai l'API degli strati di pre-elaborazione di Keras.
La seguente funzione di utilità creerà un tf.data.Dataset
dal DataFrame pandas.
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
Utilizza la funzione precedente per creare due tf.data.Dataset
, uno per l'addestramento e uno per la convalida. Potresti vedere alcuni avvisi, ma puoi tranquillamente ignorarli.
train_dataset = df_to_dataset(train_data, 'duration')
validation_dataset = df_to_dataset(val_data, 'duration')
Nel modello, utilizzerai i seguenti strati di pre-elaborazione:
- Livello di normalizzazione: esegue la normalizzazione delle caratteristiche di input in base alle caratteristiche.
- Strato IntegerLookup: trasforma i valori categorici interi in indici di numeri interi.
- Livello CategoryEncoding: trasforma le caratteristiche categoriche intere in rappresentazioni dense con codifica one-hot, multi-hot o TF-IDF.
Tieni presente che questi livelli non sono addestrabili. Imposti invece lo stato del livello di preelaborazione esponendolo ai dati di addestramento tramite il metodo adapt()
.
La seguente funzione crea un livello di normalizzazione che puoi utilizzare per la funzionalità di distanza. Imposterai lo stato prima di adattare il modello utilizzando il metodo adapt()
sui dati di addestramento. Verranno calcolate la media e la varianza da utilizzare per la normalizzazione. In seguito, quando passi il set di dati di convalida al modello, queste stesse medie e varianze calcolate sui dati di addestramento verranno utilizzate per scalare i dati di convalida.
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
Analogamente, la seguente funzione crea una codifica delle categorie da utilizzare per le funzionalità relative all'ora e al giorno della settimana.
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))
Quindi, crea la parte di pre-elaborazione del modello. Innanzitutto, crea un livello tf.keras.Input
per ogni elemento.
# 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')
Poi crea i livelli di normalizzazione e codifica delle categorie, archiviandoli in un elenco.
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)
Dopo aver definito gli strati di preelaborazione, puoi definire il resto del modello. Concatena tutte le funzionalità di input e passale a un livello denso. Il livello di output è una singola unità poiché si tratta di un problema di regressione.
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)
Infine, compila il modello.
model.compile(optimizer = tf.keras.optimizers.Adam(0.001),
loss='mean_squared_logarithmic_error')
Ora che hai definito il modello, puoi visualizzare l'architettura
tf.keras.utils.plot_model(model, show_shapes=True, rankdir="LR")
Tieni presente che questo modello è piuttosto complicato per questo semplice set di dati. È destinato a scopi dimostrativi.
Eseguiamo l'addestramento per un'epoca per verificare che il codice venga eseguito.
model.fit(train_dataset, validation_data = validation_dataset, epochs = 1)
Addestra il modello con una GPU
Successivamente, addestrerai il modello per più tempo e utilizzerai il selettore hardware per velocizzare l'addestramento. Vertex AI Workbench ti consente di cambiare l'hardware senza arrestare l'istanza. Aggiungendo la GPU solo quando serve, puoi ridurre i costi.
Per modificare il profilo hardware, fai clic sul tipo di macchina nell'angolo in alto a destra e seleziona Modifica hardware.
Seleziona Collega GPU e scegli una GPU NVIDIA T4 Tensor Core.
La configurazione dell'hardware richiede circa cinque minuti. Al termine della procedura, addestriamo il modello ancora per un po'. Noterai che ora ogni epoca richiede meno tempo.
model.fit(train_dataset, validation_data = validation_dataset, epochs = 5)
🎉 Complimenti! 🎉
Hai imparato a utilizzare Vertex AI Workbench per:
- Esplorare i dati in BigQuery
- Utilizzare il client BigQuery per caricare i dati in Python
- Addestrare un modello TensorFlow con gli strati di pre-elaborazione di Keras e una GPU
Per saperne di più sulle diverse parti di Vertex AI, consulta la documentazione.
7. Esegui la pulizia
Poiché abbiamo configurato il timeout del blocco note dopo 60 minuti di inattività, non dobbiamo preoccuparci di arrestare l'istanza. Se vuoi arrestare manualmente l'istanza, fai clic sul pulsante Arresta nella sezione Vertex AI Workbench della console. Per eliminare completamente il blocco note, fai clic sul pulsante Elimina.