1. Übersicht
In diesem Lab verwenden Sie Vertex AI, um einen Hyperparameter-Abstimmungsjob in Vertex AI Training auszuführen.
Dieses Lab ist Teil der Videoreihe Von Prototyp zur Produktion. Schließen Sie das vorherige Lab ab, bevor Sie mit diesem beginnen. Weitere Informationen finden Sie in der zugehörigen Videoreihe:
.
Lerninhalte
Die folgenden Themen werden behandelt:
- Code der Trainingsanwendung für die automatische Hyperparameter-Abstimmung ändern
- Hyperparameter-Abstimmungsjob mit dem Vertex AI Python SDK konfigurieren und starten
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 bindet die ML-Angebote in Google Cloud in eine nahtlose Entwicklungsumgebung ein. 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 enthält viele verschiedene Produkte zur Unterstützung von End-to-End-ML-Workflows. In diesem Lab liegt der Schwerpunkt auf den unten aufgeführten Produkten: Training und Workbench.
3. Umgebung einrichten
Führen Sie die Schritte im Lab Benutzerdefinierte Modelle mit Vertex AI trainieren aus, um Ihre Umgebung einzurichten.
4. Code der Trainingsanwendung containerisieren
Zum Senden dieses Trainingsjobs an Vertex AI fügen Sie Ihren Trainingsanwendungscode in einen Docker-Container ein und übertragen diesen Container per Push in Google Artifact Registry. Mit diesem Ansatz können Sie ein Modell trainieren und optimieren, das mit einem beliebigen Framework erstellt wurde.
Öffnen Sie zuerst im Launcher-Menü des Workbench-Notebooks, das Sie in den vorherigen Labs erstellt haben, ein Terminalfenster.
Schritt 1: Trainingscode schreiben
Erstellen Sie ein neues Verzeichnis mit dem Namen flowers-hptune
und fügen Sie es mit cd ein:
mkdir flowers-hptune
cd flowers-hptune
Führen Sie Folgendes aus, um ein Verzeichnis für den Trainingscode und eine Python-Datei zu erstellen, in die Sie den folgenden Code einfügen.
mkdir trainer
touch trainer/task.py
Ihr flowers-hptune/
-Verzeichnis sollte jetzt so aussehen:
+ trainer/
+ task.py
Öffnen Sie als Nächstes die soeben erstellte Datei task.py
und kopieren Sie den folgenden Code.
Sie müssen {your-gcs-bucket}
in BUCKET_ROOT
durch den Cloud Storage-Bucket ersetzen, in dem Sie das Blumen-Dataset in Lab 1 gespeichert haben.
import tensorflow as tf
import numpy as np
import os
import hypertune
import argparse
## Replace {your-gcs-bucket} !!
BUCKET_ROOT='/gcs/{your-gcs-bucket}'
# Define variables
NUM_CLASSES = 5
EPOCHS=10
BATCH_SIZE = 32
IMG_HEIGHT = 180
IMG_WIDTH = 180
DATA_DIR = f'{BUCKET_ROOT}/flower_photos'
def get_args():
'''Parses args. Must include all hyperparameters you want to tune.'''
parser = argparse.ArgumentParser()
parser.add_argument(
'--learning_rate',
required=True,
type=float,
help='learning rate')
parser.add_argument(
'--momentum',
required=True,
type=float,
help='SGD momentum value')
parser.add_argument(
'--num_units',
required=True,
type=int,
help='number of units in last hidden layer')
args = parser.parse_args()
return args
def create_datasets(data_dir, batch_size):
'''Creates train and validation datasets.'''
train_dataset = tf.keras.utils.image_dataset_from_directory(
data_dir,
validation_split=0.2,
subset="training",
seed=123,
image_size=(IMG_HEIGHT, IMG_WIDTH),
batch_size=batch_size)
validation_dataset = tf.keras.utils.image_dataset_from_directory(
data_dir,
validation_split=0.2,
subset="validation",
seed=123,
image_size=(IMG_HEIGHT, IMG_WIDTH),
batch_size=batch_size)
train_dataset = train_dataset.cache().shuffle(1000).prefetch(buffer_size=tf.data.AUTOTUNE)
validation_dataset = validation_dataset.cache().prefetch(buffer_size=tf.data.AUTOTUNE)
return train_dataset, validation_dataset
def create_model(num_units, learning_rate, momentum):
'''Creates model.'''
model = tf.keras.Sequential([
tf.keras.layers.Resizing(IMG_HEIGHT, IMG_WIDTH),
tf.keras.layers.Rescaling(1./255, input_shape=(IMG_HEIGHT, IMG_WIDTH, 3)),
tf.keras.layers.Conv2D(16, 3, padding='same', activation='relu'),
tf.keras.layers.MaxPooling2D(),
tf.keras.layers.Conv2D(32, 3, padding='same', activation='relu'),
tf.keras.layers.MaxPooling2D(),
tf.keras.layers.Conv2D(64, 3, padding='same', activation='relu'),
tf.keras.layers.MaxPooling2D(),
tf.keras.layers.Flatten(),
tf.keras.layers.Dense(num_units, activation='relu'),
tf.keras.layers.Dense(NUM_CLASSES, activation='softmax')
])
model.compile(optimizer=tf.keras.optimizers.SGD(learning_rate=learning_rate, momentum=momentum),
loss=tf.keras.losses.SparseCategoricalCrossentropy(),
metrics=['accuracy'])
return model
def main():
args = get_args()
train_dataset, validation_dataset = create_datasets(DATA_DIR, BATCH_SIZE)
model = create_model(args.num_units, args.learning_rate, args.momentum)
history = model.fit(train_dataset, validation_data=validation_dataset, epochs=EPOCHS)
# DEFINE METRIC
hp_metric = history.history['val_accuracy'][-1]
hpt = hypertune.HyperTune()
hpt.report_hyperparameter_tuning_metric(
hyperparameter_metric_tag='accuracy',
metric_value=hp_metric,
global_step=EPOCHS)
if __name__ == "__main__":
main()
Bevor Sie den Container erstellen, werfen wir einen genaueren Blick auf den Code. Es gibt einige Komponenten, die für die Verwendung des Hyperparameter-Abstimmungsdienstes spezifisch sind.
- Das Script importiert die
hypertune
-Bibliothek. - Die Funktion
get_args()
definiert ein Befehlszeilenargument für jeden Hyperparameter, den Sie abstimmen möchten. In diesem Beispiel werden die Hyperparameter Lernrate, der Momentum-Wert im Optimierer und die Anzahl der Einheiten in der letzten verborgenen Schicht des Modells angepasst. Sie können aber auch mit anderen experimentieren. Der in diesen Argumenten übergebene Wert wird dann verwendet, um den entsprechenden Hyperparameter im Code festzulegen. - Am Ende der
main()
-Funktion wird diehypertune
-Bibliothek verwendet, um den Messwert zu definieren, den Sie optimieren möchten. In TensorFlow gibt die Keras-Methodemodel.fit
einHistory
-Objekt zurück. Das AttributHistory.history
enthält Werte für den Trainingsverlust und Messwerte für aufeinanderfolgende Epochen. Wenn Sie Validierungsdaten anmodel.fit
übergeben, enthält das AttributHistory.history
auch Validierungsverlust und Messwertwerte. Wenn Sie beispielsweise ein Modell mit Validierungsdaten für drei Epochen trainiert undaccuracy
als Messwert angegeben haben, sieht das AttributHistory.history
in etwa so aus wie das folgende Wörterbuch.
{
"accuracy": [
0.7795261740684509,
0.9471358060836792,
0.9870933294296265
],
"loss": [
0.6340447664260864,
0.16712145507335663,
0.04546636343002319
],
"val_accuracy": [
0.3795261740684509,
0.4471358060836792,
0.4870933294296265
],
"val_loss": [
2.044623374938965,
4.100203514099121,
3.0728273391723633
]
Wenn der Dienst zur Hyperparameter-Abstimmung die Werte ermitteln soll, mit denen die Validierungsgenauigkeit des Modells maximiert wird, definieren Sie den Messwert als letzten Eintrag (oder NUM_EPOCS - 1
) der Liste val_accuracy
. Übergeben Sie diesen Messwert dann an eine Instanz von HyperTune
. Sie können einen beliebigen String für hyperparameter_metric_tag
auswählen. Sie müssen ihn jedoch später noch einmal verwenden, wenn Sie den Job zur Hyperparameter-Abstimmung starten.
Schritt 2: Dockerfile erstellen
Wenn Sie Ihren Code containerisieren möchten, müssen Sie ein Dockerfile erstellen. Im Dockerfile geben Sie alle Befehle an, die zum Ausführen des Images erforderlich sind. Damit werden alle erforderlichen Bibliotheken installiert und der Einstiegspunkt für den Trainingscode eingerichtet.
Erstellen Sie über Ihr Terminal ein leeres Dockerfile im Stammverzeichnis des flowers-hptune
-Verzeichnisses:
touch Dockerfile
Ihr flowers-hptune/
-Verzeichnis sollte jetzt Folgendes enthalten:
+ Dockerfile
+ trainer/
+ task.py
Öffnen Sie das Dockerfile und fügen Sie den folgenden Code ein. Sie werden feststellen, dass es fast identisch mit dem Dockerfile ist, das wir im ersten Lab verwendet haben, mit der Ausnahme, dass wir jetzt die cloudml-hypertune-Bibliothek installieren.
FROM gcr.io/deeplearning-platform-release/tf2-gpu.2-8
WORKDIR /
# Installs hypertune library
RUN pip install cloudml-hypertune
# Copies the trainer code to the docker image.
COPY trainer /trainer
# Sets up the entry point to invoke the trainer.
ENTRYPOINT ["python", "-m", "trainer.task"]
Schritt 3: Container erstellen
Führen Sie im Terminal den folgenden Befehl aus, um eine Umgebungsvariable für Ihr Projekt zu definieren. Ersetzen Sie dabei your-cloud-project
durch die ID Ihres Projekts:
PROJECT_ID='your-cloud-project'
Definieren Sie ein Repository in Artifact Registry. Wir verwenden das Repository, das wir im ersten Lab erstellt haben.
REPO_NAME='flower-app'
Definieren Sie in Google Artifact Registry eine Variable mit dem URI Ihres Container-Images:
IMAGE_URI=us-central1-docker.pkg.dev/$PROJECT_ID/$REPO_NAME/flower_image_hptune:latest
Docker konfigurieren
gcloud auth configure-docker \
us-central1-docker.pkg.dev
Erstellen Sie dann den Container, indem Sie im Stammverzeichnis von flower-hptune
Folgendes ausführen:
docker build ./ -t $IMAGE_URI
Übertragen Sie es dann per Push in die Artifact Registry:
docker push $IMAGE_URI
Nachdem der Container in Artifact Registry gepusht wurde, können Sie den Trainingsjob starten.
5. Hyperparameter-Abstimmungsjob mit dem SDK ausführen
In diesem Abschnitt erfahren Sie, wie Sie mit der Vertex Python API den Job zur Hyperparameter-Abstimmung konfigurieren und einreichen.
Erstellen Sie über den Launcher ein TensorFlow 2-Notebook.
Importieren Sie das Vertex AI SDK.
from google.cloud import aiplatform
from google.cloud.aiplatform import hyperparameter_tuning as hpt
Um den Hyperparameter-Abstimmungsjob zu starten, müssen Sie zuerst die worker_pool_specs
definieren, in der der Maschinentyp und das Docker-Image angegeben werden. In der folgenden Spezifikation wird ein Computer mit zwei NVIDIA Tesla V100-GPUs definiert.
Ersetzen Sie {PROJECT_ID}
in image_uri
durch Ihr Projekt.
# The spec of the worker pools including machine type and Docker image
# Be sure to replace PROJECT_ID in the `image_uri` with your project.
worker_pool_specs = [{
"machine_spec": {
"machine_type": "n1-standard-4",
"accelerator_type": "NVIDIA_TESLA_V100",
"accelerator_count": 1
},
"replica_count": 1,
"container_spec": {
"image_uri": "us-central1-docker.pkg.dev/{PROJECT_ID}/flower-app/flower_image_hptune:latest"
}
}]
Als Nächstes definieren Sie parameter_spec
. Das ist ein Dictionary, in dem die Parameter angegeben werden, die Sie optimieren möchten. Der Dictionary-Schlüssel ist der String, den Sie dem Befehlszeilenargument für jeden Hyperparameter zugewiesen haben. Der Dictionary-Wert ist die Parameterspezifikation.
Für jeden Hyperparameter müssen Sie den Typ sowie die Grenzen für die Werte definieren, die vom Abgleichsdienst ausprobiert werden sollen. Hyperparameter können vom Typ „Double“, „Integer“, „Categorical“ oder „Discrete“ sein. Wenn Sie den Typ „Dezimalzahl“ oder „Ganzzahl“ auswählen, müssen Sie einen Mindest- und einen Höchstwert angeben. Wenn Sie „Kategorisch“ oder „Diskret“ auswählen, müssen Sie die Werte angeben. Für die Typen „Doppelt“ und „Ganzzahl“ müssen Sie außerdem den Skalierungswert angeben. In diesem Video erfahren Sie mehr darüber, wie Sie die richtige Skalierung auswählen.
# Dictionary representing parameters to optimize.
# The dictionary key is the parameter_id, which is passed into your training
# job as a command line argument,
# And the dictionary value is the parameter specification of the metric.
parameter_spec = {
"learning_rate": hpt.DoubleParameterSpec(min=0.001, max=1, scale="log"),
"momentum": hpt.DoubleParameterSpec(min=0, max=1, scale="linear"),
"num_units": hpt.DiscreteParameterSpec(values=[64, 128, 512], scale=None)
}
Die letzte Spezifikation, die Sie definieren müssen, ist metric_spec
. Das ist ein Wörterbuch, das den zu optimierenden Messwert darstellt. Der Wörterbuchschlüssel ist die hyperparameter_metric_tag
, die Sie im Code Ihrer Trainingsanwendung festgelegt haben, und der Wert ist das Zielvorhaben für die Optimierung.
# Dictionary representing metric to optimize.
# The dictionary key is the metric_id, which is reported by your training job,
# And the dictionary value is the optimization goal of the metric.
metric_spec={'accuracy':'maximize'}
Nachdem Sie die Spezifikationen definiert haben, erstellen Sie einen CustomJob. Dies ist die gemeinsame Spezifikation, mit der Ihr Job in jedem der Tests zur Hyperparameter-Abstimmung ausgeführt wird.
Ersetzen Sie {YOUR_BUCKET}
durch den zuvor erstellten Bucket.
# Replace YOUR_BUCKET
my_custom_job = aiplatform.CustomJob(display_name='flowers-hptune-job',
worker_pool_specs=worker_pool_specs,
staging_bucket='gs://{YOUR_BUCKET}')
Erstellen Sie dann den HyperparameterTuningJob
und führen Sie ihn aus.
hp_job = aiplatform.HyperparameterTuningJob(
display_name='flowers-hptune-job',
custom_job=my_custom_job,
metric_spec=metric_spec,
parameter_spec=parameter_spec,
max_trial_count=15,
parallel_trial_count=3)
hp_job.run()
Es gibt einige Argumente, die Sie beachten sollten:
- max_trial_count: Sie müssen eine Obergrenze für die Anzahl der Tests festlegen, die vom Dienst ausgeführt werden. Mehr Tests führen in der Regel zu besseren Ergebnissen. Es gibt jedoch einen Punkt, ab dem zusätzliche Tests wenig oder gar keinen Einfluss auf den Messwert haben, den Sie optimieren möchten. Es empfiehlt sich, mit einer kleineren Anzahl von Tests zu beginnen und sich ein Bild davon zu machen, wie sich die ausgewählten Hyperparameter auswirken, bevor Sie die Anzahl erhöhen.
- parallel_trial_count: Wenn Sie parallele Tests verwenden, stellt der Dienst mehrere Trainingsverarbeitungscluster bereit. Wenn Sie die Anzahl der parallelen Tests erhöhen, verkürzt sich die Ausführungszeit des Hyperparameter-Abstimmungsjobs. Dies kann jedoch die Effektivität des Jobs insgesamt beeinträchtigen. Das liegt daran, dass die Standardabstimmungsstrategie die Ergebnisse vorheriger Tests verwendet, um die Werte in nachfolgenden Tests zuzuweisen.
- search_algorithm: Sie können den Suchalgorithmus auf „grid“ (Raster), „random“ (Zufallsmix) oder „default“ (Standard) festlegen. Bei der Standardoption wird die Bayes'sche Optimierung angewendet, um den Bereich möglicher Hyperparameter-Werte zu durchsuchen. Dies ist der empfohlene Algorithmus. Weitere Informationen zu diesem Algorithmus finden Sie hier.
In der Konsole sehen Sie den Fortschritt des Jobs.
Nach Abschluss des Tests sehen Sie die Ergebnisse der einzelnen Tests und welche Werte die beste Leistung erzielt haben.
🎉 Glückwunsch! 🎉
Sie haben gelernt, wie Sie mit Vertex AI Folgendes tun können:
- Automatischen Hyperparameter-Abstimmungsjob ausführen
Weitere Informationen zu den verschiedenen Bereichen von Vertex finden Sie in der Dokumentation.
6. 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“.
Wenn Sie den Storage-Bucket löschen möchten, gehen Sie im Navigationsmenü der Cloud Console zu „Storage“, wählen Sie den Bucket aus und klicken Sie auf „Löschen“: