1. Panoramica
In questo lab, seguirai un flusso di lavoro di addestramento ML completo su Google Cloud, utilizzando PyTorch per creare il tuo modello. Da un ambiente Cloud AI Platform Notebooks, imparerai a pacchettizzare il job di addestramento per eseguirlo su AI Platform Training con l'ottimizzazione degli iperparametri.
Cosa imparerai
Al termine del corso sarai in grado di:
- Crea un'istanza di AI Platform Notebooks
- Crea un modello PyTorch
- Addestra il tuo modello con l'ottimizzazione degli iperparametri su AI Platform Training
Il costo totale per l'esecuzione di questo lab su Google Cloud è di circa $1.
2. Configura l'ambiente
Per eseguire questo codelab, è necessario un progetto Google Cloud con fatturazione abilitata. Per creare un progetto, segui le istruzioni riportate qui.
Passaggio 1: abilita l'API Cloud AI Platform Models
Vai alla sezione Modelli di AI Platform della console Cloud e fai clic su Abilita se non è già abilitata.
Passaggio 2: abilita l'API Compute Engine
Passa a Compute Engine e seleziona Abilita se non è già abilitato. Ne avrai bisogno per creare la tua istanza di blocco note.
Passaggio 3: crea un'istanza di AI Platform Notebooks
Vai alla sezione AI Platform Notebooks della console Cloud e fai clic su Nuova istanza. Quindi, seleziona il tipo di istanza PyTorch più recente (senza GPU):
Utilizza le opzioni predefinite o, se vuoi, assegnagli un nome personalizzato, quindi fai clic su Crea. Una volta creata l'istanza, seleziona Apri JupyterLab:
Quindi, apri un'istanza di blocco note Python 3 dall'Avvio app:
Puoi iniziare subito.
Passaggio 5: importa i pacchetti Python
Nella prima cella del blocco note, aggiungi le seguenti importazioni ed esegui la cella. Per eseguirlo, premi il pulsante Freccia destra nel menu in alto o premi Invio:
import datetime
import numpy as np
import os
import pandas as pd
import time
Noterai che non stiamo importando PyTorch qui. Il motivo è che stiamo eseguendo il job di addestramento su AI Platform Training, non dalla nostra istanza di blocco note.
3. Crea un pacchetto per il job di addestramento
Per eseguire il nostro job di addestramento su AI Platform Training, avremo bisogno del nostro codice di addestramento pacchettizzato localmente nella nostra istanza Notebooks e di un bucket Cloud Storage per archiviare gli asset per il nostro job. Per prima cosa, creeremo un bucket di archiviazione. Puoi saltare questo passaggio se ne hai già uno.
Passaggio 1: crea un bucket Cloud Storage per il nostro modello
Per prima cosa, definiamo alcune variabili di ambiente che utilizzeremo nel resto del codelab. Inserisci i valori qui sotto con il nome del tuo progetto Google Cloud e il nome del bucket Cloud Storage che vuoi creare (deve essere univoco a livello globale):
# Update these to your own GCP project, model, and version names
GCP_PROJECT = 'your-gcp-project'
BOCKET_URL = 'gs://storage_bucket_name'
Ora siamo pronti per creare un bucket di archiviazione, a cui punteremo l'inizio del job di addestramento.
Esegui questo comando gsutil
dal blocco note per creare un bucket:
!gsutil mb $BUCKET_URL
Passaggio 2: crea i file iniziali per il nostro pacchetto Python
Per eseguire un job di addestramento su AI Platform, dovremo configurare il codice come pacchetto Python. È costituito da un file setup.py
nella directory principale che specifica eventuali dipendenze del pacchetto esterno, da una sottodirectory con il nome del nostro pacchetto (qui lo chiameremo trainer/
) e da un file __init__.py
vuoto all'interno di questa sottodirectory.
Per prima cosa, scriviamo il file setup.py. Stiamo usando la magia %%writefile di iPython per salvare il file nella nostra istanza. Qui abbiamo specificato tre librerie esterne che utilizzeremo nel nostro codice di addestramento: PyTorch, Scikit-learn e Pandas:
%%writefile setup.py
from setuptools import find_packages
from setuptools import setup
REQUIRED_PACKAGES = ['torch>=1.5', 'scikit-learn>=0.20', 'pandas>=1.0']
setup(
name='trainer',
version='0.1',
install_requires=REQUIRED_PACKAGES,
packages=find_packages(),
include_package_data=True,
description='My training application package.'
)
Ora creiamo la nostra directory trainer/ e il file init.py vuoto al suo interno. Python utilizza questo file per riconoscere che si tratta di un pacchetto:
!mkdir trainer
!touch trainer/__init__.py
Ora è tutto pronto per iniziare a creare il job di addestramento.
4. Visualizza l'anteprima del set di dati
Questo lab è incentrato sugli strumenti per l'addestramento dei modelli, ma ora diamo una rapida occhiata al set di dati che utilizzeremo per addestrare il modello da comprendere. Utilizzeremo il set di dati sulla natalità disponibile in BigQuery. Contiene dati sulle nascite degli Stati Uniti relativi a vari decenni. Utilizzeremo alcune colonne del set di dati per prevedere il peso alla nascita di un bambino. Il set di dati originale è piuttosto grande e ne utilizzeremo un sottoinsieme che abbiamo messo a disposizione in un bucket Cloud Storage.
Passaggio 1: scarica il set di dati sulla natalità di BigQuery
Scarichiamo la versione del set di dati che abbiamo reso disponibile per te in Cloud Storage in un DataFrame Pandas e la visualizziamo in anteprima.
natality = pd.read_csv('https://storage.googleapis.com/ml-design-patterns/natality.csv')
natality.head()
Questo set di dati ha poco meno di 100.000 righe. Utilizzeremo 5 caratteristiche per prevedere il peso alla nascita di un neonato: l'età della madre e del padre, le settimane di gestazione, l'aumento di peso della madre in libbre e il sesso del bambino rappresentato da un valore booleano.
5. Definire il job di addestramento con l'ottimizzazione degli iperparametri
Scriveremo il nostro script di addestramento in un file chiamato model.py all'interno della sottodirectory allenatore/ che abbiamo creato in precedenza. Il nostro job di addestramento verrà eseguito su AI Platform Training e utilizzerà il servizio di ottimizzazione degli iperparametri di AI Platform per trovare gli iperparametri ottimali per il nostro modello utilizzando l'ottimizzazione bayesiana.
Passaggio 1: crea lo script di addestramento
Per prima cosa, creiamo il file Python con il nostro script di addestramento. Quindi esamineremo cosa succede al suo interno. L'esecuzione di questo comando %%writefile scriverà il codice del modello in un file Python locale:
%%writefile trainer/model.py
import argparse
import hypertune
import numpy as np
import pandas as pd
import torch
import torch.nn as nn
import torch.optim as optim
from sklearn.utils import shuffle
from sklearn.preprocessing import LabelEncoder
from sklearn.preprocessing import normalize
def get_args():
"""Argument parser.
Returns:
Dictionary of arguments.
"""
parser = argparse.ArgumentParser(description='PyTorch MNIST')
parser.add_argument('--job-dir', # handled automatically by AI Platform
help='GCS location to write checkpoints and export ' \
'models')
parser.add_argument('--lr', # Specified in the config file
type=float,
default=0.01,
help='learning rate (default: 0.01)')
parser.add_argument('--momentum', # Specified in the config file
type=float,
default=0.5,
help='SGD momentum (default: 0.5)')
parser.add_argument('--hidden-layer-size', # Specified in the config file
type=int,
default=8,
help='hidden layer size')
args = parser.parse_args()
return args
def train_model(args):
# Get the data
natality = pd.read_csv('https://storage.googleapis.com/ml-design-patterns/natality.csv')
natality = natality.dropna()
natality = shuffle(natality, random_state = 2)
natality.head()
natality_labels = natality['weight_pounds']
natality = natality.drop(columns=['weight_pounds'])
train_size = int(len(natality) * 0.8)
traindata_natality = natality[:train_size]
trainlabels_natality = natality_labels[:train_size]
testdata_natality = natality[train_size:]
testlabels_natality = natality_labels[train_size:]
# Normalize and convert to PT tensors
normalized_train = normalize(np.array(traindata_natality.values), axis=0)
normalized_test = normalize(np.array(testdata_natality.values), axis=0)
train_x = torch.Tensor(normalized_train)
train_y = torch.Tensor(np.array(trainlabels_natality))
test_x = torch.Tensor(normalized_test)
test_y = torch.Tensor(np.array(testlabels_natality))
# Define our data loaders
train_dataset = torch.utils.data.TensorDataset(train_x, train_y)
train_dataloader = torch.utils.data.DataLoader(train_dataset, batch_size=128, shuffle=True)
test_dataset = torch.utils.data.TensorDataset(test_x, test_y)
test_dataloader = torch.utils.data.DataLoader(test_dataset, batch_size=128, shuffle=False)
# Define the model, while tuning the size of our hidden layer
model = nn.Sequential(nn.Linear(len(train_x[0]), args.hidden_layer_size),
nn.ReLU(),
nn.Linear(args.hidden_layer_size, 1))
criterion = nn.MSELoss()
# Tune hyperparameters in our optimizer
optimizer = optim.SGD(model.parameters(), lr=args.lr, momentum=args.momentum)
epochs = 20
for e in range(epochs):
for batch_id, (data, label) in enumerate(train_dataloader):
optimizer.zero_grad()
y_pred = model(data)
label = label.view(-1,1)
loss = criterion(y_pred, label)
loss.backward()
optimizer.step()
val_mse = 0
num_batches = 0
# Evaluate accuracy on our test set
with torch.no_grad():
for i, (data, label) in enumerate(test_dataloader):
num_batches += 1
y_pred = model(data)
mse = criterion(y_pred, label.view(-1,1))
val_mse += mse.item()
avg_val_mse = (val_mse / num_batches)
# Report the metric we're optimizing for to AI Platform's HyperTune service
# In this example, we're mimizing error on our test set
hpt = hypertune.HyperTune()
hpt.report_hyperparameter_tuning_metric(
hyperparameter_metric_tag='val_mse',
metric_value=avg_val_mse,
global_step=epochs
)
def main():
args = get_args()
print('in main', args)
train_model(args)
if __name__ == '__main__':
main()
Il job di addestramento prevede due funzioni, in cui la maggior parte del lavoro viene svolto.
get_args()
: analizza gli argomenti della riga di comando che passeremo al momento della creazione del job di addestramento, insieme agli iperparametri che vogliamo ottimizzare con AI Platform. In questo esempio, il nostro elenco di argomenti include solo gli iperparametri che verranno ottimizzati, ovvero il tasso di apprendimento, il momentum e il numero di neuroni del modello nello strato nascosto.train_model()
: qui scarichiamo i dati in un DataFrame Pandas, li normalizziamo, li convertiamo in Tensors PyTorch e quindi definiamo il modello. Per creare il modello utilizziamo l'APInn.Sequential
PyTorch, che ci consente di definire il modello come uno stack di strati:
model = nn.Sequential(nn.Linear(len(train_x[0]), args.hidden_layer_size),
nn.ReLU(),
nn.Linear(args.hidden_layer_size, 1))
Nota che invece di impostare come hardcoded la dimensione dello strato nascosto del modello, lo rendiamo un iperparametro che AI Platform ottimizzerà per noi. Ne parleremo nella prossima sezione.
Passaggio 2: utilizza il servizio di ottimizzazione degli iperparametri di AI Platform
Anziché provare manualmente diversi valori degli iperparametri e riaddestrare il modello ogni volta, utilizzeremo il servizio di ottimizzazione degli iperparametri di Cloud AI Platform. Se impostiamo il job di addestramento con argomenti degli iperparametri, AI Platform utilizzerà l'ottimizzazione bayesiana per trovare i valori ideali per gli iperparametri specificati.
Durante l'ottimizzazione degli iperparametri, una singola prova consiste in un'esecuzione di addestramento del nostro modello con una combinazione specifica di valori degli iperparametri. A seconda del numero di prove che eseguiamo, AI Platform utilizzerà i risultati delle prove completate per ottimizzare gli iperparametri selezionati per quelli futuri. Per configurare l'ottimizzazione degli iperparametri, dobbiamo passare un file di configurazione quando iniziamo il job di addestramento con alcuni dati su ciascuno degli iperparametri che stiamo ottimizzando.
Quindi, crea il file di configurazione in locale:
%%writefile config.yaml
trainingInput:
hyperparameters:
goal: MINIMIZE
maxTrials: 10
maxParallelTrials: 5
hyperparameterMetricTag: val_mse
enableTrialEarlyStopping: TRUE
params:
- parameterName: lr
type: DOUBLE
minValue: 0.0001
maxValue: 0.1
scaleType: UNIT_LINEAR_SCALE
- parameterName: momentum
type: DOUBLE
minValue: 0.0
maxValue: 1.0
scaleType: UNIT_LINEAR_SCALE
- parameterName: hidden-layer-size
type: INTEGER
minValue: 8
maxValue: 32
scaleType: UNIT_LINEAR_SCALE
Per ogni iperparametro, specifichiamo il tipo, l'intervallo di valori da ricercare e la scala su cui aumentare il valore in diverse prove.
All'inizio del lavoro specifichiamo anche la metrica per la quale stiamo eseguendo l'ottimizzazione. Tieni presente che al termine della funzione train_model()
riportata sopra, segnaliamo questa metrica ad AI Platform ogni volta che viene completata una prova. In questo caso stiamo riducendo al minimo l'errore quadratico medio del modello, perciò vogliamo utilizzare gli iperparametri che generano l'errore quadratico medio più basso per il modello. Il nome di questa metrica (val_mse
) corrisponde al nome che utilizziamo per la segnalazione quando chiamiamo report_hyperparameter_tuning_metric()
al termine di una prova.
6. Esegui un job di addestramento su AI Platform
In questa sezione inizieremo il nostro job di addestramento del modello con l'ottimizzazione degli iperparametri su AI Platform.
Passaggio 1: definisci alcune variabili di ambiente
Per prima cosa definiamo alcune variabili di ambiente che utilizzeremo per iniziare il lavoro di addestramento. Se vuoi eseguire il job in una regione diversa, aggiorna la variabile REGION di seguito:
MAIN_TRAINER_MODULE = "trainer.model"
TRAIN_DIR = os.getcwd() + '/trainer'
JOB_DIR = BUCKET_URL + '/output'
REGION = "us-central1"
Ogni job di addestramento su AI Platform deve avere un nome univoco. Esegui il comando seguente per definire una variabile per il nome del job utilizzando un timestamp:
timestamp = str(datetime.datetime.now().time())
JOB_NAME = 'caip_training_' + str(int(time.time()))
Passaggio 2: inizia il lavoro di addestramento
Creeremo il nostro job di addestramento utilizzando gcloud, Google Cloud CLI. Possiamo eseguire il comando direttamente nel blocco note, facendo riferimento alle variabili definite sopra:
!gcloud ai-platform jobs submit training $JOB_NAME \
--scale-tier basic \
--package-path $TRAIN_DIR \
--module-name $MAIN_TRAINER_MODULE \
--job-dir $JOB_DIR \
--region $REGION \
--runtime-version 2.1 \
--python-version 3.7 \
--config config.yaml
Se il job è stato creato correttamente, vai alla sezione Job della console di AI Platform per monitorare i log.
Passaggio 3: monitora il job
Nella sezione Job della console, fai clic sul job appena avviato per visualizzare i dettagli:
Quando inizierà la prima serie di prove, potrai vedere i valori degli iperparametri selezionati per ogni prova:
Al termine delle prove, il valore risultante della metrica di ottimizzazione (in questo caso val_mse
) verrà registrato qui. L'esecuzione del job dovrebbe richiedere 15-20 minuti e la dashboard avrà un aspetto simile a questo al termine del job (i valori esatti varieranno):
Per eseguire il debug di potenziali problemi e monitorare il job in modo più dettagliato, fai clic su Visualizza log nella pagina dei dettagli del job:
Ogni istruzione print()
nel codice di addestramento del modello verrà visualizzata qui. Se riscontri problemi, prova ad aggiungere altre istruzioni di stampa e ad avviare un nuovo processo di addestramento.
Una volta completato il job di addestramento, trova gli iperparametri che hanno prodotto il valore val_mse più basso. Puoi utilizzarli per addestrare ed esportare una versione finale del tuo modello o utilizzarle come indicazioni per avviare un altro job di addestramento con ulteriori prove di ottimizzazione degli iperparametri.
7. Esegui la pulizia
Se desideri continuare a utilizzare questo blocco note, ti consigliamo di disattivarlo quando non lo usi. Dall'interfaccia utente di Notebooks in Cloud Console, seleziona il blocco note, quindi seleziona Interrompi:
Per eliminare tutte le risorse che hai creato in questo lab, elimina l'istanza del blocco note anziché arrestarla.
Utilizzando il menu di navigazione nella console Cloud, vai a Storage ed elimina i bucket creati per archiviare gli asset del modello.