Criando um modelo de classificação de imagens com AutoML na Vertex AI

Luciano Martins
google-cloud-brasil
8 min readMay 10, 2023

--

* TLDR: Aqui vamos passar pelo processo de definição de um modelo de machine learning de classificação de imagens, com a facilidade que o Google AutoML oferece, utilizando a Vertex AI, plataforma de desenvolvimento de soluções de machine learning na Google Cloud.

Como chegamos até aqui?

No mês de abril, o time de Google Cloud Brasil publicou, em 5 (cinco) episódios, uma série técnica chamada “Desvendando AI”, toda em português e voltada para audiência de praticantes de tecnologia (engenheiros, desenvolvedores, pesquisadores, etc):

playlist da série "Desvendando AI" no YouTube de Google Cloud LATAM

Se você ainda não viu, confere na playlist do canal Google Cloud LATAM.

Em um dos vídeos, recebi o comentário abaixo:

comentário na série de vídeos "Desvendando AI"

E aqui estamos. Vamos no passo a passo de como utilizar a Vertex AI para treinar um modelo de classificação de imagens em uma abordagem low code — Ou seja, utilizando o Google AutoML e sem necessitar criar cada etapa e cada detalhe do modelo de machine learning que será gerado.

Mas o que faremos aqui?

Para definirmos uma base do que faremos, vamos olhar o que envolve um processo de modelagem e treinamento de machine learning. O processo se inicia na análise de desafio de negócio, onde definimos qual problema precisa ser resolvido; passamos por uma análise de dados disponíveis, a modelagem em si (no framework que você escolher — TensorFlow, PyTorch, scikit-learn, etc), treinamento e otimização do modelo até chegar na avaliação e uso do modelo em si… E começamos tudo de novo, num ciclo iterativo e incremental. Algo como a figura abaixo:

processo de desenvolvimento de uma solução de machine learning

Como o Google AutoML ajuda nesse processo? O AutoML irá abstrair pra você (ou realizar por você) as etapas de engenharia de features, definição de modelos a serem treinados, treinamento e otimização desses modelos, seleção do melhor modelo e disponibilização do modelo para você. Ou seja, as ações da imagem abaixo:

etapas automatizadas pelo Google AutoML

Ou seja, você consegue salvar tempo de prototipação, focando mais no problema que você quer resolver e na qualidade dos seus dados e o AutoML será responsável por selecionar o melhor modelo possível em seu universo de modelos possíveis (que inclui modelos criados pela engenharia do Google e variações de modelos utilizando Neural Architecture Search, ou NAS — mas este tópico merece uma postagem inteira dedicada a isso. Mas vamos as estapas do laboratório de Vertex AI com Google AutoML.

Definição dos dados a serem utilizados

Para realizar este experimento, vamos usar o dataset gratuito ImageNetDogs, criado e gerido pela universidade de Stanford. O dataset é composto de mais de 20.000 (vinte mil) imagens de 120 (cento e vinte) raças de cachorros. São todas imagens reais, sem muita produção (não são imagens de estúdio, ou com cores e brilho otimizados), buscando montar algo que seja o mais próximo possível de fotos do nosso cotidiano (que fotografaríamos de nossos cachorros com nossos celulares). Um exemplo abaixo:

Como o dataset é bem grande, ele acaba aumentando a complexidade desse laboratório experimentativo; além disso, o AutoML realiza ações de aumento do dataset (dataset augmentation) o que nos permite criar datasets menores. Então, antes de começarmos, podemos criar um “sub-dataset” contendo menos raças de cachorros (apenas 15, das 120) e com menos exemplos de imagens de cada raça (100 imagens por raça). Para isso, usamos o shell script abaixo:

$ mkdir dataset
$ cd dataset; axel -n 15
$ tar -xf images.tar
$ cd Images; for dir in `ls`; do new_name=`echo $dir | cut -d- -f2-`; mv $ dir $new_name; done;
$ for dir in `find . -type d | shuf -n 15`; do dirname=`echo $dir | cut -d/ -f2`; mkdir -p ../train/$dirname; for img in `find $dir -type f | shuf -n 100`; do mv $img ../train/$dirname; done; done

Com isso, criamos uma estrutura de diretórios contendo 15 (quinze) pastas com nomes de raças de cachorro e 100 (cem) imagens de cada raça dentro dos diretórios correspondentes de cada raça. O próximo passo é de copiar as imagens para um Cloud Storage bucket. Neste cenário, criei um bucket chamado gs://vertexai-labs. É importante alterar o comando abaixo de acordo com as configurações de seu ambiente:

$ gsutil -m cp -r dataset/train/* gs://vertexai-labs/cachorros-dataset

Para que as imagens sejam incluídas na Vertex AI, precisamos criar um arquivo .csv que contenha a lista de todas as imagens que serão utilizadas para compor o dataset de treinamento. Maiores detalhes sobre este processo de definição do dataset podem ser encontrados na documentação da Vertex AI. Para criar o arquivo CSV com a lista de imagem, utilizamos o comando abaixo:

$ for img in `cat dataset/list.out`; do classe=`echo $img | cut -d/ -f5`; echo "${img},${classe}" >> dataset/dataset.csv; done
$ gsutil -q cp dataset/dataset.csv gs://vertexai-labs/cachorros-dataset

Com todos os dados necessários armazenados no bucket do Cloud Storage, agora faremos a criação do dataset gerenciado na Vertex AI. Utilizaremos a SDK de Python no processo.

Primeiro iremos importar o módulo Python de desenvolvimento com a Vertex AI, depois instanciar um cliente da Vertex AI e, finalmente, criar o dataset gerenciado e popular com os dados do bucket do Cloud Storage. Algo mais ou menos assim:

import google.cloud.aiplatform as aiplatform
from google.cloud.aiplatform import ImageDataset, schema

# definindo as variáveis necessáris
projeto='lucianomartins-demos-345000'
regiao='us-central1'
bucket='gs://vertexai-labs'
schema_uri = schema.dataset.ioformat.image.single_label_classification

# instanciando o cliente da Vertex AI
aiplatform.init(project=projeto,
location=regiao,
staging_bucket=bucket)

# criando o dataset gerenciado
dataset = ImageDataset.create(display_name='cachorros-dataset',
sync=True)

# populando o dataset com as imagens do bucket
dataset = dataset.import_data(gcs_source=bucket + \
'/cachorros-dataset/dataset.csv',
import_schema_uri=schema_uri,
sync=True,
import_request_timeout=2700.0)

O processo de importação das imagens pode demorar alguns minutos (cerca de quinze minutos). Ao final desta etapa, você terá o seu dataset gerenciado criado — e que pode ser visto na console da Vertex AI):

Criando o job de treinamento da Vertex AI com Google AutoML

Com o dataset preparado, a próxima etapa é realizar o treinamento de um modelo com AutoML. Por ser uma abordagem low code, ou seja, que não é necessário desenvolver, explicitamente, todas os detalhes do modelo de machine learning, teremos somente duas ações para tomar: a definição do job de treinamento e a execução do job de treinamento.

Para criar o job de treinamento, utilizaremos o cliente da Vertex AI, da SDK de Python, como fizemos para a criação do dataset gerenciado.

Vale uma explicação das informações que estamos informando:

“display name” é como ficará a descrição do job na Vertex AI

“prediction type” é qual cenário de visão computacional estamos trabalhando (classificação de imagens, neste caso)

Se o cenário é uma classificação “multi_label”, ou seja, se em uma mesma imagem pode haver várias classes (ou raças) possíveis. No nosso caso, não

“model_type”, para definir se o modelo será utilizado na Google Cloud ou preparado para ser utilizado na “borda”, em um cenário de IoT. Aqui utilizamos a opção de para “cloud”

E finalmente, informamos que não estamos otimizando um modelo treinado previamente com “base_model=None”.

job = aiplatform.AutoMLImageTrainingJob(
display_name='treinamento de classificador de cachorros',
prediction_type='classification',
multi_label=False,
model_type='CLOUD',
base_model=None)

Tendo a definição do job, podemos executá-lo (também utilizando a SDK da Vertex AI). Aqui informamos:

qual dataset será utilizado; o “model_display_name”, que é a descrição do modelo na Model Registry (ou biblioteca de modelos treinados)

como o nosso dataset será utilizado (aqui teremos 80% das imagens para o treinamento do modelo, 10% para a avaliação do modelo durante o treinamento e 10% para testes após o treinamento)

Além de outros detalhes de execução (para ver todas as possibilidades, verifique a documentação da Vertex AI para execução de jobs de treinamento):

model = job.run(
dataset=dataset,
model_display_name='classificador-cachorros',
training_fraction_split=0.8,
validation_fraction_split=0.1,
test_fraction_split=0.1,
budget_milli_node_hours=10000,
disable_early_stopping=False)

Esse processo pode demorar um tempo — No meu lab aqui, levou, mais ou menos, 2 horas e 30 minutos pra ser finalizado. Com o processo finalizado, podemos verificar as métricas do treinamento via a a console da Vertex AI e via a SDK da Vertex AI. Aqui como estamos fazendo tudo via SDK, vamos seguir nessa abordagem:

model_evaluations = model.list_model_evaluations()
for model_evaluation in model_evaluations:
print(model_evaluation.to_dict())

O resultado é a lista de todas as informações referentes às métricas do treinamento — coisas como acurácia, precisão, recall, a matriz de confusão, etc (deixando aqui só um pedaço da saída do comando):

{'name': 'projects/48397268769/locations/us-central1/models/4167564684666339328@1/evaluations/5273414928256991232', 'metricsSchemaUri':
<…>
'confidenceMetrics': [{'confidenceThreshold': 0.8, 'recall': 0.94666666, 'precision': 0.9726027},
<…>

Neste ponto, estamos prontos para o próximo passo — Implantar o modelo em uma API para usar o modelo de verdade.

Implantando o modelo treinado em uma API na cloud

Com as facilidades que a Vertex AI oferece, a implantação do modelo AutoML em uma API se baseia na execução de um único comando:

endpoint = model.deploy()

Após alguns minutos, a API estará disponível para receber chamadas REST e realizar inferências no seu modelo recém treinado.

Realizando inferências com a API do modelo

Para realizar a inferência, iremos utilizar uma imagem do dataset de Stanford que não foi utilizada no processo de treinamento. É importante que seja uma imagem não vista pelo modelo, para que o modelo não utilize o conhecimento que ele já possui sobre a imagem e acabe acertando a inferência porque “decorou” a informação.

Iremos utilizar a imagem deste basset como teste:

Para realizar a inferência devemos:

Transformar a imagem em formato `base64`

Realizar a chamada REST na API que implantamos

Tratar os resultados da inferência.

Algo como abaixo — primeiro transformando a imagem em formato base64:

with open('./imgs/testimg.jpg', 'rb') as image_file:
imagem = base64.b64encode(image_file.read())

Após isso, vamos utilizar a SDK da Vertex AI e enviar a chamada REST de inferência:

instances = [{"content": imagem.decode("utf-8")}]
prediction = endpoint.predict(instances=instances)
E, finalmente, realizar o processamento da resposta da inferência (armazenada na variável "prediction"):
id_raca = prediction[0][0]['confidences']
id_raca = id_raca.index(max(prediction[0][0]['confidences']))
prediction[0][0]['displayNames'][id_raca]

'basset'

Parabéns!! chegando até aqui você:

criou um dataset gerenciado na Vertex AI

treinou um modelo de machine learning, em uma abordagem low code, utilizando o AutoML

fez a implantação desse modelo em uma API

realizou inferências com esse modelo

Você gostou do conteúdo e quer replicar o código em seu ambiente? Sem problemas!! Basta seguir as etapas presentes neste repositório no github.

Um abraço e até a próxima!

--

--