Passer au contenu principal
Ce guide fournit des recommandations pour intégrer W&B à votre script d’entraînement Python ou à votre notebook afin d’optimiser la recherche d’hyperparamètres.

Script d’entraînement original

Supposons que vous disposiez d’un script Python qui entraîne un modèle (voir ci-dessous). Votre objectif est de trouver les hyperparamètres qui maximisent la précision de validation (val_acc). Dans votre script Python, vous définissez deux fonctions : train_one_epoch et evaluate_one_epoch. La fonction train_one_epoch simule l’entraînement pendant une époque et renvoie la précision et la perte d’entraînement. La fonction evaluate_one_epoch simule l’évaluation du modèle sur le jeu de données de validation et renvoie la précision et la perte de validation. Vous définissez un dictionnaire de configuration (config) qui contient des valeurs d’hyperparamètres telles que le taux d’apprentissage (lr), la taille du lot (batch_size) et le nombre d’époques (epochs). Les valeurs du dictionnaire de configuration contrôlent le processus d’entraînement. Ensuite, vous définissez une fonction appelée main qui reproduit une boucle d’entraînement classique. Pour chaque époque, la précision et la perte sont calculées sur les jeux de données d’entraînement et de validation.
Ce code est un script d’entraînement factice. Il n’entraîne pas de modèle, mais simule le processus d’entraînement en générant des valeurs aléatoires de précision et de perte. L’objectif de ce code est de montrer comment intégrer W&B à votre script d’entraînement.
import random
import numpy as np

def train_one_epoch(epoch, lr, batch_size):
    acc = 0.25 + ((epoch / 30) + (random.random() / 10))
    loss = 0.2 + (1 - ((epoch - 1) / 10 + random.random() / 5))
    return acc, loss

def evaluate_one_epoch(epoch):
    acc = 0.1 + ((epoch / 20) + (random.random() / 10))
    loss = 0.25 + (1 - ((epoch - 1) / 10 + random.random() / 6))
    return acc, loss

# variable de configuration avec les valeurs des hyperparamètres
config = {"lr": 0.0001, "batch_size": 16, "epochs": 5}

def main():
    lr = config["lr"]
    batch_size = config["batch_size"]
    epochs = config["epochs"]

    for epoch in np.arange(1, epochs):
        train_acc, train_loss = train_one_epoch(epoch, lr, batch_size)
        val_acc, val_loss = evaluate_one_epoch(epoch)

        print("epoch: ", epoch)
        print("training accuracy:", train_acc, "training loss:", train_loss)
        print("validation accuracy:", val_acc, "validation loss:", val_loss)

if __name__ == "__main__":
    main()
Dans la section suivante, vous allez ajouter W&B à votre script Python afin de suivre les hyperparamètres et les métriques pendant l’entraînement. Vous allez utiliser W&B pour trouver les meilleurs hyperparamètres afin de maximiser la précision de validation (val_acc).

Ajoutez W&B à votre script d’entraînement

Mettez à jour votre script d’entraînement pour y intégrer W&B. La manière d’intégrer W&B à votre script Python ou notebook dépend de la façon dont vous gérez les Sweeps. Pour utiliser le W&B Python SDK afin de démarrer, d’arrêter et de gérer les Sweeps, suivez les instructions de l’onglet Python script or notebook. Pour utiliser le W&B CLI à la place, suivez les instructions de l’onglet CLI.
Créez un fichier de configuration YAML avec la configuration de votre balayage. Le fichier de configuration contient les hyperparamètres que vous souhaitez que le balayage explore. Dans l’exemple suivant, les hyperparamètres de taille de lot (batch_size), d’époques (epochs) et de taux d’apprentissage (lr) varient à chaque balayage.
# config.yaml
program: train.py
method: random
name: sweep
metric:
  goal: maximize
  name: val_acc
parameters:
  batch_size:
    values: [16, 32, 64]
  lr:
    min: 0.0001
    max: 0.1
  epochs:
    values: [5, 10, 15]
Pour en savoir plus sur la création d’une configuration de balayage W&B, voir Définir la configuration de balayage.Vous devez fournir le nom de votre script Python pour la clé program dans votre fichier YAML.Ensuite, ajoutez les éléments suivants à l’exemple de code :
  1. Importez le SDK Python de W&B (wandb) et PyYAML (yaml). PyYAML sert à lire notre fichier de configuration YAML.
  2. Lisez le fichier de configuration.
  3. Utilisez wandb.init() pour démarrer un processus en arrière-plan afin de synchroniser et journaliser les données en tant que W&B Run. Transmettez l’objet de configuration au paramètre config.
  4. Définissez les valeurs des hyperparamètres à partir de wandb.Run.config au lieu d’utiliser des valeurs codées en dur.
  5. Journalisez la métrique que vous souhaitez optimiser avec wandb.Run.log(). Vous devez journaliser la métrique définie dans votre configuration. Dans le dictionnaire de configuration (sweep_configuration dans cet exemple), vous définissez le balayage pour maximiser la valeur val_acc.
import wandb
import yaml
import random
import numpy as np


def train_one_epoch(epoch, lr, batch_size):
    acc = 0.25 + ((epoch / 30) + (random.random() / 10))
    loss = 0.2 + (1 - ((epoch - 1) / 10 + random.random() / 5))
    return acc, loss


def evaluate_one_epoch(epoch):
    acc = 0.1 + ((epoch / 20) + (random.random() / 10))
    loss = 0.25 + (1 - ((epoch - 1) / 10 + random.random() / 6))
    return acc, loss


def main():
    # Configurez vos hyperparamètres par défaut
    with open("./config.yaml") as file:
        config = yaml.load(file, Loader=yaml.FullLoader)

    with wandb.init(config=config) as run:
        for epoch in np.arange(1, run.config['epochs']):
            train_acc, train_loss = train_one_epoch(epoch, run.config['lr'], run.config['batch_size'])
            val_acc, val_loss = evaluate_one_epoch(epoch)
            run.log(
                {
                    "epoch": epoch,
                    "train_acc": train_acc,
                    "train_loss": train_loss,
                    "val_acc": val_acc,
                    "val_loss": val_loss,
                }
            )

# Appeler la fonction principale.
main()
Dans votre CLI, définissez le nombre maximal de runs que l’agent de balayage doit essayer. C’est facultatif. Dans cet exemple, nous fixons ce nombre maximal à 5.
NUM=5
Ensuite, initialisez le balayage avec la commande wandb sweep. Indiquez le nom du fichier YAML. Vous pouvez aussi indiquer le nom du projet avec l’option de projet (--project) :
wandb sweep --project sweep-demo-cli config.yaml
Cela renvoie un ID de balayage. Pour en savoir plus sur l’initialisation des balayages, voir Initialiser les balayages.Copiez l’ID de balayage et remplacez sweepID dans l’extrait de code suivant pour démarrer le job de balayage avec la commande wandb agent :
wandb agent --count $NUM your-entity/sweep-demo-cli/sweepID
Pour plus d’informations, voir Lancer des jobs de balayage.
Journalisation des métriques dans W&B lors d’un balayageVous devez journaliser la métrique que vous définissez et que vous optimisez, à la fois dans votre configuration de balayage et avec wandb.Run.log(). Par exemple, si vous définissez val_acc comme métrique à optimiser dans votre configuration de balayage, vous devez également journaliser val_acc dans W&B. Si vous ne journalisez pas cette métrique, W&B ne saura pas quoi optimiser.
with wandb.init() as run:
    val_loss, val_acc = train()
    run.log(
        {
            "val_loss": val_loss,
            "val_acc": val_acc
            }
        )
L’exemple suivant montre une journalisation incorrecte de la métrique dans W&B. La métrique optimisée dans la configuration de balayage est val_acc, mais le code journalise val_acc dans un dictionnaire imbriqué sous la clé validation. Vous devez journaliser la métrique directement, et non dans un dictionnaire imbriqué.
with wandb.init() as run:
    val_loss, val_acc = train()
    run.log(
        {
            "validation": {
                "val_loss": val_loss, 
                "val_acc": val_acc
                }
            }
        )