Como treinar o RetinaNet na Cloud TPU

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

Nas instruções abaixo, presume-se que você conheça a execução de um modelo na Cloud TPU. Se você conhece a Cloud TPU há pouco tempo, consulte o guia de início rápido para ver os conceitos básicos.

Se você planeja treinar em uma fração do pod da TPU, veja como realizar o treinamento em pods de TPU para entender as alterações de parâmetros necessárias para frações de pod.

Objetivos

  • Criar um intervalo do Cloud Storage para armazenar o conjunto de dados e a saída do modelo.
  • Preparar o conjunto de dados COCO
  • Configurar uma VM do Compute Engine e um nó da Cloud TPU para treinamento e avaliação
  • Executar treinamento e avaliação em uma única Cloud TPU ou um pod da Cloud TPU

Custos

Neste tutorial, há componentes faturáveis do Google Cloud Platform, entre eles:

  • Compute Engine
  • Cloud TPU
  • Cloud Storage

Use a calculadora de preços para gerar uma estimativa de custos baseada na projeção de uso. Os novos usuários do GCP podem estar qualificados para uma avaliação gratuita.

Antes de começar

Nesta seção, você verá como configurar o armazenamento do Cloud Storage e uma VM do Compute Engine.

  1. Abra uma janela do Cloud Shell.

    Abrir o Cloud Shell

  2. Crie uma variável para o nome do projeto.

    export PROJECT_NAME=your-project_name
    
  3. Configure a ferramenta de linha de comando da gcloud para usar o projeto em que a Cloud TPU será criada.

    gcloud config set project ${PROJECT_NAME}
    
  4. Crie um intervalo do Cloud Storage usando o seguinte comando:

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

    Esse intervalo do Cloud Storage armazena os dados usados para treinar o modelo e os resultados do treinamento.

  5. Inicie uma VM do Compute Engine usando o comando ctpu up.

    $ ctpu up  --vm-only --disk-size-gb=300 --machine-type=n1-standard-8 --zone=europe-west4-a
    
  6. A configuração especificada aparecerá. Digite y para aprovar ou n para cancelar.

  7. Quando o comando ctpu up terminar a execução, verifique se o prompt do shell foi alterado de username@project para username@tpuname. Essa alteração mostra que você fez login na VM do Compute Engine.

    Se você não estiver conectado à VM do Compute Engine, execute o seguinte comando:

        gcloud compute ssh username --zone=europe-west4-a
    

Ao seguir essas instruções, execute cada comando iniciado por (vm)$ na janela de sessão da VM.

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

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

Preparar o conjunto de dados COCO

  1. Execute o script download_and_preprocess_coco.sh para converter o conjunto de dados COCO em um conjunto de TFRecords (*.tfrecord) 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. Ele gera uma série de arquivos *.tfrecord no diretório de dados locais. O script de download e conversão do COCO leva aproximadamente 1 hora para ser concluído.

  2. Depois de converter os dados para TFRecords, use o comando gsutil para copiá-los do armazenamento local para o intervalo do Cloud Storage. Também é preciso copiar os arquivos de anotação. Eles ajudam a validar 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
    

Configurar o ambiente de treinamento

  1. Execute o comando a seguir para criar a Cloud TPU.

    (vm)$ ctpu up --tpu-only --tpu-size=v3-8 --zone=europe-west4-a
    
    Parâmetro Descrição
    tpu-size Especifica o tipo de Cloud TPU. Especifique um tipo disponível na zona que você está usando para criar a Cloud TPU.
    zone A zona em que você planeja criar a Cloud TPU. Ela precisa ser a mesma zona usada para a VM do Compute Engine. Por exemplo, europe-west4-a.

  2. A configuração especificada aparecerá. Digite y para aprovar ou n para cancelar.

    Você verá a mensagem: Operation success; not ssh-ing to Compute Engine VM due to --tpu-only flag. Como você já concluiu a propagação de chave SSH anteriormente, ignore essa mensagem.

  3. 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 && \
          pip install --user Cython matplotlib opencv-python-headless pyyaml Pillow && \
          pip install --user 'git+https://github.com/cocodataset/cocoapi#egg=pycocotools&subdirectory=PythonAPI' && \
          pip install --user -U gast==0.2.2
    
  4. Atualizar os valores de sinal de atividade 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=120 \
           net.ipv4.tcp_keepalive_intvl=120 \
           net.ipv4.tcp_keepalive_probes=5
    
  5. Definir valores de parâmetros

    Em seguida, defina vários valores de parâmetro. Use esses parâmetros para treinar e avaliar o modelo.

    As variáveis que precisam ser definidas são descritas na tabela a seguir:

    Parâmetro Descrição
    STORAGE_BUCKET Esse é o nome do intervalo do Cloud Storage criado na seção Antes de começar.
    TPU_NAME Esse é o nome da VM do Compute Engine e da Cloud TPU. A VM do Compute Engine e o nome da Cloud TPU precisam ser os mesmos. Como a VM do Compute Engine foi definida com o valor padrão, o nome de usuário, defina a Cloud TPU com o mesmo valor.

  6. Use o comando export para definir essas variáveis.

      (vm)$ export STORAGE_BUCKET=gs://your-bucket-name
      (vm)$ export TPU_NAME=username
      

  7. Agora, está tudo pronto para executar o modelo nos dados de COCO pré-processados. Primeiro, adicione a pasta de nível superior /models ao caminho do Python com o comando:

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

O treinamento e a avaliação requerem o TensorFlow 1.13 ou uma versão posterior.

Treinamento sobre dispositivos de Cloud TPU único

Os scripts de treinamento a seguir foram executados em uma Cloud TPU v3-8. Isso levará mais tempo, mas também é possível executá-los em uma Cloud TPU v2-8.

Esse script treina por 22.500 etapas e leva aproximadamente três horas para ser executado em uma Cloud TPU v2-8 e aproximadamente uma hora e meia em uma Cloud TPU v3-8.

  1. Configure as seguintes variáveis 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 } }"
    
    Parâmetro Descrição
    tpu Especifica o nome da Cloud TPU. Para isso, especifique a variável de ambiente (TPU_NAME).
    model_dir Especifica o diretório em que os checkpoints e os resumos são armazenados durante o treinamento do modelo. Se a pasta não existir, ela será criada pelo programa. Ao usar uma Cloud TPU, o model_dir precisa ser um caminho do Cloud Storage (`gs://...`). É possível reutilizar uma pasta existente para carregar dados dos checkpoints atuais e armazenar outros checkpoints, contanto que os anteriores tenham sido criados usando uma TPU com o mesmo tamanho e versão do TensorFlow.
    RESNET_CHECKPOINT Especifica um checkpoint 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 checkpoint 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 checkpoint a partir do diretório do modelo do ResNet.

Avaliação de dispositivos de Cloud TPU único

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 as seguintes variáveis 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?} } }"
    
    Parâmetro Descrição
    tpu Especifica o nome da Cloud TPU. Para isso, especifique a variável de ambiente (TPU_NAME).
    model_dir Especifica o diretório em que os checkpoints e os resumos são armazenados durante o treinamento do modelo. Se a pasta não existir, ela será criada pelo programa. Ao usar uma Cloud TPU, o model_dir precisa ser um caminho do Cloud Storage (`gs://...`). É possível reutilizar uma pasta existente para carregar dados dos checkpoints atuais e armazenar outros checkpoints, contanto que os anteriores tenham sido criados usando uma TPU com o mesmo tamanho e versão do TensorFlow.

A partir daqui, é possível concluir este tutorial e limpar os recursos do GCP ou explorar a execução do modelo em pods da Cloud TPU.

Como escalonar o modelo com os pods da Cloud TPU

Para resultados mais rápidos, escalone o modelo com os pods da Cloud TPU. O modelo RetinaNet totalmente compatível funciona com as seguintes frações de pod:

  • v2-32
  • v3-32

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

  1. Exclua o recurso da Cloud TPU criado para treinar o modelo em um único dispositivo.

    (vm)$ ctpu delete --tpu-only --zone=europe-west4-a
  2. Execute o comando ctpu up, usando o parâmetro tpu-size para especificar a fração de pod a ser usada. Por exemplo, o comando a seguir usa uma fração de pod v3-32.

    (vm)$ ctpu up --tpu-only --tpu-size=v3-32 --zone=europe-west4-a 
  3. A configuração especificada aparecerá. Digite y para aprovar ou n para cancelar.

    Você verá a mensagem: Operation success; not ssh-ing to Compute Engine VM due to --tpu-only flag. Como você já concluiu a propagação de chave SSH anteriormente, ignore essa mensagem.

  4. Instale os pacotes extras necessários para o RetinaNet.

    (vm)$ sudo apt-get install -y python-tk && \
          pip install --user Cython matplotlib opencv-python-headless pyyaml Pillow && \
          pip install --user 'git+https://github.com/cocodataset/cocoapi#egg=pycocotools&subdirectory=PythonAPI' && \
          pip install --user -U gast==0.2.2
    
  5. Atualizar os valores de sinal de atividade 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=120 \
       net.ipv4.tcp_keepalive_intvl=120 \
       net.ipv4.tcp_keepalive_probes=5
    
  6. Defina as variáveis necessárias para o treinamento em um pod. Use o comando export para criar diversas variáveis bash e usá-las em uma string de configuração.

    (vm)$ export STORAGE_BUCKET=gs://your-bucket-name
    (vm)$ export TPU_NAME=username
    
  7. Adicione a pasta de nível superior /models ao caminho do Python.

    (vm)$ export PYTHONPATH="$PYTHONPATH:/usr/share/tpu/models"
    
  8. Configure as seguintes variáveis 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-*;
    
  9. Execute o script de treinamento do pod em um nó da TPU v3-32:

    (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 }} }"
    
    Parâmetro Descrição
    tpu Especifica o nome da Cloud TPU. Para isso, especifique a variável de ambiente (TPU_NAME).
    model_dir Especifica o diretório em que os checkpoints e os resumos são armazenados durante o treinamento do modelo. Se a pasta não existir, ela será criada pelo programa. Ao usar uma Cloud TPU, o model_dir precisa ser um caminho do Cloud Storage (`gs://...`). É possível reutilizar uma pasta existente para carregar dados dos checkpoints atuais e armazenar outros checkpoints, contanto que os anteriores tenham sido criados usando uma TPU com o mesmo tamanho e versão do TensorFlow.
    RESNET_CHECKPOINT Especifica um checkpoint 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 checkpoint 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 checkpoint a partir do diretório do modelo do ResNet.

Limpeza

Para evitar cobranças dos recursos usados neste tutorial na conta do Google Cloud Platform:

  1. Desconecte-se da instância do Compute Engine, caso ainda não tenha feito isso:

    (vm)$ exit
    

    Agora, o prompt 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 a Cloud TPU para excluir a VM do Compute Engine e a Cloud TPU:

    $ ctpu delete --zone=europe-west4-a
    
  3. Execute o seguinte comando para verificar se a VM do Compute Engine e a Cloud TPU foram encerradas:

    $ ctpu status --zone=europe-west4-a
    

    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 "europe-west4-a"
    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 em vez do 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.

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

Enviar comentários sobre…

Precisa de ajuda? Acesse nossa página de suporte.