Entraîner RetinaNet sur Cloud TPU (TF 2.x)

Ce document décrit une mise en œuvre du modèle de détection d'objets RetinaNet. Le code est disponible sur GitHub.

Les instructions ci-dessous supposent que vous savez comment exécuter un modèle sur Cloud TPU. Si vous débutez avec Cloud TPU, consultez le guide de démarrage rapide pour en savoir plus.

Si vous prévoyez d'effectuer l'entraînement sur une tranche de pod TPU, consultez la section Entraîner sur des pods TPU pour comprendre les modifications de paramètres requises pour les tranches de pods.

Objectifs

  • Créer un bucket Cloud Storage pour stocker votre ensemble de données et la sortie du modèle
  • Préparer l'ensemble de données COCO
  • Configurer une VM Compute Engine et un nœud Cloud TPU pour l'entraînement et l'évaluation
  • Exécuter les tâches d'entraînement et d'évaluation sur un seul Cloud TPU ou sur un pod Cloud TPU

Coûts

Ce tutoriel utilise des composants facturables de Google Cloud, dont :

  • Instance
  • Cloud TPU
  • Cloud Storage

Obtenez une estimation des coûts en fonction de votre utilisation prévue à l'aide du simulateur de coût. Les nouveaux utilisateurs de Google Cloud peuvent bénéficier d'un essai gratuit.

Avant de commencer

Cette section fournit des informations sur la configuration du bucket Cloud Storage et d'une VM Compute Engine.

  1. Ouvrez une fenêtre Cloud Shell.

    Ouvrir Cloud Shell

  2. Créez une variable pour l'ID de votre projet.

    export PROJECT_ID=project-id
    
  3. Configurez l'outil de ligne de commande gcloud pour utiliser le projet dans lequel vous souhaitez créer Cloud TPU.

    gcloud config set project ${PROJECT_ID}
    
  4. Créez un compte de service pour le projet Cloud TPU.

    gcloud beta services identity create --service tpu.googleapis.com --project $PROJECT_ID
    

    La commande renvoie un compte de service Cloud TPU au format suivant :

    service-PROJECT_NUMBER@cloud-tpu.iam.gserviceaccount.com
    

  5. Créez un bucket Cloud Storage à l'aide de la commande suivante :

    gsutil mb -p ${PROJECT_ID} -c standard -l europe-west4 -b on gs://bucket-name
    

    Ce bucket Cloud Storage stocke les données que vous utilisez pour entraîner votre modèle, ainsi que les résultats de l'entraînement. L'outil ctpu up utilisé dans ce tutoriel définit les autorisations par défaut pour le compte de service Cloud TPU que vous avez configuré à l'étape précédente. Si vous souhaitez utiliser des autorisations plus précises, vérifiez les autorisations de niveau d'accès.

  6. Lancez une VM Compute Engine à l'aide de la commande ctpu up.

    $ ctpu up --vm-only \
    --name=retinanet-tutorial \
    --disk-size-gb=300 \
    --machine-type=n1-standard-8 \
    --zone=europe-west4-a \
    --tf-version=2.3.1
    

    Description des options de commande

    vm-only
    Crée la VM sans créer de Cloud TPU. Par défaut, la commande ctpu up crée une VM et un Cloud TPU.
    name
    Nom du Cloud TPU à créer.
    disk-size-gb
    Taille du disque dur en Go de la VM créée par la commande ctpu up.
    machine-type
    Type de machine de la VM Compute Engine à créer.
    zone
    Zone dans laquelle vous prévoyez de créer votre Cloud TPU.
    tf-version
    La version de Tensorflow que ctpu installe sur la VM.

    Pour plus d'informations sur l'utilitaire CTPU, consultez la section Référence CTPU.

  7. Lorsque vous y êtes invité, appuyez sur y pour créer vos ressources Cloud TPU.

    .

    Une fois la commande ctpu up terminée, vérifiez que l'invite de l'interface système est passée de username@projectname à username@vm-name. Cette modification indique que vous êtes maintenant connecté à votre VM Compute Engine.

    gcloud compute ssh retinanet-tutorial --zone=europe-west4-a
    

    À mesure que vous appliquez ces instructions, exécutez chaque commande commençant par (vm)$ dans votre instance Compute Engine.

  8. Installer les packages supplémentaires

    L'application d'apprentissage RetinaNet nécessite plusieurs packages supplémentaires. Installez-les maintenant :

    (vm)$ sudo apt-get install -y python3-tk
    (vm)$ pip3 install --user Cython matplotlib opencv-python-headless pyyaml Pillow
    
    (vm)$ pip3 install --user 'git+https://github.com/cocodataset/cocoapi#egg=pycocotools&subdirectory=PythonAPI'
    
    (vm)$ sudo pip3 install --user -r /usr/share/models/official/requirements.txt
    

Préparer l'ensemble de données COCO

L'ensemble de données COCO sera stocké sur Cloud Storage. Par conséquent, définissez une variable de bucket de stockage spécifiant le nom du bucket que vous avez créé :

(vm)$ export STORAGE_BUCKET=gs://bucket-name
(vm)$ export DATA_DIR=${STORAGE_BUCKET}/coco

Exécutez le script download_and_preprocess_coco.sh pour convertir l'ensemble de données COCO en fichiers TFRecord (*.tfrecord), ce qui correspond au format attendu par l'application d'entraînement.

(vm)$ sudo bash /usr/share/tpu/tools/datasets/download_and_preprocess_coco.sh ./data/dir/coco

Cela installe les bibliothèques requises et exécute le script de prétraitement. Il génère un certain nombre de fichiers *.tfrecord dans votre répertoire de données local. L'exécution du script de téléchargement et de conversion COCO prend environ une heure.

Copier les données dans votre bucket Cloud Storage

Après avoir converti les données en TFRecord, copiez-les depuis le stockage local vers votre bucket Cloud Storage à l'aide de la commande gsutil. Vous devez également copier les fichiers d'annotation. Ces fichiers vous aident à valider les performances du modèle.

(vm)$ gsutil -m cp ./data/dir/coco/*.tfrecord ${DATA_DIR}
(vm)$ gsutil cp ./data/dir/coco/raw-data/annotations/*.json ${DATA_DIR}

Configurer l'environnement d'entraînement

  1. Créez une ressource Cloud TPU à l'aide de la commande ctpu up.

    (vm)$ ctpu up --tpu-only \
      --tpu-size=v3-8 \
      --zone=europe-west4-a \
      --name=retinanet-tutorial \
      --tf-version=2.3.1
    

    Pour plus d'informations sur l'utilitaire CTPU, consultez la section Référence CTPU.

    Description des options de commande

    tpu-only
    Crée un Cloud TPU uniquement. Par défaut, la commande ctpu up crée une VM et un Cloud TPU.
    tpu-size
    Le type de Cloud TPU à créer.
    zone
    Zone dans laquelle vous prévoyez de créer votre Cloud TPU.
    name
    Nom de la ressource Cloud TPU à créer.
    tf-version
    La version de Tensorflow que ctpu installe sur la VM.
    Réglage Description

    Pour plus d'informations sur l'utilitaire CTPU, consultez la section Référence CTPU.

  2. Lorsque vous y êtes invité, appuyez sur y pour créer vos ressources Cloud TPU.

    .

    Une fois la commande ctpu up terminée, vérifiez que l'invite de l'interface système est passée de username@projectname à username@vm-name. Cette modification indique que vous êtes maintenant connecté à votre VM Compute Engine.

    gcloud compute ssh retinanet-tutorial --zone=europe-west4-a
    

    À mesure que vous appliquez ces instructions, exécutez chaque commande commençant par (vm)$ dans votre instance Compute Engine.

  3. Créez une variable d'environnement pour le nom du TPU.

    (vm)$ export TPU_NAME=retinanet-tutorial
    
  4. Ajoutez le dossier racine /models au chemin Python à l'aide de la commande suivante :

    (vm)$ export PYTHONPATH="${PYTHONPATH}:/usr/share/models"
    

Entraînement sur un seul appareil Cloud TPU

Les scripts d'entraînement suivants ont été exécutés sur un Cloud TPU v3-8. Vous pouvez également les exécuter sur un Cloud TPU v2-8, mais cela prendra plus de temps.

L'exemple de script ci-dessous est entraîné pendant 10 étapes et dure moins de 5 minutes sur un nœud TPU v3-8. L'entraînement à la convergence nécessite environ 22 500 étapes et une heure et demie sur un TPU v3-8.

  1. Configurez les variables d'environnement suivantes :

    (vm)$ export MODEL_DIR=${STORAGE_BUCKET}/retinanet-train
    (vm)$ export RESNET_CHECKPOINT=gs://cloud-tpu-checkpoints/retinanet/resnet50-checkpoint-2018-02-07
    (vm)$ export TRAIN_FILE_PATTERN=${DATA_DIR}/train-*
    (vm)$ export EVAL_FILE_PATTERN=${DATA_DIR}/val-*
    (vm)$ export VAL_JSON_FILE=${DATA_DIR}/instances_val2017.json
    
  2. Exécutez le script d'entraînement :

    (vm)$ python3 /usr/share/models/official/vision/detection/main.py \
         --strategy_type=tpu \
         --tpu=${TPU_NAME} \
         --model_dir=${MODEL_DIR} \
         --mode="train" \
         --params_override="{ type: retinanet, train: { total_steps: 10, checkpoint: { path: ${RESNET_CHECKPOINT}, prefix: resnet50/ }, train_file_pattern: ${TRAIN_FILE_PATTERN} }, eval: { val_json_file: ${VAL_JSON_FILE}, eval_file_pattern: ${EVAL_FILE_PATTERN}, eval_samples: 5000 } }"
    

    Description des options de commande

    strategy_type
    Pour entraîner le modèle RetinaNet sur un TPU, vous devez définir distribution_strategy sur tpu.
    tpu
    Nom du Cloud TPU. Cette valeur est définie à l'aide de la variable d'environnement TPU_NAME.
    model_dir
    Répertoire dans lequel sont stockés les points de contrôle et les résumés lors de l'entraînement du modèle. Si ce dossier n'existe pas, le programme va le créer. Lorsque vous utilisez Cloud TPU, le chemin model_dir doit être un chemin Cloud Storage (gs://...). Vous pouvez réutiliser un dossier existant pour charger les données de point de contrôle actuelles et pour stocker des points de contrôle supplémentaires si les points de contrôle précédents ont été créés avec un Cloud TPU de la même taille et la même version de TensorFlow.
    mode
    Définissez ce paramètre sur train pour entraîner le modèle ou sur eval pour l'évaluer.
    params_override
    Chaîne JSON qui remplace les paramètres de script par défaut. Pour en savoir plus sur les paramètres de script, consultez /usr/share/models/official/vision/detection/main.py.

Pendant l'entraînement du modèle, vous pouvez suivre la progression en affichant la sortie du journal. Une sortie semblable à celle-ci signifie que l'entraînement se déroule normalement :

31517803669, 'learning_rate': 0.08, 'box_loss': 0.0006472870009019971,
'l2_regularization_loss': 0.09328179806470871}
I0210 21:59:19.888985 139927795508992 distributed_executor.py:49]
Saving model as TF checkpoint: gs://bucket-eu/retinanet-model/ctl_step_2500.ckpt-5
I0210 22:01:07.714749 139927795508992 distributed_executor.py:446]
Train Step: 3000/22500  / loss = {'model_loss': 0.08362223953008652,
'total_loss': 0.17120523750782013, 'cls_loss': 0.057121846824884415,
'learning_rate': 0.08, 'box_loss': 0.0005300078773871064,
'l2_regularization_loss': 0.08758299797773361} / training metric =
{'model_loss': 0.08362223953008652, 'total_loss': 0.17120523750782013, 'cls_loss': 0.0
57121846824884415, 'learning_rate': 0.08, 'box_loss': 0.0005300078773871064,
'l2_regularization_loss': 0.08758299797773361}
I0210 22:01:15.813422 139927795508992 distributed_executor.py:49]
Saving model as TF checkpoint: gs://bucket-eu/retinanet-model/ctl_step_3000.ckpt-6

Évaluation sur un seul appareil Cloud TPU

La procédure suivante utilise les données d'évaluation COCO. L'exécution des pas d'évaluation prend environ 10 minutes.

  1. Configurez les variables d'environnement suivantes :

    (vm)$ export EVAL_SAMPLES=5000
    
  2. Exécutez le script d'évaluation :

    (vm)$ python3 /usr/share/models/official/vision/detection/main.py \
          --strategy_type=tpu \
          --tpu=${TPU_NAME} \
          --model_dir=${MODEL_DIR} \
          --mode="eval" \
          --params_override="{ type: retinanet, eval: { val_json_file: ${VAL_JSON_FILE}, eval_file_pattern: ${EVAL_FILE_PATTERN}, eval_samples: ${EVAL_SAMPLES} } }"
    

    Description des options de commande

    strategy_type
    Pour entraîner le modèle RetinaNet sur un TPU, vous devez définir distribution_strategy sur tpu.
    tpu
    Nom du Cloud TPU. Cette valeur est définie à l'aide de la variable d'environnement TPU_NAME.
    model_dir
    Répertoire dans lequel sont stockés les points de contrôle et les résumés lors de l'entraînement du modèle. Si ce dossier n'existe pas, le programme va le créer. Lorsque vous utilisez Cloud TPU, le chemin model_dir doit être un chemin d'accès Cloud Storage (gs://...). Vous pouvez réutiliser un dossier existant pour charger les données de point de contrôle actuelles et stocker des points de contrôle supplémentaires si les points de contrôle précédents ont été créés à l'aide d'un Cloud TPU de la même taille et la même version de TensorFlow.
    mode
    Définissez model sur eval pour évaluer le modèle.
    params_override
    Chaîne JSON qui remplace les paramètres de script par défaut. Pour en savoir plus sur les paramètres de script, consultez /usr/share/models/official/vision/detection/main.py.

    À la fin de l'évaluation, vous verrez dans la console des messages semblables à ce qui suit :

    Accumulating evaluation results...
    DONE (t=7.66s).
     Average Precision  (AP) @[ IoU=0.50:0.95 | area=   all | maxDets=100 ] = 0.000
     Average Precision  (AP) @[ IoU=0.50      | area=   all | maxDets=100 ] = 0.000
     Average Precision  (AP) @[ IoU=0.75      | area=   all | maxDets=100 ] = 0.000
     Average Precision  (AP) @[ IoU=0.50:0.95 | area= small | maxDets=100 ] = 0.000
     Average Precision  (AP) @[ IoU=0.50:0.95 | area=medium | maxDets=100 ] = 0.000
     Average Precision  (AP) @[ IoU=0.50:0.95 | area= large | maxDets=100 ] = 0.000
     Average Recall     (AR) @[ IoU=0.50:0.95 | area=   all | maxDets=  1 ] = 0.000
     Average Recall     (AR) @[ IoU=0.50:0.95 | area=   all | maxDets= 10 ] = 0.000
     Average Recall     (AR) @[ IoU=0.50:0.95 | area=   all | maxDets=100 ] = 0.000
     Average Recall     (AR) @[ IoU=0.50:0.95 | area= small | maxDets=100 ] = 0.000
     Average Recall     (AR) @[ IoU=0.50:0.95 | area=medium | maxDets=100 ] = 0.000
     Average Recall     (AR) @[ IoU=0.50:0.95 | area= large | maxDets=100 ] = 0.000
    

    Vous pouvez maintenant terminer ce tutoriel et nettoyer vos ressources GCP. Vous pouvez également choisir d'explorer plus avant l'exécution du modèle dans un pod Cloud TPU.

Mise à l'échelle de votre modèle avec les pods Cloud TPU

Vous pouvez obtenir des résultats plus rapidement en adaptant votre modèle aux pods Cloud TPU. Le modèle entièrement compatible RetinaNet peut fonctionner avec les tranches de pod v2-32 :

.
  1. Supprimez la ressource Cloud TPU que vous avez créée pour entraîner le modèle sur un seul appareil.

    (vm)$ ctpu delete --tpu-only --zone=europe-west4-a --name=retinanet-tutorial
  2. Exécutez la commande ctpu up à l'aide du paramètre tpu-size pour spécifier la tranche de pod que vous souhaitez utiliser. Par exemple, la commande suivante utilise une tranche de pod v2-32.

    (vm)$ ctpu up --tpu-only \
    --tpu-size=v2-32  \
    --zone=europe-west4-a \
    --name=retinanet-tutorial \
    --tf-version=2.3.1

    Description des options de commande

    tpu-only
    Crée uniquement le Cloud TPU. Par défaut, la commande ctpu up crée à la fois une VM et un Cloud TPU.
    tpu-size
    Type du Cloud TPU à créer.
    zone
    Zone dans laquelle vous prévoyez de créer votre Cloud TPU.
    name
    Nom de la ressource Cloud TPU à créer.
    tf-version
    La version de Tensorflow que ctpu installe sur la VM.

    Pour plus d'informations sur l'utilitaire CTPU, consultez la section Référence CTPU.

  3. Définissez la variable de nom Cloud TPU. Il s'agit du nom que vous avez spécifié avec le paramètre --name ou du nom d'utilisateur par défaut :

    (vm)$ export TPU_NAME=retinanet-tutorial
    
  4. Configurez la variable d'environnement suivante :

    (vm)$ export MODEL_DIR=${STORAGE_BUCKET}/retinanet-pod
    
  5. Exécutez le script d'entraînement de pod sur un nœud TPU v3-32 :

    L'exemple de script d'entraînement suivant a été exécuté sur un pod Cloud TPU v2-32. Il s'exécute en 10 étapes seulement et dure moins de 5 minutes. Pour effectuer un entraînement à la conversion, vous devez disposer de 2 100 étapes et d'environ 50 minutes sur un pod TPU v2-32.

    (vm)$  python3 /usr/share/models/official/vision/detection/main.py \
        --strategy_type=tpu \
        --tpu=${TPU_NAME} \
        --model_dir=${MODEL_DIR} \
        --mode="train" \
        --params_override="{ type: retinanet, train: { total_steps: 10, batch_size: 256, checkpoint: { path: ${RESNET_CHECKPOINT}, prefix: resnet50/ }, train_file_pattern: ${TRAIN_FILE_PATTERN} }, eval: { val_json_file: ${VAL_JSON_FILE}, eval_file_pattern: ${EVAL_FILE_PATTERN}, eval_samples: 5000 } }"
    

    Description des options de commande

    tpu
    Spécifie le nom du Cloud TPU. Cette valeur est définie à l'aide de la variable d'environnement TPU_NAME.
    model_dir
    Spécifie le répertoire dans lequel les points de contrôle et les résumés sont stockés lors de l'entraînement du modèle. Si ce dossier n'existe pas, le programme va le créer. Lorsque vous utilisez Cloud TPU, le chemin model_dir doit être un chemin d'accès Cloud Storage (gs://...). Vous pouvez réutiliser un dossier existant pour charger les données de point de contrôle actuelles et stocker des points de contrôle supplémentaires si les points de contrôle précédents ont été créés à l'aide d'un Cloud TPU de la même taille et la même version de TensorFlow.

Nettoyer

Pour éviter que les ressources utilisées dans ce tutoriel soient facturées sur votre compte Google Cloud Platform :

  1. Déconnectez-vous de la VM Compute Engine :

    (vm)$ exit
    

    Votre invite devrait maintenant être username@projectname, indiquant que vous êtes dans Cloud Shell.

  2. Dans votre VM ou Cloud Shell, utilisez la commande suivante pour supprimer votre VM et Cloud TPU :

    $ ctpu delete --name=retinanet-tutorial \
      --zone=europe-west4-a
    
  3. Exécutez ctpu status en spécifiant votre zone pour vérifier qu'il ne vous reste aucune instance allouée, afin d'éviter des frais inutiles liés à l'utilisation des ressources TPU. La suppression peut prendre plusieurs minutes. Si vous n'avez plus d'instances allouées, une réponse de ce type s'affiche :

    $ ctpu status --name=retinanet-tutorial \
      --zone=europe-west4-a
    
    2018/04/28 16:16:23 WARNING: Setting zone to "europe-west4-a"
    No instances currently exist.
        Compute Engine VM:     --
        Cloud TPU:             --
    
  4. Exécutez gsutil comme indiqué, en remplaçant bucket-name par le nom du bucket Cloud Storage que vous avez créé pour ce tutoriel :

    $ gsutil rm -r gs://bucket-name
    

Étape suivante

Dans ce tutoriel, vous avez entraîné le modèle RetinaNet à l'aide d'un exemple d'ensemble de données. Les résultats de cet entraînement ne sont pas utilisables pour l'inférence dans la plupart des cas. Afin d'utiliser un modèle pour l'inférence, vous pouvez entraîner les données sur un ensemble de données accessible au public ou sur votre propre ensemble de données. Les modèles entraînés sur des appareils Cloud TPU nécessitent des ensembles de données au format TFRecord.

Vous pouvez utiliser l'exemple d'outil de conversion d'ensemble de données pour convertir un ensemble de données de classification d'images au format TFRecord. Si vous n'utilisez pas de modèle de classification d'images, vous devez convertir vous-même votre ensemble de données au format TFRecord. Pour en savoir plus, consultez la section TFRecord et tf.Example.

Réglages d'hyperparamètres

Pour améliorer les performances du modèle avec votre ensemble de données, vous pouvez régler ses hyperparamètres. Vous trouverez des informations sur les hyperparamètres communs à tous les modèles compatibles avec des TPU sur GitHub. Des informations sur les hyperparamètres spécifiques au modèle sont disponibles dans le code source de chaque modèle. Pour en savoir plus sur ces réglages, consultez les pages Présentation des réglages d'hyperparamètres, Utiliser le service de réglage d'hyperparamètres et Régler les hyperparamètres.

Inférence

Une fois que vous avez entraîné votre modèle, vous pouvez l'utiliser pour l'inférence (également appelée prédiction). AI Platform est une solution basée sur le cloud permettant de développer, d'entraîner et de déployer des modèles de machine learning. Une fois un modèle déployé, vous pouvez utiliser le service AI Platform Prediction.

Entraînez le modèle à l'aide d'autres tailles d'images

Vous pouvez essayer d'utiliser un réseau backbone plus étendu (par exemple, ResNet-101 au lieu de ResNet-50). Une image d'entrée plus grande et un réseau backbone plus puissant permettent d'obtenir un modèle plus lent, mais plus précis.

Utilisez une base différente

Vous pouvez pré-entraîner un modèle ResNet à l'aide de votre propre ensemble de données et l'utiliser comme base pour votre modèle RetinaNet. Vous pouvez également exploiter un autre réseau backbone que ResNet, ce qui requiert quelques étapes de configuration supplémentaires. Enfin, si vous souhaitez mettre en œuvre vos propres modèles de détection d'objets, ce réseau peut constituer une bonne base pour vos tests.