1. Przegląd
W tym module użyjesz Vertex AI do uruchomienia zadania dostrajania hiperparametrów w Vertex AI Training.
Ten moduł jest częścią serii filmów Od prototypu do produkcji. Zanim rozpoczniesz ten moduł, wykonaj poprzedni. Więcej informacji znajdziesz w powiązanej serii filmów:
.
Czego się dowiesz
Poznasz takie zagadnienia jak:
- Modyfikowanie kodu aplikacji trenującej na potrzeby automatycznego dostrajania hiperparametrów
- Skonfiguruj i uruchom zadanie dostrajania hiperparametrów za pomocą pakietu Vertex AI Python SDK.
Całkowity koszt ukończenia tego modułu w Google Cloud wynosi około 1 USD.
2. Wprowadzenie do Vertex AI
W tym module wykorzystujemy najnowszą ofertę produktów AI dostępną w Google Cloud. Vertex AI integruje usługi ML w Google Cloud, zapewniając płynne środowisko programistyczne. Wcześniej modele wytrenowane za pomocą AutoML i modele niestandardowe były dostępne w ramach osobnych usług. Nowa oferta łączy je w jeden interfejs API wraz z innymi nowymi usługami. Możesz też przeprowadzić migrację istniejących projektów do Vertex AI.
Vertex AI obejmuje wiele różnych usług, które obsługują kompleksowe przepływy pracy związane z uczeniem maszynowym. Ten moduł skupia się na wyróżnionych poniżej usługach: trenowanie i Workbench.

3. Konfigurowanie środowiska
Aby skonfigurować środowisko, wykonaj czynności opisane w module Trenowanie modeli niestandardowych za pomocą Vertex AI.
4. Konteneryzowanie kodu aplikacji trenującej
To zadanie trenowania prześlesz do Vertex AI, umieszczając kod aplikacji do trenowania w kontenerze Dockera i przenosząc ten kontener do Google Artifact Registry. Dzięki temu możesz trenować i dostrajać model utworzony w dowolnej platformie.
Zacznij od otwarcia okna terminala w menu Launchera notatnika Workbench utworzonego w poprzednich ćwiczeniach.

Krok 1. Napisz kod szkoleniowy
Utwórz nowy katalog o nazwie flowers-hptune i przejdź do niego:
mkdir flowers-hptune
cd flowers-hptune
Uruchom to polecenie, aby utworzyć katalog na kod szkoleniowy i plik Pythona, do którego dodasz poniższy kod.
mkdir trainer
touch trainer/task.py
W katalogu flowers-hptune/ powinny się teraz znajdować te pliki:
+ trainer/
+ task.py
Następnie otwórz utworzony plik task.py i skopiuj poniższy kod.
Musisz zastąpić {your-gcs-bucket} w BUCKET_ROOT nazwą zasobnika Cloud Storage, w którym w ćwiczeniu 1 został zapisany zbiór danych o kwiatach.
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()
Zanim utworzysz kontener, przyjrzyjmy się bliżej kodowi. Istnieje kilka komponentów, które są specyficzne dla korzystania z usługi dostrajania hiperparametrów.
- Skrypt importuje bibliotekę
hypertune. - Funkcja
get_args()definiuje argument wiersza poleceń dla każdego hiperparametru, który chcesz dostroić. W tym przykładzie dostrajane hiperparametry to tempo uczenia się, wartość momentum w optymalizatorze i liczba jednostek w ostatniej warstwie ukrytej modelu, ale możesz eksperymentować z innymi. Wartość przekazana w tych argumentach jest następnie używana do ustawienia odpowiedniego hiperparametru w kodzie. - Na końcu funkcji
main()bibliotekahypertunesłuży do zdefiniowania danych, które chcesz zoptymalizować. W TensorFlow metoda kerasmodel.fitzwraca obiektHistory. AtrybutHistory.historyto zapis wartości funkcji straty i wartości danych w kolejnych epokach. Jeśli przekażesz dane weryfikacyjne do atrybutumodel.fit, atrybutHistory.historybędzie zawierać również wartości utraty weryfikacyjnej i wartości wskaźników. Jeśli na przykład wytrenujesz model w 3 epokach z danymi do weryfikacji i podaszaccuracyjako wskaźnik, atrybutHistory.historybędzie wyglądać podobnie do tego słownika.
{
"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
]
Jeśli chcesz, aby usługa dostrajania hiperparametrów odkryła wartości, które maksymalizują dokładność weryfikacji modelu, zdefiniuj dane jako ostatni wpis (lub NUM_EPOCS - 1) na liście val_accuracy. Następnie przekaż te dane do instancji elementu HyperTune. W przypadku parametru hyperparameter_metric_tag możesz wybrać dowolny ciąg znaków, ale musisz go użyć ponownie później, gdy uruchomisz zadanie dostrajania hiperparametrów.
Krok 2. Utwórz plik Dockerfile
Aby umieścić kod w kontenerze, musisz utworzyć plik Dockerfile. W pliku Dockerfile umieścisz wszystkie polecenia potrzebne do uruchomienia obrazu. Zainstaluje wszystkie niezbędne biblioteki i skonfiguruje punkt wejścia dla kodu trenowania.
W terminalu utwórz pusty plik Dockerfile w katalogu głównym flowers-hptune:
touch Dockerfile
W katalogu flowers-hptune/ powinny się teraz znajdować te pliki:
+ Dockerfile
+ trainer/
+ task.py
Otwórz plik Dockerfile i skopiuj do niego poniższy kod. Zauważysz, że jest on niemal identyczny z plikiem Dockerfile używanym w pierwszym laboratorium. Różnica polega na tym, że teraz instalujemy bibliotekę cloudml-hypertune.
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"]
Krok 3. Utwórz kontener
W terminalu uruchom to polecenie, aby zdefiniować zmienną środowiskową dla projektu. Pamiętaj, aby zastąpić your-cloud-project identyfikatorem projektu:
PROJECT_ID='your-cloud-project'
Zdefiniuj repozytorium w Artifact Registry. Użyjemy repozytorium utworzonego w pierwszym module.
REPO_NAME='flower-app'
Zdefiniuj zmienną z identyfikatorem URI obrazu kontenera w Google Artifact Registry:
IMAGE_URI=us-central1-docker.pkg.dev/$PROJECT_ID/$REPO_NAME/flower_image_hptune:latest
Konfigurowanie Dockera
gcloud auth configure-docker \
us-central1-docker.pkg.dev
Następnie utwórz kontener, uruchamiając to polecenie w katalogu głównym flower-hptune:
docker build ./ -t $IMAGE_URI
Na koniec prześlij go do Artifact Registry:
docker push $IMAGE_URI
Po przesłaniu kontenera do Artifact Registry możesz rozpocząć zadanie trenowania.
5. Uruchamianie zadania dostrajania hiperparametrów za pomocą pakietu SDK
W tej sekcji dowiesz się, jak skonfigurować i przesłać zadanie dostrajania hiperparametrów za pomocą interfejsu Vertex Python API.
W menu uruchamiania utwórz notatnik TensorFlow 2.

Zaimportuj pakiet Vertex AI SDK.
from google.cloud import aiplatform
from google.cloud.aiplatform import hyperparameter_tuning as hpt
Aby uruchomić zadanie dostrajania hiperparametrów, musisz najpierw zdefiniować worker_pool_specs, który określa typ maszyny i obraz Dockera. Poniższa specyfikacja określa 1 maszynę z 2 procesorami graficznymi NVIDIA Tesla V100.
W image_uri musisz zastąpić {PROJECT_ID} nazwą swojego projektu.
# 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"
}
}]
Następnie zdefiniuj parameter_spec, czyli słownik określający parametry, które chcesz optymalizować. Kluczem słownika jest ciąg tekstowy przypisany do argumentu wiersza poleceń dla każdego hiperparametru, a wartością słownika jest specyfikacja parametru.
W przypadku każdego hiperparametru musisz określić typ oraz zakres wartości, które będzie testować usługa optymalizacji. Hiperparametry mogą być typu Double, Integer, Categorical lub Discrete. Jeśli wybierzesz typ Double lub Integer, musisz podać wartość minimalną i maksymalną. Jeśli wybierzesz opcję Kategorialne lub Dyskretne, musisz podać wartości. W przypadku typów Double i Integer musisz też podać wartość skalowania. Więcej informacji o tym, jak wybrać najlepszą skalę, znajdziesz w tym filmie.
# 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)
}
Ostatnią specyfikacją do zdefiniowania jest metric_spec, czyli słownik reprezentujący wskaźnik, który ma zostać zoptymalizowany. Kluczem słownika jest hyperparameter_metric_tag ustawiony w kodzie aplikacji do trenowania, a wartością jest cel optymalizacji.
# 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'}
Po zdefiniowaniu specyfikacji utworzysz CustomJob, czyli wspólną specyfikację, która będzie używana do uruchamiania zadania w każdej próbie dostrajania hiperparametrów.
Zastąp {YOUR_BUCKET} utworzonym wcześniej zasobnikiem.
# Replace YOUR_BUCKET
my_custom_job = aiplatform.CustomJob(display_name='flowers-hptune-job',
worker_pool_specs=worker_pool_specs,
staging_bucket='gs://{YOUR_BUCKET}')
Następnie utwórz i uruchom HyperparameterTuningJob.
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()
Warto zwrócić uwagę na kilka argumentów:
- max_trial_count: musisz określić górną granicę liczby prób, które usługa przeprowadzi. Większa liczba prób zwykle pozwala uzyskać lepsze wyniki, ale w pewnym momencie dodatkowe próby przestają przynosić korzyści i mają niewielki lub żaden wpływ na wskaźnik, który próbujesz zoptymalizować. Zalecamy rozpoczęcie od mniejszej liczby prób, aby sprawdzić, jak duże znaczenie mają wybrane hiperparametry, zanim zwiększysz skalę.
- parallel_trial_count: jeśli używasz równoległych prób, usługa udostępnia wiele klastrów przetwarzania treningowego. Zwiększenie liczby równoległych prób skraca czas działania zadania dostrajania hiperparametrów, ale może zmniejszyć ogólną skuteczność zadania. Dzieje się tak, ponieważ domyślna strategia dostrajania wykorzystuje wyniki poprzednich prób do określania wartości w kolejnych próbach.
- search_algorithm: możesz ustawić algorytm wyszukiwania na siatkę, losowy lub domyślny (brak). Opcja domyślna stosuje optymalizację bayesowską do przeszukiwania przestrzeni możliwych wartości hiperparametrów i jest zalecanym algorytmem. Więcej informacji o tym algorytmie znajdziesz tutaj.
W konsoli możesz sprawdzić postęp zadania.

Po zakończeniu testu możesz wyświetlić wyniki każdej wersji próbnej i sprawdzić, który zestaw wartości przyniósł najlepsze rezultaty.

🎉 Gratulacje! 🎉
Dowiedziałeś się, jak używać Vertex AI do:
- Uruchamianie automatycznego zadania dostrajania hiperparametrów
Więcej informacji o różnych częściach Vertex znajdziesz w dokumentacji.
6. Czyszczenie
Skonfigurowaliśmy notebooka tak, aby po 60 minutach bezczynności wyłączał się automatycznie, więc nie musimy się martwić o zamykanie instancji. Jeśli chcesz ręcznie wyłączyć instancję, kliknij przycisk Zatrzymaj w sekcji Vertex AI Workbench w konsoli. Jeśli chcesz całkowicie usunąć notatnik, kliknij przycisk Usuń.

Aby usunąć zasobnik Storage, w menu nawigacyjnym w konsoli Cloud otwórz Storage, wybierz zasobnik i kliknij Usuń:
