Vertex AI: Réglages d'hyperparamètres

1. Aperçu

Dans cet atelier, vous allez utiliser Vertex AI pour exécuter une tâche de réglage d'hyperparamètres pour un modèle TensorFlow. Cet atelier utilise TensorFlow pour le code du modèle, mais les concepts s'appliquent également à d'autres frameworks de ML.

Objectifs

Vous apprendrez à effectuer les tâches suivantes :

  • Modifier le code de l'application d'entraînement pour le réglage automatisé des hyperparamètres
  • Configurer et lancer une tâche de réglage des hyperparamètres depuis l'UI Vertex AI
  • Configurer et lancer une tâche de réglage des hyperparamètres avec le SDK Python Vertex AI

Le coût total d'exécution de cet atelier sur Google Cloud est d'environ 3$ USD.

2. Présentation de Vertex AI

Cet atelier utilise la solution d'IA la plus récente de Google Cloud. Vertex AI intègre toutes les offres de ML de Google Cloud pour créer une expérience de développement fluide. Auparavant, les modèles entraînés avec AutoML et les modèles personnalisés étaient accessibles via des services distincts. La nouvelle offre regroupe ces deux types de modèles en une seule API, ainsi que d'autres nouveaux produits. Vous pouvez également migrer des projets existants vers Vertex AI. Pour envoyer des commentaires, accédez à la page d'assistance.

Vertex AI comprend de nombreux produits différents qui permettent de gérer les workflows de ML de bout en bout. Cet atelier porte sur les produits présentés ci-dessous (Training (Formation) et Workbench).

Présentation des produits Vertex

3. Configurez votre environnement.

Pour exécuter cet atelier de programmation, vous aurez besoin d'un projet Google Cloud Platform dans lequel la facturation sera activée. Pour créer un projet, suivez ces instructions.

Étape 1: Activez l'API Compute Engine

Accédez à Compute Engine et sélectionnez Enable (Activer) si ce n'est pas déjà fait. Vous en aurez besoin pour créer votre instance de notebook.

Étape 2: Activez l'API Container Registry

Accédez à Container Registry et sélectionnez Enable (Activer) si ce n'est pas déjà fait. Cette clé vous permettra de créer un conteneur pour votre tâche d'entraînement personnalisée.

Étape 3: Activez l'API Vertex AI

Accédez à la section Vertex AI de Cloud Console, puis cliquez sur Activer l'API Vertex AI.

Tableau de bord Vertex AI

Étape 4: Créez une instance Vertex AI Workbench

Dans la section Vertex AI de Cloud Console, cliquez sur Workbench:

Menu Vertex AI

Activez l'API Notebooks si elle ne l'est pas encore.

API pour notebooks

Une fois l'option activée, cliquez sur NOTEG Notebooks:

Interface utilisateur de notebook

Sélectionnez ensuite NOUVEAU NOTEBOOK.

new_notebook

Attribuez un nom à votre notebook, puis cliquez sur Advanced Settings (Paramètres avancés).

créer_notebook

Sous "Paramètres avancés", activez l'arrêt en cas d'inactivité et définissez le nombre de minutes sur 60. Cela signifie que votre notebook s'arrête automatiquement lorsqu'il n'est pas utilisé. Vous ne payez donc pas de frais inutiles.

idle_timeout

Sous Sécurité, sélectionnez "Activer le terminal" si elle n'est pas déjà activée.

activer_terminal

Vous pouvez conserver tous les autres paramètres avancés tels quels.

Cliquez ensuite sur Create (Créer). Le provisionnement de l'instance prend quelques minutes.

Une fois l'instance créée, sélectionnez Ouvrir JupyterLab.

open_jupyterlab.

La première fois que vous utilisez une nouvelle instance, vous êtes invité à vous authentifier. Pour ce faire, suivez les étapes indiquées dans l'interface utilisateur.

authentifier

4. Conteneuriser le code de l'application d'entraînement

Le modèle que vous allez entraîner et ajuster dans cet atelier est un modèle de classification d'images entraîné sur l'ensemble de données chevaux ou humains des ensembles de données TensorFlow.

Vous allez envoyer cette tâche de réglage des hyperparamètres à Vertex AI en plaçant le code de votre application d'entraînement dans un conteneur Docker et en le transmettant à Google Container Registry. Cette approche vous permet d'ajuster les hyperparamètres pour un modèle créé avec n'importe quel framework.

Pour commencer, à partir du menu du Lanceur d'applications, ouvrez une fenêtre Terminal dans votre instance de notebook:

Ouvrir le terminal dans le notebook

Créez un répertoire appelé horses_or_humans et ajoutez-y le code de commande suivant:

mkdir horses_or_humans
cd horses_or_humans

Étape 1: Créez un Dockerfile

La première étape pour conteneuriser votre code consiste à créer un Dockerfile. Dans le fichier Dockerfile, vous allez inclure toutes les commandes nécessaires à l'exécution de l'image. Cette commande installe toutes les bibliothèques nécessaires, y compris la bibliothèque CloudML Hypertune, puis configure le point d'entrée du code d'entraînement.

À partir de votre terminal, créez un Dockerfile vide:

touch Dockerfile

Ouvrez le Dockerfile et copiez-y les éléments suivants:

FROM gcr.io/deeplearning-platform-release/tf2-gpu.2-7

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"]

Ce Dockerfile utilise l'image Docker TensorFlow Enterprise 2.7 Deep Learning. Les conteneurs de deep learning sur Google Cloud sont préinstallés sur de nombreux frameworks de ML et de science des données courants. Après avoir téléchargé cette image, ce Dockerfile configure le point d'entrée du code d'entraînement. Vous n'avez pas encore créé ces fichiers. À l'étape suivante, vous ajouterez le code pour entraîner et ajuster le modèle.

Étape 2: Ajoutez le code d'entraînement du modèle

Depuis le terminal, exécutez la commande suivante afin de créer un répertoire pour le code d'entraînement et un fichier Python dans lequel vous ajouterez le code:

mkdir trainer
touch trainer/task.py

Votre répertoire horses_or_humans/ doit maintenant contenir le code suivant:

+ Dockerfile
+ trainer/
    + task.py

Ensuite, ouvrez le fichier task.py que vous venez de créer et copiez le code ci-dessous.

import tensorflow as tf
import tensorflow_datasets as tfds
import argparse
import hypertune

NUM_EPOCHS = 10

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 preprocess_data(image, label):
  '''Resizes and scales images.'''

  image = tf.image.resize(image, (150,150))
  return tf.cast(image, tf.float32) / 255., label

def create_dataset():
  '''Loads Horses Or Humans dataset and preprocesses data.'''

  data, info = tfds.load(name='horses_or_humans', as_supervised=True, with_info=True)

  # Create train dataset
  train_data = data['train'].map(preprocess_data)
  train_data  = train_data.shuffle(1000)
  train_data  = train_data.batch(64)

  # Create validation dataset
  validation_data = data['test'].map(preprocess_data)
  validation_data  = validation_data.batch(64)

  return train_data, validation_data

def create_model(num_units, learning_rate, momentum):
  '''Defines and compiles model.'''

  inputs = tf.keras.Input(shape=(150, 150, 3))
  x = tf.keras.layers.Conv2D(16, (3, 3), activation='relu')(inputs)
  x = tf.keras.layers.MaxPooling2D((2, 2))(x)
  x = tf.keras.layers.Conv2D(32, (3, 3), activation='relu')(x)
  x = tf.keras.layers.MaxPooling2D((2, 2))(x)
  x = tf.keras.layers.Conv2D(64, (3, 3), activation='relu')(x)
  x = tf.keras.layers.MaxPooling2D((2, 2))(x)
  x = tf.keras.layers.Flatten()(x)
  x = tf.keras.layers.Dense(num_units, activation='relu')(x)
  outputs = tf.keras.layers.Dense(1, activation='sigmoid')(x)
  model = tf.keras.Model(inputs, outputs)
  model.compile(
      loss='binary_crossentropy',
      optimizer=tf.keras.optimizers.SGD(learning_rate=learning_rate, momentum=momentum),
      metrics=['accuracy'])
  return model

def main():
  args = get_args()
  train_data, validation_data = create_dataset()
  model = create_model(args.num_units, args.learning_rate, args.momentum)
  history = model.fit(train_data, epochs=NUM_EPOCHS, validation_data=validation_data)

  # 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=NUM_EPOCHS)

if __name__ == "__main__":
    main()

Avant de créer le conteneur, examinons de plus près le code. Certains composants sont spécifiques à l'utilisation du service de réglage des hyperparamètres.

  1. Le script importe la bibliothèque hypertune. Notez que le Dockerfile de l'étape 1 incluait des instructions pour installer pip à l'aide de la commande "pip".
  2. La fonction get_args() définit un argument de ligne de commande pour chaque hyperparamètres que vous souhaitez régler. Dans cet exemple, les hyperparamètres qui seront ajustés sont le taux d'apprentissage, la valeur de la puissance de l'optimiseur et le nombre d'unités dans la dernière couche cachée du modèle, mais n'hésitez pas à effectuer des tests avec d'autres utilisateurs. La valeur transmise dans ces arguments est ensuite utilisée pour définir le point de terminaison correspondant dans le code.
  3. À la fin de la fonction main(), la bibliothèque hypertune permet de définir la métrique que vous souhaitez optimiser. Dans TensorFlow, la méthode model.fit keras renvoie un objet History. L'attribut History.history est un enregistrement des valeurs de perte et d'entraînement pour les époques successives. Si vous transmettez des données de validation à model.fit, l'attribut History.history inclut également les valeurs de perte et de métrique de validation. Par exemple, si vous avez entraîné un modèle pendant trois époques avec des données de validation et fourni accuracy comme métrique, l'attribut History.history ressemblerait au dictionnaire suivant.
{
 "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
 ]

Si vous souhaitez que le service de réglage des hyperparamètres identifie les valeurs qui optimisent la justesse de validation du modèle, vous devez définir la métrique en tant que dernière entrée (ou NUM_EPOCS - 1) de la liste val_accuracy. Transmettez ensuite cette métrique à une instance de HyperTune. Vous pouvez choisir la chaîne de votre choix pour hyperparameter_metric_tag, mais vous devrez l'utiliser de nouveau ultérieurement pour lancer la tâche de réglage des hyperparamètres.

Étape 3: Créez le conteneur

Depuis le terminal, exécutez la commande suivante pour définir une variable d'environnement pour votre projet, en veillant à remplacer your-cloud-project par l'ID de votre projet:

PROJECT_ID='your-cloud-project'

Définissez une variable avec l'URI de votre image de conteneur dans Google Container Registry:

IMAGE_URI="gcr.io/$PROJECT_ID/horse-human:hypertune"

Ensuite, créez le conteneur en exécutant la commande suivante à partir de la racine de votre répertoire horses_or_humans:

docker build ./ -t $IMAGE_URI

Enfin, transférez-le vers Google Container Registry:

docker push $IMAGE_URI

Maintenant que le conteneur est transféré dans Container Registry, vous êtes prêt à lancer une tâche de réglage d'hyperparamètres de modèle personnalisé.

5. Exécuter une tâche de réglage des hyperparamètres sur Vertex AI

Dans cet atelier, vous allez utiliser l'entraînement personnalisé via un conteneur personnalisé sur Google Container Registry, mais vous pouvez également exécuter une tâche de réglage des hyperparamètres avec un conteneur prédéfini Vertex AI.

Pour commencer, accédez à la section Entraînement dans la section "Vertex" de Cloud Console:

Menu uCAIP

Étape 1: Configurez la tâche d'entraînement

Cliquez sur Create (Créer) pour saisir les paramètres de votre réglage de réglage des hyperparamètres.

  • Sous Ensemble de données, sélectionnez Aucun ensemble de données géré.
  • Sélectionnez ensuite Custom training (advanced) (Entraînement personnalisé) comme méthode d'entraînement, puis cliquez sur Continue (Continuer).
  • Saisissez horses-humans-hyptertune (ou le nom que vous souhaitez attribuer à votre modèle) dans le champ Nom du modèle
  • Cliquez sur Continuer.

À l'étape "Paramètres du conteneur", sélectionnez Conteneur personnalisé:

Option de conteneur personnalisé

Dans la première zone (Container image), saisissez la valeur de votre variable IMAGE_URI dans la section précédente. Il devrait s'agir de gcr.io/your-cloud-project/horse-human:hypertune, avec votre propre nom de projet. Laissez les autres champs vides et cliquez sur Continue (Continuer).

Étape 2: Configurez la tâche de réglage des hyperparamètres

Sélectionnez Activer le réglage des hyperparamètres.

Hyperparamètres

Configurer les hyperparamètres

Vous devez ensuite ajouter les hyperparamètres que vous définissez en tant qu'arguments de ligne de commande dans le code de l'application d'entraînement. Lorsque vous ajoutez un hyperparamètre, vous devez indiquer son nom. Il doit correspondre au nom de l'argument que vous avez transmis à argparse.

learning_rate_name (nom du taux d'apprentissage)

Ensuite, sélectionnez le type ainsi que les limites pour les valeurs que le service de réglage essaiera. Si vous sélectionnez le type "Double" ou "Entier", vous devez indiquer des valeurs minimale et maximale. Si vous sélectionnez "Catégorique" ou "Discrete", vous devez indiquer les valeurs.

learning_rate_type [type_de_taux_d'apprentissage]learning_rate_name (nom du taux d'apprentissage)

Pour les types "Double" et "Entier", vous devez également fournir la valeur de scaling.

formation_taux_d'évaluation

Après avoir ajouté l'hyperparamètres learning_rate, ajoutez les paramètres momentum et num_units.

config

Nombre d'éléments configurés

Configurer la métrique

Après avoir ajouté les hyperparamètres, vous devez fournir la métrique que vous souhaitez optimiser, ainsi que l'objectif. Il doit être identique au hyperparameter_metric_tag que vous avez défini dans votre application d'entraînement.

métrique_configuration

Le service de réglage des hyperparamètres Vertex AI exécute plusieurs tests sur votre application d'entraînement avec les valeurs configurées aux étapes précédentes. Vous devez indiquer une limite supérieure pour le nombre d'essais exécutés par le service. Un nombre plus élevé d'essais permet généralement d'obtenir de meilleurs résultats, mais vous constaterez peut-être une baisse au niveau des retours après lesquels des tests supplémentaires n'auront que peu ou pas d'effet sur la métrique que vous essayez d'optimiser. Il est recommandé de commencer par un petit nombre d'essais et de vous faire une idée de l'impact de vos hyperparamètres avant de passer à un grand nombre d'essais.

Vous devez également définir une limite supérieure pour le nombre d'essais parallèles. L'augmentation du nombre de tests parallèles réduit le temps nécessaire à l'exécution de la tâche de réglage des hyperparamètres. Toutefois, cela peut réduire l'efficacité de la tâche dans son ensemble. En effet, la stratégie de réglage par défaut utilise les résultats des essais précédents pour orienter l'attribution des valeurs dans les tests suivants. Si vous exécutez un trop grand nombre d'essais en parallèle, certains d'entre eux commenceront sans bénéficier du résultat associé.

Vous pouvez définir le nombre d'essais sur 15 et le nombre maximal d'essais parallèles sur 3. Vous pouvez tester différents chiffres, mais cela peut prendre plus de temps et des coûts plus élevés.

Test_configuration

La dernière étape consiste à sélectionner "Default" (Algorithme de recherche) comme algorithme de recherche, qui utilisera Google Vizier pour effectuer le réglage bayésien des réglages d'hyperparamètres. Pour en savoir plus sur cet algorithme, cliquez ici.

algorithme_configuration

Cliquez sur Continuer.

Étape 3: Configurez le calcul

Dans Calcul et tarification, laissez la région sélectionnée telle quelle et configurez le pool de nœuds de calcul 0 comme suit.

Machine type

Cliquez sur Start training (Démarrer l'entraînement) pour lancer la tâche de réglage des hyperparamètres. Dans la section "Training" (Entraînement) de l'onglet HYPERPARAMETER TUNING JOBS (Tâches de réglage des paramètres HYPERPARAMETER), vous trouverez le résultat suivant:

Tâches Hyperparam

Une fois l'exécution du test terminée, vous pouvez cliquer sur son nom pour afficher les résultats.

Sortie d'hyperparamètre

🎉 Félicitations ! 🎉

Vous avez appris à utiliser Vertex AI pour:

  • Lancer une tâche de réglage des hyperparamètres pour le code d'entraînement fourni dans un conteneur personnalisé. Dans cet exemple, vous avez utilisé un modèle TensorFlow. Vous pouvez toutefois entraîner un modèle créé avec n'importe quel framework à l'aide de conteneurs personnalisés.

Pour en savoir plus sur les différentes parties de Vertex, consultez la documentation.

6. [Facultatif] Utiliser le SDK Vertex

La section précédente explique comment lancer la tâche de réglage des hyperparamètres via l'UI. Dans cette section, vous allez découvrir un autre moyen d'envoyer une tâche de réglage des hyperparamètres à l'aide de l'API Vertex Python.

À partir du Lanceur d'applications, créez un notebook TensorFlow 2.

new_notebook

Importez le SDK Vertex AI.

from google.cloud import aiplatform
from google.cloud.aiplatform import hyperparameter_tuning as hpt

Pour lancer la tâche de réglage des hyperparamètres, vous devez d'abord définir les spécifications suivantes. Vous devrez remplacer {PROJECT_ID} par image_uri dans votre projet.

# 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": "gcr.io/{PROJECT_ID}/horse-human:hypertune"
    }
}]

# Dictionary representing metrics 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'}

# 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)
}

Ensuite, créez un CustomJob. Vous devez remplacer {YOUR_BUCKET} par un bucket dans votre projet pour la préproduction.

# Replace YOUR_BUCKET
my_custom_job = aiplatform.CustomJob(display_name='horses-humans-sdk-job',
                              worker_pool_specs=worker_pool_specs,
                              staging_bucket='gs://{YOUR_BUCKET}')

Ensuite, créez et exécutez le HyperparameterTuningJob.

hp_job = aiplatform.HyperparameterTuningJob(
    display_name='horses-humans-sdk-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()

7. Nettoyage

Comme nous avons configuré le notebook de sorte qu'il expire au bout de 60 minutes inactives, nous n'avons pas besoin de nous arrêter pour arrêter l'instance. Si vous souhaitez arrêter manuellement l'instance, cliquez sur le bouton "Stop" (Arrêter) dans la section "Vertex AI Workbench" de la console. Si vous souhaitez supprimer entièrement le notebook, cliquez sur le bouton "Supprimer".

Arrêter l'instance

Pour supprimer le bucket de stockage, utilisez le menu de navigation de Cloud Console, accédez à Storage et sélectionnez votre bucket, puis cliquez sur "Delete" (Supprimer) :

Supprimer l'espace de stockage