Esegui questo tutorial come blocco note in Colab | Visualizza il blocco note su GitHub |
Questo tutorial illustra l'ottimizzazione degli obiettivi condizionali di AI Platform Analyzer.
Set di dati
Il set di dati sul reddito del censimento utilizzato da questo campione per l'addestramento è ospitato dal repository di machine learning di UC Irvine.
Utilizzando dati del censimento che contengono l'età, l'istruzione, lo stato civile e l'occupazione di una persona (le caratteristiche), l'obiettivo sarà prevedere se la persona guadagna o meno più di 50.000 dollari all'anno (etichetta target). Dovrai addestrare un modello di regressione logistica che, date le informazioni di un individuo, restituisce un numero compreso tra 0 e 1. Questo valore può essere interpretato come la probabilità che un individuo abbia un reddito annuo superiore a 50.000 dollari.
Scopo
Questo tutorial illustra come utilizzare AI Platform Ottimizzatore per ottimizzare la ricerca di iperparametri per i modelli di machine learning.
Questo esempio implementa una demo di apprendimento automatico che ottimizza un modello di classificazione su un set di dati di censimento utilizzando AI Platform Ottimizzatore con algoritmi integrati AI Platform Training. Utilizzerai AI Platform Ottimizzatore per ottenere i valori degli iperparametri suggeriti e inviare job di addestramento dei modelli con i valori degli iperparametri suggeriti tramite gli algoritmi integrati di AI Platform Training.
Costi
Questo tutorial utilizza i componenti fatturabili di Google Cloud:
- AI Platform Training
- Cloud Storage
Scopri di più sui prezzi di AI Platform Training e sui prezzi di Cloud Storage e utilizza il Calcolatore prezzi per generare una stima dei costi in base all'utilizzo previsto.
Pacchetti di installazione e dipendenze PIP
Installa le dipendenze aggiuntive non installate nell'ambiente del blocco note.
- Utilizzare la versione GA principale più recente del framework.
! pip install -U google-api-python-client
! pip install -U google-cloud
! pip install -U google-cloud-storage
! pip install -U requests
# Automatically restart kernel after installs
import IPython
app = IPython.Application.instance()
app.kernel.do_shutdown(True)
Configura il tuo progetto Google Cloud
I passaggi seguenti sono obbligatori, indipendentemente dall'ambiente del blocco note.
Assicurati che la fatturazione sia abilitata per il progetto.
Se esegui questo blocco note in locale, devi installare Google Cloud SDK.
Inserisci l'ID progetto nella cella seguente. Poi esegui la cella per assicurarti che Cloud SDK usi il progetto corretto per tutti i comandi in questo blocco note.
Nota: Jupyter esegue le righe con prefisso !
come comandi della shell e interpola le variabili Python con prefisso $
in questi comandi.
PROJECT_ID = "[project-id]" #@param {type:"string"}
! gcloud config set project $PROJECT_ID
Autentica l'account Google Cloud
Se utilizzi AI Platform Notebooks, il tuo ambiente è già autenticato. Salta questi passaggi.
La cella seguente richiederà l'autenticazione due volte.
import sys
# If you are running this notebook in Colab, run this cell and follow the
# instructions to authenticate your Google Cloud account. This provides access
# to your Cloud Storage bucket and lets you submit training jobs and prediction
# requests.
if 'google.colab' in sys.modules:
from google.colab import auth as google_auth
google_auth.authenticate_user()
# If you are running this tutorial in a notebook locally, replace the string
# below with the path to your service account key and run this cell to
# authenticate your Google Cloud account.
else:
%env GOOGLE_APPLICATION_CREDENTIALS your_path_to_credentials.json
# Log in to your account on Google Cloud
! gcloud auth application-default login
! gcloud auth login
Importa librerie
import json
import time
import datetime
from googleapiclient import errors
Tutorial
Configurazione
Questa sezione definisce alcuni parametri e metodi util per chiamare le API AI Platform Analyzer. Inserisci le seguenti informazioni per iniziare.
# Update to your username
USER = '[user-id]' #@param {type: 'string'}
STUDY_ID = '{}_study_{}'.format(USER, datetime.datetime.now().strftime('%Y%m%d_%H%M%S')) #@param {type: 'string'}
REGION = 'us-central1'
def study_parent():
return 'projects/{}/locations/{}'.format(PROJECT_ID, REGION)
def study_name(study_id):
return 'projects/{}/locations/{}/studies/{}'.format(PROJECT_ID, REGION, study_id)
def trial_parent(study_id):
return study_name(study_id)
def trial_name(study_id, trial_id):
return 'projects/{}/locations/{}/studies/{}/trials/{}'.format(PROJECT_ID, REGION,
study_id, trial_id)
def operation_name(operation_id):
return 'projects/{}/locations/{}/operations/{}'.format(PROJECT_ID, REGION, operation_id)
print('USER: {}'.format(USER))
print('PROJECT_ID: {}'.format(PROJECT_ID))
print('REGION: {}'.format(REGION))
print('STUDY_ID: {}'.format(STUDY_ID))
Crea il client API
La cella seguente crea il client API generato automaticamente utilizzando il servizio di rilevamento delle API di Google. Lo schema API in formato JSON è ospitato in un bucket Cloud Storage.
from google.cloud import storage
from googleapiclient import discovery
_OPTIMIZER_API_DOCUMENT_BUCKET = 'caip-optimizer-public'
_OPTIMIZER_API_DOCUMENT_FILE = 'api/ml_public_google_rest_v1.json'
def read_api_document():
client = storage.Client(PROJECT_ID)
bucket = client.get_bucket(_OPTIMIZER_API_DOCUMENT_BUCKET)
blob = bucket.get_blob(_OPTIMIZER_API_DOCUMENT_FILE)
return blob.download_as_string()
ml = discovery.build_from_document(service=read_api_document())
print('Successfully built the client.')
Configurazione dello studio
In questo tutorial, AI Platform ottimizzato crea uno studio e richiede prove. Per ogni prova, creerai un job con algoritmo integrato di AI Platform Training per eseguire l'addestramento del modello utilizzando gli iperparametri suggeriti. Una misurazione per ogni prova viene riportata come modello accuracy
.
Le funzionalità dei parametri condizionali fornite da AI Platform Ottimizzatore definiscono uno spazio di ricerca ad albero per gli iperparametri. L'iperparametro di primo livello è model_type
e viene deciso tra LINEAR
e WIDE_AND_DEEP
. A ogni tipo di modello corrispondono iperparametri di secondo livello da ottimizzare:
- Se
model_type
èLINEAR
,learning_rate
è ottimizzato. - Se
model_type
èWIDE_AND_DEEP
,learning_rate
ednn_learning_rate
sono ottimizzati.
Di seguito è riportato un esempio di configurazione di studio, creato come dizionario Python gerarchico. È già compilato. Esegui la cella per configurare lo studio.
param_learning_rate = {
'parameter': 'learning_rate',
'type' : 'DOUBLE',
'double_value_spec' : {
'min_value' : 0.00001,
'max_value' : 1.0
},
'scale_type' : 'UNIT_LOG_SCALE',
'parent_categorical_values' : {
'values': ['LINEAR', 'WIDE_AND_DEEP']
},
}
param_dnn_learning_rate = {
'parameter': 'dnn_learning_rate',
'type' : 'DOUBLE',
'double_value_spec' : {
'min_value' : 0.00001,
'max_value' : 1.0
},
'scale_type' : 'UNIT_LOG_SCALE',
'parent_categorical_values' : {
'values': ['WIDE_AND_DEEP']
},
}
param_model_type = {
'parameter': 'model_type',
'type' : 'CATEGORICAL',
'categorical_value_spec' : {'values': ['LINEAR', 'WIDE_AND_DEEP']},
'child_parameter_specs' : [param_learning_rate, param_dnn_learning_rate,]
}
metric_accuracy = {
'metric' : 'accuracy',
'goal' : 'MAXIMIZE'
}
study_config = {
'algorithm' : 'ALGORITHM_UNSPECIFIED', # Let the service choose the `default` algorithm.
'parameters' : [param_model_type,],
'metrics' : [metric_accuracy,],
}
study = {'study_config': study_config}
print(json.dumps(study, indent=2, sort_keys=True))
Crea lo studio
Poi crea lo studio, che eseguirai in seguito per ottimizzare l'obiettivo.
# Creates a study
req = ml.projects().locations().studies().create(
parent=study_parent(), studyId=STUDY_ID, body=study)
try :
print(req.execute())
except errors.HttpError as e:
if e.resp.status == 409:
print('Study already existed.')
else:
raise e
Impostare parametri di input/output
Quindi, imposta i seguenti parametri di output.
OUTPUT_BUCKET
e OUTPUT_DIR
sono il bucket e la directory Cloud Storage utilizzati come "job_dir" per i job di AI Platform Training. OUTPUT_BUCKET
deve essere un bucket nel progetto e OUTPUT_DIR
è il nome che vuoi assegnare alla cartella di output nel bucket.
job_dir
avrà il formato "gs://$OUTPUT_BUCKET/$OUTPUT_DIR/"
TRAINING_DATA_PATH
è il percorso per il set di dati di addestramento degli input.
# `job_dir` will be `gs://${OUTPUT_BUCKET}/${OUTPUT_DIR}/${job_id}`
OUTPUT_BUCKET = '[output-bucket-name]' #@param {type: 'string'}
OUTPUT_DIR = '[output-dir]' #@param {type: 'string'}
TRAINING_DATA_PATH = 'gs://caip-optimizer-public/sample-data/raw_census_train.csv' #@param {type: 'string'}
print('OUTPUT_BUCKET: {}'.format(OUTPUT_BUCKET))
print('OUTPUT_DIR: {}'.format(OUTPUT_DIR))
print('TRAINING_DATA_PATH: {}'.format(TRAINING_DATA_PATH))
# Create the bucket in Cloud Storage
! gsutil mb -p $PROJECT_ID gs://$OUTPUT_BUCKET/
Valutazione delle metriche
Questa sezione definisce i metodi per eseguire la valutazione delle prove.
Per ogni prova, invia un job con algoritmo integrato di AI Platform per addestrare un modello di machine learning utilizzando gli iperparametri suggeriti dall'ottimizzatore di AI Platform. Al termine, ogni job scrive il file di riepilogo del modello in Cloud Storage. Puoi recuperare l'accuratezza del modello dalla directory del job e segnalarla come final_measurement
della prova.
import logging
import math
import subprocess
import os
import yaml
from google.cloud import storage
_TRAINING_JOB_NAME_PATTERN = '{}_condition_parameters_{}_{}'
_IMAGE_URIS = {'LINEAR' : 'gcr.io/cloud-ml-algos/linear_learner_cpu:latest',
'WIDE_AND_DEEP' : 'gcr.io/cloud-ml-algos/wide_deep_learner_cpu:latest'}
_STEP_COUNT = 'step_count'
_ACCURACY = 'accuracy'
def EvaluateTrials(trials):
"""Evaluates trials by submitting training jobs to AI Platform Training service.
Args:
trials: List of Trials to evaluate
Returns: A dict of <trial_id, measurement> for the given trials.
"""
trials_by_job_id = {}
mesurement_by_trial_id = {}
# Submits a AI Platform Training job for each trial.
for trial in trials:
trial_id = int(trial['name'].split('/')[-1])
model_type = _GetSuggestedParameterValue(trial, 'model_type', 'stringValue')
learning_rate = _GetSuggestedParameterValue(trial, 'learning_rate',
'floatValue')
dnn_learning_rate = _GetSuggestedParameterValue(trial, 'dnn_learning_rate',
'floatValue')
job_id = _GenerateTrainingJobId(model_type=model_type,
trial_id=trial_id)
trials_by_job_id[job_id] = {
'trial_id' : trial_id,
'model_type' : model_type,
'learning_rate' : learning_rate,
'dnn_learning_rate' : dnn_learning_rate,
}
_SubmitTrainingJob(job_id, trial_id, model_type, learning_rate, dnn_learning_rate)
# Waits for completion of AI Platform Training jobs.
while not _JobsCompleted(trials_by_job_id.keys()):
time.sleep(60)
# Retrieves model training result(e.g. global_steps, accuracy) for AI Platform Training jobs.
metrics_by_job_id = _GetJobMetrics(trials_by_job_id.keys())
for job_id, metric in metrics_by_job_id.items():
measurement = _CreateMeasurement(trials_by_job_id[job_id]['trial_id'],
trials_by_job_id[job_id]['model_type'],
trials_by_job_id[job_id]['learning_rate'],
trials_by_job_id[job_id]['dnn_learning_rate'],
metric)
mesurement_by_trial_id[trials_by_job_id[job_id]['trial_id']] = measurement
return mesurement_by_trial_id
def _CreateMeasurement(trial_id, model_type, learning_rate, dnn_learning_rate, metric):
if not metric[_ACCURACY]:
# Returns `none` for trials without metrics. The trial will be marked as `INFEASIBLE`.
return None
print(
'Trial {0}: [model_type = {1}, learning_rate = {2}, dnn_learning_rate = {3}] => accuracy = {4}'.format(
trial_id, model_type, learning_rate,
dnn_learning_rate if dnn_learning_rate else 'N/A', metric[_ACCURACY]))
measurement = {
_STEP_COUNT: metric[_STEP_COUNT],
'metrics': [{'metric': _ACCURACY, 'value': metric[_ACCURACY]},]}
return measurement
def _SubmitTrainingJob(job_id, trial_id, model_type, learning_rate, dnn_learning_rate=None):
"""Submits a built-in algo training job to AI Platform Training Service."""
try:
if model_type == 'LINEAR':
subprocess.check_output(_LinearCommand(job_id, learning_rate), stderr=subprocess.STDOUT)
elif model_type == 'WIDE_AND_DEEP':
subprocess.check_output(_WideAndDeepCommand(job_id, learning_rate, dnn_learning_rate), stderr=subprocess.STDOUT)
print('Trial {0}: Submitted job [https://console.cloud.google.com/ai-platform/jobs/{1}?project={2}].'.format(trial_id, job_id, PROJECT_ID))
except subprocess.CalledProcessError as e:
logging.error(e.output)
def _GetTrainingJobState(job_id):
"""Gets a training job state."""
cmd = ['gcloud', 'ai-platform', 'jobs', 'describe', job_id,
'--project', PROJECT_ID,
'--format', 'json']
try:
output = subprocess.check_output(cmd, stderr=subprocess.STDOUT, timeout=3)
except subprocess.CalledProcessError as e:
logging.error(e.output)
return json.loads(output)['state']
def _JobsCompleted(jobs):
"""Checks if all the jobs are completed."""
all_done = True
for job in jobs:
if _GetTrainingJobState(job) not in ['SUCCEEDED', 'FAILED', 'CANCELLED']:
print('Waiting for job[https://console.cloud.google.com/ai-platform/jobs/{0}?project={1}] to finish...'.format(job, PROJECT_ID))
all_done = False
return all_done
def _RetrieveAccuracy(job_id):
"""Retrices the accuracy of the trained model for a built-in algorithm job."""
storage_client = storage.Client(project=PROJECT_ID)
bucket = storage_client.get_bucket(OUTPUT_BUCKET)
blob_name = os.path.join(OUTPUT_DIR, job_id, 'model/deployment_config.yaml')
blob = storage.Blob(blob_name, bucket)
try:
blob.reload()
content = blob.download_as_string()
accuracy = float(yaml.safe_load(content)['labels']['accuracy']) / 100
step_count = int(yaml.safe_load(content)['labels']['global_step'])
return {_STEP_COUNT: step_count, _ACCURACY: accuracy}
except:
# Returns None if failed to load the built-in algo output file.
# It could be due to job failure and the trial will be `INFEASIBLE`
return None
def _GetJobMetrics(jobs):
accuracies_by_job_id = {}
for job in jobs:
accuracies_by_job_id[job] = _RetrieveAccuracy(job)
return accuracies_by_job_id
def _GetSuggestedParameterValue(trial, parameter, value_type):
param_found = [p for p in trial['parameters'] if p['parameter'] == parameter]
if param_found:
return param_found[0][value_type]
else:
return None
def _GenerateTrainingJobId(model_type, trial_id):
return _TRAINING_JOB_NAME_PATTERN.format(STUDY_ID, model_type, trial_id)
def _GetJobDir(job_id):
return os.path.join('gs://', OUTPUT_BUCKET, OUTPUT_DIR, job_id)
def _LinearCommand(job_id, learning_rate):
return ['gcloud', 'ai-platform', 'jobs', 'submit', 'training', job_id,
'--scale-tier', 'BASIC',
'--region', 'us-central1',
'--master-image-uri', _IMAGE_URIS['LINEAR'],
'--project', PROJECT_ID,
'--job-dir', _GetJobDir(job_id),
'--',
'--preprocess',
'--model_type=classification',
'--batch_size=250',
'--max_steps=1000',
'--learning_rate={}'.format(learning_rate),
'--training_data_path={}'.format(TRAINING_DATA_PATH)]
def _WideAndDeepCommand(job_id, learning_rate, dnn_learning_rate):
return ['gcloud', 'ai-platform', 'jobs', 'submit', 'training', job_id,
'--scale-tier', 'BASIC',
'--region', 'us-central1',
'--master-image-uri', _IMAGE_URIS['WIDE_AND_DEEP'],
'--project', PROJECT_ID,
'--job-dir', _GetJobDir(job_id),
'--',
'--preprocess',
'--test_split=0',
'--use_wide',
'--embed_categories',
'--model_type=classification',
'--batch_size=250',
'--learning_rate={}'.format(learning_rate),
'--dnn_learning_rate={}'.format(dnn_learning_rate),
'--max_steps=1000',
'--training_data_path={}'.format(TRAINING_DATA_PATH)]
Configurazione per richiedere suggerimenti/prove
client_id
: l'identificatore del cliente che richiede il suggerimento. Se più richieste SuggestTrialsRequest hanno lo stesso client_id
, il servizio restituisce la prova identica suggerita se la prova è PENDING
e fornisce una nuova prova se l'ultima prova suggerita è stata completata.
suggestion_count_per_request
: il numero di suggerimenti (prove) richiesti in una singola richiesta.
max_trial_id_to_stop
: il numero di prove da esplorare prima di fermarsi. È impostato su 4 per ridurre il tempo di esecuzione del codice, quindi non aspettarti convergenza. Per la convergenza, sarebbe probabilmente necessario essere circa 20 (una buona regola generale è moltiplicare la dimensionalità totale per 10).
client_id = 'client1' #@param {type: 'string'}
suggestion_count_per_request = 2 #@param {type: 'integer'}
max_trial_id_to_stop = 4 #@param {type: 'integer'}
print('client_id: {}'.format(client_id))
print('suggestion_count_per_request: {}'.format(suggestion_count_per_request))
print('max_trial_id_to_stop: {}'.format(max_trial_id_to_stop))
Richiedere ed eseguire prove dell'ottimizzazione di AI Platform
Esegui le prove.
current_trial_id = 0
while current_trial_id < max_trial_id_to_stop:
# Request trials
resp = ml.projects().locations().studies().trials().suggest(
parent=trial_parent(STUDY_ID),
body={'client_id': client_id, 'suggestion_count': suggestion_count_per_request}).execute()
op_id = resp['name'].split('/')[-1]
# Polls the suggestion long-running operations.
get_op = ml.projects().locations().operations().get(name=operation_name(op_id))
while True:
operation = get_op.execute()
if 'done' in operation and operation['done']:
break
time.sleep(1)
# Featches the suggested trials.
trials = []
for suggested_trial in get_op.execute()['response']['trials']:
trial_id = int(suggested_trial['name'].split('/')[-1])
trial = ml.projects().locations().studies().trials().get(name=trial_name(STUDY_ID, trial_id)).execute()
if trial['state'] not in ['COMPLETED', 'INFEASIBLE']:
print("Trial {}: {}".format(trial_id, trial))
trials.append(trial)
# Evaluates trials - Submit model training jobs using AI Platform Training built-in algorithms.
measurement_by_trial_id = EvaluateTrials(trials)
# Completes trials.
for trial in trials:
trial_id = int(trial['name'].split('/')[-1])
current_trial_id = trial_id
measurement = measurement_by_trial_id[trial_id]
print(("=========== Complete Trial: [{0}] =============").format(trial_id))
if measurement:
# Completes trial by reporting final measurement.
ml.projects().locations().studies().trials().complete(
name=trial_name(STUDY_ID, trial_id),
body={'final_measurement' : measurement}).execute()
else:
# Marks trial as `infeasbile` if when missing final measurement.
ml.projects().locations().studies().trials().complete(
name=trial_name(STUDY_ID, trial_id),
body={'trial_infeasible' : True}).execute()
[FACOLTATIVO] Crea prove utilizzando i tuoi parametri
Oltre a richiedere suggerimenti (il metodo suggest
) per i parametri al servizio, l'API di AI Platform Ottimizzatore consente anche agli utenti di creare prove (il metodo create
) utilizzando i propri parametri. Lo strumento di ottimizzazione di AI Platform ti aiuterà a tenere traccia degli esperimenti effettuati dagli utenti e a utilizzare le conoscenze per generare nuovi suggerimenti.
Ad esempio, se esegui un job di addestramento di modelli utilizzando i tuoi model_type
e learning_rate
anziché quelli suggeriti dall'ottimizzatore di AI Platform, puoi creare una prova come parte dello studio.
# User has to leave `trial.name` unset in CreateTrial request, the service will
# assign it.
custom_trial = {
"clientId": "client1",
"finalMeasurement": {
"metrics": [
{
"metric": "accuracy",
"value": 0.86
}
],
"stepCount": "1000"
},
"parameters": [
{
"parameter": "model_type",
"stringValue": "LINEAR"
},
{
"floatValue": 0.3869103706121445,
"parameter": "learning_rate"
}
],
"state": "COMPLETED"
}
trial = ml.projects().locations().studies().trials().create(
parent=trial_parent(STUDY_ID), body=custom_trial).execute()
print(json.dumps(trial, indent=2, sort_keys=True))
Elenca le prove
Elenca i risultati di ogni addestramento di prova per l'ottimizzazione.
resp = ml.projects().locations().studies().trials().list(parent=trial_parent(STUDY_ID)).execute()
print(json.dumps(resp, indent=2, sort_keys=True))
Eseguire la pulizia
Per eseguire la pulizia di tutte le risorse Google Cloud utilizzate in questo progetto, puoi eliminare il progetto Google Cloud che hai utilizzato per il tutorial.