Como executar o Inception na Cloud TPU

Neste tutorial, você verá como treinar o modelo do Inception (em inglês) na Cloud TPU.

Exoneração de responsabilidade

Este tutorial usa um conjunto de dados de terceiros. O Google não oferece declarações, proteções ou outras garantias sobre a validade ou quaisquer outros aspectos desse conjunto de dados.

Descrição do modelo

O Inception v3 é um modelo de reconhecimento de imagem muito usado que atinge uma enorme acurácia. Esse modelo é o auge de muitas ideias desenvolvidas por vários pesquisadores ao longo dos anos. Ele é baseado no documento original "Rethinking the Inception Architecture for Computer Vision", de Szegedy e outros autores.

O modelo inclui elementos básicos simétricos e assimétricos como:

  • convoluções;
  • pool médio;
  • pool máximo;
  • concatenações;
  • dropouts;
  • camadas totalmente conectadas.

A perda é calculada por meio da função softmax.

A imagem a seguir mostra o modelo em detalhes:

imagem

Você encontra mais informações sobre o modelo no GitHub (em inglês).

O modelo foi criado usando a avançada API Estimator (em inglês).

A API simplifica a criação do modelo ao encapsular a maioria das funções de nível baixo. Isso possibilita que os usuários se concentrem no desenvolvimento de modelos, e não no funcionamento interno do hardware subjacente responsável por execuções.

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. No Console do GCP, na página do seletor de projetos, selecione ou crie um projeto do GCP.

    Acesse a página do seletor de projetos

  3. Verifique se o faturamento foi ativado no projeto do Google Cloud Platform. Saiba como confirmar que o faturamento está ativado para seu projeto.

  4. Este tutorial inclui componentes faturáveis do Google Cloud Platform. Consulte a página de preços da Cloud TPU para fazer uma estimativa dos custos. Para evitar cobranças desnecessárias, não se esqueça de apagar os recursos criados ao terminar de usá-los.

Configurar os recursos

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

Criar 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 da Cloud TPU. Caso queira permissões mais específicas, consulte as permissões de nível de acesso.

O local do intervalo precisa estar na mesma região da máquina virtual (VM, na sigla em inglês) e do nó da TPU. As VMs e os nós da TPU estão localizados em zonas específicas, que são subdivisões dentro de uma região.

  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: Standard
    • Local: especifique um local para o intervalo na mesma região em que você planeja criar seu nó da TPU. Consulte tipos e zonas de TPU para saber onde vários tipos de TPU estão disponíveis.

Usar a ferramenta ctpu

Nesta seção, você verá como usar a ferramenta de provisionamento da Cloud TPU (em inglês), ctpu, para criar e gerenciar recursos de projeto da Cloud TPU. Esse recursos são compostos por uma máquina virtual (VM, na sigla em inglês) e um recurso da 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 a VM e os recursos da TPU usando comandos gcloud ou por meio do Console do Cloud. Consulte a página Como criar e excluir TPUs para aprender todas as maneiras de configurar e gerenciar a VM do Compute Engine e os recursos da Cloud TPU.

Executar 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 a Cloud TPU será criada.

  3. Execute ctpu up especificando as sinalizações mostradas para um dispositivo Cloud TPU ou fração do pod. Consulte a Referência da CTPU para ver as opções de sinalização e descrições.

  4. Configure um dispositivo do Cloud TPU:

    $ ctpu up 

    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 da Cloud TPU.

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

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

Verificar a VM do Compute Engine

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.

Conseguir os dados

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

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

O aplicativo de treinamento precisa que os dados de treinamento sejam acessíveis no Cloud Storage. Ele também usa o intervalo do Cloud Storage para armazenar pontos de verificação durante o treinamento.

Conjunto de dados de treinamento

O ImageNet é um banco de dados de imagens. As imagens do banco de dados são organizadas hierarquicamente, com cada nó da hierarquia representado por centenas e milhares de imagens.

Neste tutorial, é usada uma versão de demonstração do conjunto de dados completo do ImageNet, conhecido como o conjunto de dados fake_imagenet. Essa versão de demonstração permite que você teste o tutorial sem a exigência do armazenamento ou tempo necessário para fazer o download e executar um modelo no banco de dados completo do ImageNet. Veja abaixo as instruções para usar o conjunto de dados fake_imagenet gerado aleatoriamente para testar o modelo. Também é possível usar o conjunto de dados completo do ImageNet.

Usamos a variável de ambiente DATA_DIR, descrita abaixo, para especificar em qual conjunto de dados faremos o treinamento.

O conjunto de dados fake_imagenet é útil apenas para entender como usar uma Cloud TPU e validar o desempenho de ponta a ponta. Os números de acurácia e o modelo salvo não são importantes.

O conjunto de dados do fake_imagenet está neste local no Cloud Storage:

gs://cloud-tpu-test-datasets/fake_imagenet

Configurar o TensorBoard (opcional)

No TensorBoard, há um conjunto de ferramentas desenvolvidas para apresentar visualmente os dados do TensorFlow. Quando o TensorBoard é usado para monitoramento, é possível identificar gargalos no processamento e receber sugestões para melhorar o desempenho.

Caso não seja necessário monitorar a saída do modelo no momento, ignore as etapas de configuração do TensorBoard.

Caso queira monitorar a saída e o desempenho do modelo, siga o guia para configurar o TensorBoard.

Executar o modelo

Agora você está pronto para treinar e avaliar o modelo do Inception v3 usando os dados do ImageNet.

Esse modelo está pré-instalado na sua VM do Compute Engine, no diretório /usr/share/tpu/models/experimental/inception/.

Nas etapas a seguir, o prefixo (vm)$ significa que é preciso executar o comando na VM do Compute Engine:

  1. Configure uma variável de ambiente DATA_DIR que contenha um dos valores a seguir:

    • Se você estiver usando o conjunto de dados fake_imagenet:

      (vm)$ export DATA_DIR=gs://cloud-tpu-test-datasets/fake_imagenet
      
    • Se tiver feito o upload de um conjunto de dados de treinamento no intervalo do Cloud Storage:

      (vm)$ export DATA_DIR=${STORAGE_BUCKET}/data
      
  2. Execute o modelo do Inception v3:

    (vm)$ python /usr/share/tpu/models/experimental/inception/inception_v3.py \
        --tpu=$TPU_NAME \
        --learning_rate=0.165 \
        --train_steps=250000 \
        --iterations=500 \
        --use_tpu=True \
        --use_data=real \
        --mode=train_and_eval \
        --train_steps_per_eval=2000 \
        --data_dir=${DATA_DIR} \
        --model_dir=${STORAGE_BUCKET}/inception
    • --tpu especifica o nome da Cloud TPU. Observe que ctpu transmite esse nome para a VM do Compute Engine como uma variável de ambiente (TPU_NAME).
    • --use_data especifica o tipo de dados que o programa precisa usar durante o treinamento, seja fictício ou real. O valor padrão é fictício.
    • --data_dir especifica o caminho do Cloud Storage para a entrada de treinamento. O aplicativo ignora esse parâmetro quando você usa dados fake_imagenet.
    • --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, o programa criará uma. Ao usar uma Cloud TPU, o model_dir precisa ser um caminho do Cloud Storage (gs://...). É possível reutilizar uma pasta atual para carregar dados dos checkpoints atuais e armazenar outros checkpoints, contanto que os anteriores tenham sido criados usando uma TPU do mesmo tamanho e versão do Tensorflow.

O que esperar

O Inception v3 funciona em imagens 299 x 299. O tamanho de lote padrão do treinamento é 1024. Isso significa que cada iteração opera em 1024 dessas imagens.

É possível usar a sinalização --mode para selecionar um dos três modos de operação: train, eval e train_and_eval.

  • --mode=train ou --mode=eval especificam um job somente de treinamento ou de avaliação, respectivamente.
  • --mode=train_and_eval especifica um job híbrido que faz treinamento e avaliação.

Os jobs somente "train" são executados para o número especificado de etapas definidas em train_steps. Se você quiser, eles podem passar por todo o conjunto de treinamento.

Os jobs "train_and_eval" são ciclos com segmentos de treinamento e avaliação. Cada ciclo de treinamento é executado em train_steps_per_eval e seguido por um job de avaliação (usando as ponderações que foram treinadas até então).

O número de ciclos de treinamento é definido pela função piso (em inglês) de train_steps dividido por train_steps_per_eval.

floor(train_steps / train_steps_per_eval)

Por padrão, os modelos baseados na API Estimator informam os valores de perda a cada número de etapas específico. O formato do relatório é similar a este:

step = 15440, loss = 12.6237

Discussão: modificações específicas da TPU no modelo

Preparar os modelos baseados na API Estimator requer bem poucas modificações específicas. O programa importa as bibliotecas a seguir:

from google.third_party.tensorflow.contrib.tpu.python.tpu import tpu_config
from google.third_party.tensorflow.contrib.tpu.python.tpu import tpu_estimator
from google.third_party.tensorflow.contrib.tpu.python.tpu import tpu_optimizer

A função "CrossShardOptimizer" encapsula o otimizador assim:

if FLAGS.use_tpu:
  optimizer = tpu_optimizer.CrossShardOptimizer(optimizer)

A função que define o modelo retorna uma especificação da Estimator usando:

return tpu_estimator.TPUEstimatorSpec(
    mode=mode, loss=loss, train_op=train_op, eval_metrics=eval_metrics)

A função principal define uma configuração compatível com a Estimator usando:

run_config = tpu_config.RunConfig(
    master=tpu_grpc_url,
    evaluation_master=tpu_grpc_url,
    model_dir=FLAGS.model_dir,
    save_checkpoints_secs=FLAGS.save_checkpoints_secs,
    save_summary_steps=FLAGS.save_summary_steps,
    session_config=tf.ConfigProto(
        allow_soft_placement=True,
        log_device_placement=FLAGS.log_device_placement),
    tpu_config=tpu_config.TPUConfig(
        iterations_per_loop=iterations,
        num_shards=FLAGS.num_shards,
        per_host_input_for_training=per_host_input_for_training))

O programa usa essa configuração definida e uma função de definição de modelo para criar um objeto da Estimador:

inception_classifier = tpu_estimator.TPUEstimator(
    model_fn=inception_model_fn,
    use_tpu=FLAGS.use_tpu,
    config=run_config,
    params=params,
    train_batch_size=FLAGS.train_batch_size,
    eval_batch_size=eval_batch_size,
    batch_axis=(batch_axis, 0))

Os jobs somente "train" precisam chamar apenas a função de treinamento:

inception_classifier.train(
    input_fn=imagenet_train.input_fn, steps=FLAGS.train_steps)

Os jobs somente "eval" recebem os dados dos checkpoints disponíveis e aguardam até que outro também fique disponível:

for checkpoint in get_next_checkpoint():
  eval_results = inception_classifier.evaluate(
      input_fn=imagenet_eval.input_fn,
      steps=eval_steps,
      hooks=eval_hooks,
      checkpoint_path=checkpoint)

Quando a opção train_and_eval é selecionada, os jobs de treinamento e os de avaliação são executados em paralelo. Durante a avaliação, as variáveis treináveis são carregadas a partir do último checkpoint a ficar disponível. Os ciclos de treinamento e avaliação são repetidos conforme especificado nas sinalizações:

for cycle in range(FLAGS.train_steps // FLAGS.train_steps_per_eval):
  inception_classifier.train(
      input_fn=imagenet_train.input_fn, steps=FLAGS.train_steps_per_eval)

  eval_results = inception_classifier.evaluate(
      input_fn=imagenet_eval.input_fn, steps=eval_steps, hooks=eval_hooks)

Se você usou o conjunto de dados fake_imagenet para treinar o modelo, siga para a limpeza.

Como usar o conjunto de dados completo do ImageNet

Verificar requisitos de espaço

Você precisa de cerca de 300 GB de espaço disponível na sua máquina local ou VM para usar o conjunto de dados completo do ImageNet.

É possível aumentar o tamanho do disco da VM usando um dos seguintes métodos:

  • Especifique a sinalização --disk-size-gb na linha de comando ctpu up com o tamanho, em GB, que você quer alocar.
  • Siga o guia do Compute Engine para adicionar um disco à VM.
    • Defina Ao excluir uma instância como Excluir disco para garantir que o disco seja removido quando você excluir a VM.
    • Anote o caminho do novo disco. Por exemplo, /mnt/disks/mnt-dir.

Fazer o download dos dados do ImageNet e convertê-los

  1. Inscreva-se em uma conta do ImageNet (link em inglês). Lembre-se do nome de usuário e senha que você usou para criar a conta.

  2. Configure uma variável de ambiente DATA_DIR que aponta para um caminho no intervalo do Cloud Storage:

    (vm)$ export DATA_DIR=gs://storage-bucket
    
  3. No GitHub, faça o download do script imagenet_to_gcs.py:

    $ wget https://raw.githubusercontent.com/tensorflow/tpu/master/tools/datasets/imagenet_to_gcs.py
    
  4. Defina uma variável SCRATCH_DIR para conter os arquivos de trabalho do script. A variável precisa especificar um local na máquina local ou na VM do Compute Engine. Por exemplo, na sua máquina local:

    $ SCRATCH_DIR=./imagenet_tmp_files
    

    Ou se você estiver processando os dados na VM:

    (vm)$ SCRATCH_DIR=/mnt/disks/mnt-dir/imagenet_tmp_files
    
  5. Execute o script imagenet_to_gcs.py para fazer o download, formatar e fazer upload dos dados do ImageNet para o intervalo. Substitua [USERNAME] e [PASSWORD] pelo nome de usuário e senha que você usou para criar a conta do ImageNet.

    $ pip install google-cloud-storage
    $ python imagenet_to_gcs.py \
      --project=$PROJECT \
      --gcs_output_path=$DATA_DIR \
      --local_scratch_dir=$SCRATCH_DIR \
      --imagenet_username=[USERNAME] \
      --imagenet_access_key=[PASSWORD]
    

Opcionalmente, se os dados brutos, no formato JPEG, já tiverem sido salvos, será possível fornecer um caminho raw_data_directory direto. Se um diretório de dados brutos para dados de treinamento ou validação for fornecido, ele precisará estar no formato:

Os nomes dos subdiretórios de treinamento (por exemplo, n03062245) são "IDs do WordNet" (wnid). A API ImageNet (em inglês) mostra o mapeamento de IDs do WordNet para seus rótulos de validação associados no arquivo synset_labels.txt. Uma sincronia nesse contexto é um grupo visualmente semelhante de imagens.

Observação: o download e o pré-processamento dos dados podem levar 10 horas ou mais, dependendo da velocidade da rede e do computador. Não interrompa o script.

Quando o script terminar o processamento, uma mensagem como esta será exibida:

2018-02-17 14:30:17.287989: Finished writing all 1281167 images in data set.

O script produz vários diretórios para treinamento e validação do formulário:

${DATA_DIR}/train-00000-of-01024
${DATA_DIR}/train-00001-of-01024
 ...
${DATA_DIR}/train-01023-of-01024

e

${DATA_DIR}/validation-00000-of-00128
S{DATA_DIR}/validation-00001-of-00128
 ...
${DATA_DIR}/validation-00127-of-00128

Depois que os dados forem enviados para seu intervalo do Cloud, execute seu modelo e defina --data_dir=${DATA_DIR}.

Realizar a 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 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 [optional: --zone]
    
  3. Execute ctpu status para garantir que não haja instâncias alocadas e evitar cobranças desnecessárias no 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. Substitua YOUR-BUCKET-NAME pelo nome do intervalo do Cloud Storage criado para este tutorial:

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

Inception v4

O modelo do Inception v4 é de rede neural profunda. Ele usa componentes do Inception v3 para alcançar uma precisão maior. O modelo é descrito no artigo "Inception-v4, Inception-ResNet and the Impact of Residual Connections on Learning", de Szegedy e outros autores.

O modelo do Inception v4 está pré-instalado na sua VM do Compute Engine, no diretório /usr/share/tpu/models/experimental/inception/.

Nas etapas a seguir, o prefixo (vm)$ significa que é preciso executar o comando na VM do Compute Engine:

  1. Se o TensorBoard estiver em execução na guia do Cloud Shell, você precisará de outra guia para trabalhar. Abra outra guia no Cloud Shell e use ctpu no novo shell para se conectar à VM do Compute Engine:

    $ ctpu up
  2. Configure uma variável de ambiente DATA_DIR que contenha um dos valores a seguir:

    • Se você estiver usando o conjunto de dados fake_imagenet:

      (vm)$ export DATA_DIR=gs://cloud-tpu-test-datasets/fake_imagenet
      
    • Se tiver feito o upload de um conjunto de dados de treinamento no intervalo do Cloud Storage:

      (vm)$ export DATA_DIR=${STORAGE_BUCKET}/data
      
  3. Execute o modelo do Inception v4:

    (vm)$ python /usr/share/tpu/models/experimental/inception/inception_v4.py \
        --tpu=$TPU_NAME \
        --learning_rate=0.36 \
        --train_steps=1000000 \
        --iterations=500 \
        --use_tpu=True \
        --use_data=real \
        --train_batch_size=256 \
        --mode=train_and_eval \
        --train_steps_per_eval=2000 \
        --data_dir=${DATA_DIR} \
        --model_dir=${STORAGE_BUCKET}/inception
    • --tpu especifica o nome da Cloud TPU. Observe que ctpu transmite esse nome para a VM do Compute Engine como uma variável de ambiente (TPU_NAME).
    • --use_data especifica o tipo de dados que o programa precisa usar durante o treinamento, seja fictício ou real. O valor padrão é fictício.
    • --train_batch_size especifica o tamanho do lote de treinamento como 256. Como o modelo do Inception v4 é maior que o do v3, ele precisa ser executado em um tamanho de lote menor por núcleo de TPU.
    • --data_dir especifica o caminho do Cloud Storage para a entrada de treinamento. O aplicativo ignora esse parâmetro quando você usa dados fake_imagenet.
    • --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, o programa criará uma. Ao usar uma Cloud TPU, o model_dir precisa ser um caminho do Cloud Storage (gs://...). É possível reutilizar uma pasta atual para carregar dados dos checkpoints atuais e armazenar outros checkpoints, contanto que os anteriores tenham sido criados usando uma TPU do mesmo tamanho e versão do Tensorflow.

A seguir