Como treinar o RetinaNet no Cloud TPU

Neste documento, descrevemos uma implementação do modelo de detecção de objetos do RetinaNet. O código está disponível no GitHub (em inglês).

As instruções abaixo supõem que você tem familiaridade com a execução de um modelo no Cloud TPU. Se você conhece o Cloud TPU há pouco tempo, consulte o guia de início rápido para conhecer os conceitos básicos.

Antes de começar

Antes de começar o tutorial, verifique se o projeto do Google Cloud Platform foi configurado corretamente.

  1. Faça login na sua Conta do Google.

    Se você ainda não tiver uma, inscreva-se.

  2. Selecione ou crie um projeto do Google Cloud Platform.

    Acessar a página Gerenciar recursos

  3. Verifique se o faturamento foi ativado no projeto do Google Cloud Platform.

    Saiba como ativar o faturamento

  4. Verifique se você tem cota suficiente para usar dispositivos TPU ou Pods.

Como configurar os recursos

Nesta seção, você verá como configurar os recursos de armazenamento, a VM e o Cloud TPU do Cloud Storage para tutoriais.

Crie um intervalo do Cloud Storage

É preciso um intervalo do Cloud Storage para armazenar os dados usados para treinar o modelo e os resultados do treinamento. A ferramenta ctpu up usada neste tutorial configura permissões padrão para a conta de serviço do Cloud TPU. Caso queira permissões mais específicas, consulte as permissões de nível de acesso.

O intervalo criado precisa residir na mesma região que a máquina virtual (VM, na sigla em inglês) e o dispositivo Cloud TPU ou fração do Cloud TPU (vários dispositivos TPU).

  1. Acesse a página do Cloud Storage no Console do GCP.

    Acessar a página do Cloud Storage

  2. Crie um novo intervalo especificando as opções a seguir:

    • Um nome exclusivo à sua escolha
    • classe de armazenamento padrão: Regional
    • localização: se quiser usar um dispositivo Cloud TPU, aceite o padrão apresentado. Caso queira usar uma fatia do pod do Cloud TPU, especifique uma região em que eles estão disponíveis.

Use a ferramenta ctpu

Nesta seção, mostramos o uso da ferramenta de provisionamento do Cloud TPU (ctpu) para criar e gerenciar recursos do projeto no Cloud TPU. Os recursos são compostos por uma máquina virtual (VM, na sigla em inglês) e um recurso do Cloud TPU com o mesmo nome. Eles precisam residir na mesma região/zona que o intervalo recém-criado.

Também é possível configurar os recursos de VM e TPU usando comandos do gcloud ou o Console do Cloud. Para mais informações, consulte Como gerenciar recursos de VM e TPU.

Execute o ctpu up para criar recursos

  1. Abra uma janela do Cloud Shell.

    Abrir o Cloud Shell

  2. Execute gcloud config set project <Your-Project> para usar o projeto em que você quer criar o Cloud TPU.

  3. Execute ctpu up especificando as sinalizações mostradas para um dispositivo Cloud TPU ou para uma fração de pod. Para opções e descrições do sinalizador, consulte Referência do CTPU.

  4. Configure um dispositivo Cloud TPU ou uma fração de pod:

Dispositivo TPU

Configure um dispositivo Cloud TPU:

$ ctpu up --tpu-size=v3-8 --machine-type n1-standard-8

A seguinte mensagem de configuração será exibida:

ctpu will use the following configuration:

Name: [your TPU's name]
Zone: [your project's zone]
GCP Project: [your project's name]
TensorFlow Version: 1.14
VM:
  Machine Type: [your machine type]
  Disk Size: [your disk size]
  Preemptible: [true or false]
Cloud TPU:
  Size: [your TPU size]
  Preemptible: [true or false]

OK to create your Cloud TPU resources with the above configuration? [Yn]:

Pressione y para criar os recursos do Cloud TPU.

Pod do TPU

Configure uma fatia do Cloud TPU na VM e na zona em que você está trabalhando:

$ ctpu up --tpu-size=v3-32 --machine-type n1-standard-8

A seguinte mensagem de configuração será exibida:

ctpu will use the following configuration:

Name: [your TPU's name]
Zone: [your project's zone]
GCP Project: [your project's name]
TensorFlow Version: 1.14
VM:
  Machine Type: [your machine type]
  Disk Size: [your disk size]
  Preemptible: [true or false]
Cloud TPU:
  Size: [your TPU size]
  Preemptible: [true or false]

OK to create your Cloud TPU resources with the above configuration? [Yn]:

Pressione y para criar os recursos do Cloud TPU.

O comando ctpu up cria uma máquina virtual (VM, na sigla em inglês) e serviços do Cloud TPU.

Daqui em diante, o prefixo (vm)$ significa que você precisa executar o comando na instância de VM do Compute Engine.

Verifique a VM do Compute Engine

Quando o comando ctpu up for concluído, verifique se o prompt do shell é username@tpuname, o que mostra que você está conectado à VM do Compute Engine.

Verificar o modelo do RetinaNet

Quando o comando ctpu inicia uma máquina virtual (VM) do Compute Engine, ele coloca automaticamente os arquivos do modelo RetinaNet do branch TensorFlow (em inglês) no seguinte local:

(vm)$ ls /usr/share/tpu/models/official/detection/

Preparar o conjunto de dados COCO

Antes de poder treinar o modelo, é necessário preparar os dados de treinamento. O modelo do RetinaNet foi configurado para ser treinado no conjunto de dados COCO.

Configure a variável de ambiente a seguir, substituindo YOUR-BUCKET-NAME pelo nome do intervalo do Cloud Storage:

(vm)$ export STORAGE_BUCKET=gs://YOUR-BUCKET-NAME

Execute o script download_and_preprocess_coco.sh para converter o conjunto de dados COCO em um grupo de TFRecords (*.tfrecord), que é esperado pelo aplicativo de treinamento.

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

Isso instala as bibliotecas necessárias e executa o script de pré-processamento. A saída são alguns arquivos *.tfrecord no diretório de dados. O script de download e conversão do COCO leva aproximadamente 1 hora para ser concluído.

É necessário copiar esses arquivos para o Cloud Storage para que eles possam ser acessados pelo modelo para treinamento. Use gsutil para copiar os arquivos do diretório local de dados para seu intervalo de armazenamento. Você também precisa salvar os arquivos de anotação, que validam o desempenho do modelo.

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

Instalar pacotes extras

O aplicativo de treinamento do RetinaNet requer vários pacotes extras. Instale-os agora:

(vm)$ sudo apt-get install -y python-tk
(vm)$ pip install Cython matplotlib opencv-python-headless pyyaml Pillow
(vm)$ pip install 'git+https://github.com/cocodataset/cocoapi#egg=pycocotools&subdirectory=PythonAPI'

Atualizar os valores keepalive da conexão da VM

Para este tutorial, é necessária uma conexão de longa duração com a instância do Compute Engine. Para garantir que a instância não seja desconectada, execute o seguinte comando:

(vm)$ sudo /sbin/sysctl \
       -w net.ipv4.tcp_keepalive_time=60 \
       net.ipv4.tcp_keepalive_intvl=60 \
       net.ipv4.tcp_keepalive_probes=5

Definir o caminho para o diretório de modelos

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

Executar o modelo

Nesta seção, descrevemos cinco maneiras de executar o modelo RetinaNet. Elas são executadas no TensorFlow 1.13 ou no TensorFlow 1.14:

  • apenas treinamento (um único dispositivo de TPU)
  • apenas avaliação (um único dispositivo de TPU)
  • alternância entre treinamento e avaliação (um único dispositivo de TPU)
  • exportação de um modelo para inferência (um único dispositivo de TPU)
  • treinamento em um pod do Cloud TPU

Treinamento e avaliação em uma única TPU

Os scripts de treinamento a seguir foram executados em um Cloud TPU v3-8. Isso levará mais tempo, mas também é possível executá-los em um Cloud TPU v2-8. Para treinar em tipos maiores de Cloud TPU, consulte Treinamento em um pod do Cloud TPU.

Apenas treinamento

Esse script treina por 22.500 etapas e leva aproximadamente duas horas para ser executado em um Cloud TPU v3-8.

  1. Configure a seguinte variável de ambiente:

    (vm)$ TPU_NAME=$TPU_NAME  \
    export MODEL_DIR=${STORAGE_BUCKET}/retinanet-model-train; \
    export RESNET_CHECKPOINT=gs://cloud-tpu-artifacts/resnet/resnet-nhwc-2018-10-14/model.ckpt-112602; \
    export TRAIN_FILE_PATTERN=${STORAGE_BUCKET}/coco/train-*; \
    export EVAL_FILE_PATTERN=${STORAGE_BUCKET}/coco/val-*; \
    export VAL_JSON_FILE=${STORAGE_BUCKET}/coco/instances_val2017.json
    
  2. Execute o script de treinamento:

    (vm)$ python /usr/share/tpu/models/official/detection/main.py \
    --use_tpu=True \
    --tpu="${TPU_NAME?}" \
    --num_cores=8 \
    --model_dir="${MODEL_DIR?}" \
    --mode="train" \
    --eval_after_training=True \
    --params_override="{ type: retinanet, train: { 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 } }"
    
    • --tpu especifica o nome da TPU. Observe que ctpu passa esse nome para a VM do Compute Engine como uma variável de ambiente (TPU_NAME).
    • RESNET_CHECKPOINT especifica um ponto de verificação pré-treinado. O RetinaNet requer um modelo de classificação de imagem pré-treinado como o ResNet para servir de rede de backbone. Neste exemplo, usamos um ponto de verificação pré-treinado, criado com o modelo de demonstração do ResNet. Em vez disso, é possível treinar o próprio modelo do ResNet e especificar um ponto de verificação a partir do diretório do modelo do ResNet.

Apenas avaliação

O procedimento a seguir usa os dados de avaliação do COCO. Ele leva cerca de 10 minutos para ser executado nas etapas de avaliação.

  1. Configure a seguinte variável de ambiente:

    (vm)$ TPU_NAME=$TPU_NAME  \
    export MODEL_DIR=${STORAGE_BUCKET}/retinanet-model-train; \
    export EVAL_FILE_PATTERN=${STORAGE_BUCKET}/coco/val-*; \
    export VAL_JSON_FILE=${STORAGE_BUCKET}/coco/instances_val2017.json \
    export EVAL_SAMPLES=5000
    
  2. Execute o script de avaliação:

    (vm)$ python /usr/share/tpu/models/official/detection/main.py \
    --use_tpu=True \
    --tpu="${TPU_NAME?}" \
    --num_cores=8 \
    --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?} } }"
    
    • --tpu especifica o nome da TPU. Observe que ctpu passa esse nome para a VM do Compute Engine como uma variável de ambiente (TPU_NAME).

Treinamento e avaliação

Este script treina por um total de 22.500 etapas. Ele alterna entre o treinamento de mil etapas e a avaliação de 5 mil amostras de avaliação. O processo completo de treinamento e avaliação leva aproximadamente 9 horas em um Cloud TPU v3-8.

  1. Configure a seguinte variável de ambiente:

    (vm)$ TPU_NAME=$TPU_NAME  \
    export MODEL_DIR=${STORAGE_BUCKET}/retinanet-train-eval; \
    export RESNET_CHECKPOINT=gs://cloud-tpu-artifacts/resnet/resnet-nhwc-2018-10-14/model.ckpt-112602; \
    export TRAIN_FILE_PATTERN=${STORAGE_BUCKET}/coco/train-*; \
    export EVAL_FILE_PATTERN=${STORAGE_BUCKET}/coco/val-*; \
    export VAL_JSON_FILE=${STORAGE_BUCKET}/coco/instances_val2017.json \
    export EVAL_SAMPLES=5000 \
    export NUM_STEPS_PER_EVAL=1000
    
  2. Execute o script de treinamento e avaliação:

    (vm)$ python /usr/share/tpu/models/official/detection/main.py \
    --use_tpu=True \
    --tpu="${TPU_NAME?}" \
    --num_cores=8 \
    --model_dir="${MODEL_DIR?}" \
    --mode="train_and_eval" \
    --params_override="{ type: retinanet, train: { 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: ${EVAL_SAMPLES?}, num_steps_per_eval: ${NUM_STEPS_PER_EVAL?} } }"
    
    • --tpu especifica o nome da TPU. Observe que ctpu passa esse nome para a VM do Compute Engine como uma variável de ambiente (TPU_NAME).

Exportar modelo

O script a seguir salva um modelo de treinamento em um formato de alto nível do TensorFlow (SavedModel) que pode ser usado para inferências.

  1. Configure a seguinte variável de ambiente:

    (vm)$ export EXPORT_DIR="Target directory to store the SavedModel" \
    export CHECKPOINT_PATH="Path to the trained checkpoint" \
    export USE_TPU=true \
    export PARAMS_OVERRIDE="" \
    export BATCH_SIZE=1 \
    export INPUT_TYPE="image_bytes" \
    export INPUT_NAME="input" \
    export INPUT_IMAGE_SIZE="640,640" \
    export OUTPUT_IMAGE_INFO=true \
    export OUTPUT_NORMALIZED_COORDINATES=false \
    export CAST_NUM_DETECTIONS_TO_FLOAT=true
    
  2. Execute o script de exportação do modelo:

    (vm)$ /usr/share/tpu/models/official/detection/export_saved_model.py \
    --export_dir="${EXPORT_DIR?}" \
    --checkpoint_path="${CHECKPOINT_PATH?}" \
    --use_tpu="${USE_TPU?}" \
    --params_overrides="${PARAMS_OVERRIDE?}" \
    --batch_size="${BATCH_SIZE?}" \
    --input_type="${INPUT_TYPE?}" \
    --input_name="${INPUT_NAME?}" \
    --input_image_size="${INPUT_IMAGE_SIZE?}" \
    --output_image_info="${OUTPUT_IMAGE_INFO?}" \
    --output_normalized_coordinates="${OUTPUT_NORMALIZED_COORDINATES?}" \
    --cast_num_detections_to_float="${CAST_NUM_DETECTIONS_TO_FLOAT?}"
    

Treinamento de pod do Cloud TPU

O treinamento a seguir foi executado em um TPU v3-32. Se você usar outro tipo de pod de TPU, ajuste o parâmetro --num_cores com o número de núcleos correspondente ao seu tipo de TPU. Além disso, o train_batch_size precisa ser divisível pelo número de núcleos no seu tipo de TPU.

O script é treinado em 2109 etapas. O treinamento leva aproximadamente 30 minutos no TPU v3-32 e 10 minutos no TPU v3-128.

  1. Configure a seguinte variável de ambiente:

    (vm)$ TPU_NAME=$TPU_NAME  \
    export MODEL_DIR=${STORAGE_BUCKET}/retinanet-model-pod; \
    export  RESNET_CHECKPOINT=gs://cloud-tpu-artifacts/resnet/resnet-nhwc-2018-10-14/model.ckpt-112602; \
    export TRAIN_FILE_PATTERN=${STORAGE_BUCKET}/coco/train-*;
    
  2. Execute o script de treinamento do pod:

    (vm)$ python /usr/share/tpu/models/official/detection/main.py \
      --use_tpu=True \
      --tpu="${TPU_NAME?}" \
      --num_cores=32 \
      --model_dir="${MODEL_DIR?}" \
      --mode="train" \
      --eval_after_training=False \
      --params_override="{ type: retinanet, train: { train_batch_size: 1024, total_steps: 2109, learning_rate: { warmup_steps: 820, init_learning_rate: 0.64, learning_rate_levels: [0.064, 0.0064], learning_rate_steps: [1641, 1992] }, checkpoint: { path: ${RESNET_CHECKPOINT?}, prefix: resnet50/ }, train_file_pattern: ${TRAIN_FILE_PATTERN?} }, resnet: { batch_norm: { batch_norm_momentum: 0.9 }}, fpn: { batch_norm: { batch_norm_momentum: 0.9 }}, retinanet_head: { batch_norm: { batch_norm_momentum: 0.9 }} }"
    

Verificar o status do treinamento

Use o TensorBoard para ver o progresso do treinamento.

Quando você configura uma VM de avaliação, ela lê continuamente novos pontos de verificação e coloca as saídas dos eventos de avaliação no diretório model_dir. Veja o status atual do treinamento e avaliação no TensorBoard:

Siga o guia de configuração do TensorBoard e explore as ferramentas do Cloud TPU no TensorBoard.

Limpeza

As etapas abaixo mostram como evitar cobranças na sua conta do GCP pelo uso de recursos.

  1. Encerre a conexão com a VM do Compute Engine:

    (vm)$ exit
    

    Agora, o prompt precisa ser user@projectname, mostrando que você está no Cloud Shell.

  2. No Cloud Shell, execute ctpu delete com a sinalização --zone, usada ao configurar o Cloud TPU, para excluir a VM do Compute Engine e o Cloud TPU:

    $ ctpu delete [optional: --zone]
    
  3. Execute ctpu status para verificar se não há instâncias alocadas e evitar cobranças desnecessárias pelo uso da TPU. A exclusão pode levar vários minutos. Uma resposta como esta indica que não há mais instâncias alocadas:

    2018/04/28 16:16:23 WARNING: Setting zone to "us-central1-b"
    No instances currently exist.
            Compute Engine VM:     --
            Cloud TPU:             --
    
  4. Execute gsutil conforme mostrado, substituindo YOUR-BUCKET-NAME pelo nome do intervalo do Cloud Storage criado para este tutorial:

    $ gsutil rm -r gs://YOUR-BUCKET-NAME
    

A seguir

Treinar com diferentes tamanhos de imagem

Use uma rede backbone maior (por exemplo, ResNet-101 em vez de ResNet-50). Uma imagem maior de entrada e um backbone mais potente produzirão um modelo mais lento, porém, mais preciso.

Usar uma base diferente

Se preferir, faça o pré-treinamento de um modelo do ResNet no próprio conjunto de dados e use-o como base para o modelo do RetinaNet. Com um pouco mais de trabalho, também é possível alternar uma outra rede de backbone com o ResNet. Por fim, caso tenha interesse em implementar modelos próprios de detecção de objetos, essa rede pode ser uma boa base para fazer mais experimentos.

Lotes maiores em pods de TPU

Ao usar um pod do Cloud TPU, é possível especificar um tamanho de lote maior para reduzir o tempo de treinamento. Por exemplo, use o tamanho de lote 64 em um Cloud TPU de oito núcleos, o tamanho de lote 256 em um Cloud TPU de 32 núcleos e um tamanho de lote de 1024 em um Cloud TPU de 128 núcleos. O modelo escalona a taxa de aprendizado linearmente de acordo com o tamanho do lote.

(vm)$ export MODEL_DIR=${STORAGE_BUCKET}/retinanet-model; \
export RESNET_CHECKPOINT=gs://cloud-tpu-artifacts/resnet/resnet-nhwc-2018-10-14/model.ckpt-112602; \
export TRAIN_FILE_PATTERN=${STORAGE_BUCKET}/coco/train-*; \
python /usr/share/tpu/models/experimental/detection/main.py \
  --use_tpu=True \
  --tpu="${TPU_NAME?}" \
  --num_cores=128 \
  --model_dir="${MODEL_DIR?}" \
  --mode="train" \
  --eval_after_training=False \
  --params_override="{ type: retinanet, train: { train_batch_size: 1024, total_steps: 2109, learning_rate: { warmup_steps: 820, init_learning_rate: 0.64, learning_rate_levels: [0.064, 0.0064], learning_rate_steps: [1641, 1992] }, checkpoint: { path: ${RESNET_CHECKPOINT?}, prefix: resnet50/ }, train_file_pattern: ${TRAIN_FILE_PATTERN?} }, resnet: { batch_norm: { batch_norm_momentum: 0.9 }}, fpn: { batch_norm: { batch_norm_momentum: 0.9 }}, retinanet_head: { batch_norm: { batch_norm_momentum: 0.9 }} }"

Esta página foi útil? Conte sua opinião sobre:

Enviar comentários sobre…