Converter um conjunto de dados de classificação de imagem para uso com o Cloud TPU

Neste tutorial, descrevemos como usar o script de amostra de conversor de dados de classificação de imagens para converter um conjunto de dados brutos de classificação de imagens no formato TFRecord, que é usado para treinar modelos do Cloud TPU.

Os TFRecords tornam a leitura de arquivos grandes do Cloud Storage mais eficiente do que a leitura de cada imagem como um arquivo individual. É possível usar o TFRecord sempre que você usa um pipeline tf.data.Dataset.

Consulte os seguintes documentos do TensorFlow para saber como usar o TFRecord:

Se você usa o framework PyTorch ou JAX e não usa o Cloud Storage para armazenamento de conjuntos de dados, pode não ter a mesma vantagem dos TFRecords.

Visão geral da conversão

A pasta de classificação de imagens no repositório do conversor de dados no GitHub contém o script converter, image_classification_data.py e uma implementação de amostra, simple_example.py, que podem ser copiados e modificados para você fazer sua própria conversão de dados.

A amostra de conversão de dados de classificação de imagens define duas classes, ImageClassificationConfig e ImageClassificationBuilder. Essas classes são definidas em tpu/tools/data_converter/image_classification_data.py.

ImageClassificationConfig é uma classe base abstrata. Você usa a subclasse ImageClassificationConfig para definir a configuração necessária para criar uma instância de ImageClassificationBuilder.

ImageClassificationBuilder é um builder de conjuntos de dados do Tensorflow para classificação de imagens. Ele é uma subclasse de tdfs.core.GeneratorBasedBuilder. Sua função é recuperar exemplos de dados do conjunto de dados e os converter em TFRecords. Os TFRecords são gravados em um caminho especificado pelo parâmetro data_dir para o método __init__ de ImageClassificationBuilder.

Em simples_example.py, SimpleDatasetConfig usa a subclasse ImageClassificationConfig, implementando propriedades que definem os modos disponíveis, o número de classes de imagem e um gerador de exemplo que produz um dicionário com dados de imagem e uma classe de imagem para cada exemplo no conjunto de dados.

A função main() cria um conjunto de dados de imagem gerados aleatoriamente e uma instância de um objeto SimpleDatasetConfig, especificando o número de classes e o caminho para o conjunto de dados no disco. Em seguida, main() cria uma instância de um objeto ImageClassificationBuilder, transmitindo a instância SimpleDatasetConfig. Por fim, main() chama download_and_prepare(). Quando esse método é chamado, a instância ImageClassificationBuilder usa o gerador de exemplo de dados implementado por SimpleDatasetConfig para carregar cada exemplo e os salva em uma série de arquivos TFRecord.

Para uma explicação mais detalhada, consulte o Notebook do conversor de classificação.

Como modificar a amostra de conversão de dados para carregar seu conjunto de dados

Para converter seu conjunto de dados no formato TFRecord, crie uma subclasse da classe ImageClassificationConfig e defina as seguintes propriedades:

  • num_labels: retorna o número de classes de imagem.
  • supported_modes: retorna uma lista de modos aceitos pelo conjunto de dados (como teste, treinamento e validação).
  • text_label_map: retorna um dicionário que modela a associação entre um rótulo de classe de texto e um rótulo de classe de número inteiro (SimpleDatasetConfig não usa essa propriedade porque não requer uma associação).
  • download_path: o caminho para fazer o download do conjunto de dados (SimpleDatasetConfig não usa essa propriedade porque o example_generator carrega os dados do disco).

Implemente a função do gerador example_generator. Esse método precisa produzir um dicionário com os dados e o nome da classe da imagem para cada exemplo. ImageClassificationBuilder usa a função example_generator() para recuperar cada exemplo e os grava no disco no formato TFRecord.

Como executar a amostra de conversão de dados

  1. Crie um bucket do Cloud Storage usando o seguinte comando:

    gcloud storage buckets create gs://bucket-name --project=your-project-id --location=us-central2
  2. Inicie um Cloud TPU usando o comando gcloud.

    $ gcloud compute tpus tpu-vm create tpu-name \
        --zone=us-central2-b \
        --accelerator-type=v4-8 \
        --version=tpu-vm-tf-2.17.1-pjrt

    Descrições de flags de comando

    zone
    A zona em que você planeja criar o Cloud TPU.
    accelerator-type
    O tipo de acelerador especifica a versão e o tamanho do Cloud TPU que você quer criar. Para mais informações sobre os tipos de aceleradores disponíveis em cada versão de TPU, consulte Versões de TPU.
    version
    A versão do software do Cloud TPU.
  3. Conecte-se à TPU usando SSH:

    $ gcloud compute tpus tpu-vm ssh tpu-name --zone=us-central2-b

    Quando você se conecta à TPU, o prompt do shell muda de username@projectname para username@vm-name.

  4. Instale os pacotes necessários.

    (vm)$ pip3 install opencv-python-headless pillow
    (vm)$ pip3 install tensorflow-datasets
  5. Crie as variáveis de ambiente a seguir a serem usadas pelo script.

    (vm)$ export STORAGE_BUCKET=gs://bucket-name
    (vm)$ export CONVERTED_DIR=$HOME/tfrecords
    (vm)$ export GENERATED_DATA=$HOME/data
    (vm)$ export GCS_CONVERTED=$STORAGE_BUCKET/data_converter/image_classification/tfrecords
    (vm)$ export GCS_RAW=$STORAGE_BUCKET/image_classification/raw
    (vm)$ export PYTHONPATH="$PYTHONPATH:/usr/share/tpu/models"
  6. Faça o download do repositório de TPUs do TensorFlow.

    (vm)$ cd /usr/share/
    (vm)$ git clone https://github.com/tensorflow/tpu.git
    (vm)$ cd tpu/tools/data_converter

Como executar o conversor de dados em um conjunto de dados falso

O script simple_example.py está na pasta image_classification da amostra do conversor de dados. Executar esse script com os parâmetros a seguir gera um conjunto de imagens falsas e as converte em TFRecords.

(vm)$ python3 image_classification/simple_example.py \
  --num_classes=1000 \
  --data_path=$GENERATED_DATA \
  --generate=True \
  --num_examples_per_class_low=10 \
  --num_examples_per_class_high=11 \
  --save_dir=$CONVERTED_DIR

Como executar o conversor de dados em um dos nossos conjuntos de dados brutos

  1. Crie uma variável de ambiente para o local dos dados brutos.

    (vm)$ export GCS_RAW=gs://cloud-tpu-test-datasets/data_converter/raw_image_classification
  2. Execute o script simple_example.py.

    (vm)$ python3 image_classification/simple_example.py \
    --num_classes=1000 \
    --data_path=$GCS_RAW \
    --generate=False \
    --save_dir=$CONVERTED_DIR

O script simple_example.py usa os seguintes parâmetros:

  • num_classes indica o número de classes no conjunto de dados. Usamos 1.000 aqui para corresponder ao formato ImageNet.
  • generate determina se os dados brutos serão ou não gerados.
  • data_path indica o caminho em que os dados devem ser gerados, no caso de generate=True, ou o caminho em que os dados brutos são armazenados, no caso de generate=False.
  • num_examples_per_class_low e num_examples_per_class_high determinam quantos exemplos gerar por classe. O script gera um número aleatório de exemplos nesse intervalo.
  • save_dir indica o local em que os TFRecords são salvos. Para treinar um modelo no Cloud TPU, os dados precisam ser armazenados no Cloud Storage. Isso pode ser feito no Cloud Storage ou na VM.

Como renomear e mover os TFRecords para o Cloud Storage

O exemplo a seguir usa os dados convertidos com o modelo do ResNet.

  1. Renomeie esses TFRecords para o mesmo formato dos TFRecords do ImageNet:

    (vm)$ cd $CONVERTED_DIR/image_classification_builder/Simple/0.1.0/
    (vm)$ sudo apt update
    (vm)$ sudo apt install rename
    (vm)$ rename -v 's/image_classification_builder-(\w+)\.tfrecord/$1/g' *
  2. Copie os TFRecords para o Cloud Storage:

    (vm)$ gcloud storage cp train* $GCS_CONVERTED
    (vm)$ gcloud storage cp validation* $GCS_CONVERTED

Limpeza

  1. Desconecte-se do Cloud TPU, 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 gcloud para excluir o recurso da VM.

    $ gcloud compute tpus tpu-vm delete tpu-name \
      --zone=us-central2-b
  3. Execute gcloud compute tpus tpu-vm list para verificar se a VM foi excluída. A exclusão pode levar vários minutos. Uma resposta como a seguir indica que as instâncias foram excluídas.

    $ gcloud compute tpus tpu-vm list --zone=us-central2-b
    Listed 0 items.
    
  4. Execute a gcloud CLI conforme mostrado, substituindo bucket-name pelo nome do bucket do Cloud Storage criado neste tutorial:

    $ gcloud storage rm gs://bucket-name --recursive