1. Visão geral
Neste laboratório, você usará a Vertex AI para executar um job de ajuste de hiperparâmetros para um modelo do TensorFlow. Embora este laboratório use o TensorFlow para o código do modelo, os conceitos também são aplicáveis a outros frameworks de ML.
Conteúdo do laboratório
Você aprenderá como realizar as seguintes tarefas:
- Modificar código do aplicativo de treinamento para ajuste automático de hiperparâmetros
- Configurar e iniciar um job de ajuste de hiperparâmetros na IU do Vertex AI
- Configurar e lançar um job de ajuste de hiperparâmetros com o Vertex AI Python SDK
O custo total da execução deste laboratório no Google Cloud é de aproximadamente US$3.
2. Introdução ao Vertex AI
Este laboratório usa a mais nova oferta de produtos de IA disponível no Google Cloud. A Vertex AI integra as ofertas de ML do Google Cloud em uma experiência de desenvolvimento intuitiva. Anteriormente, modelos treinados com o AutoML e modelos personalizados eram acessíveis por serviços separados. A nova oferta combina os dois tipos em uma única API, junto com outros produtos novos. Você também pode migrar projetos existentes para a Vertex AI. Se você tiver algum feedback, consulte a página de suporte.
A Vertex AI inclui vários produtos diferentes para dar suporte a fluxos de trabalho integrais de ML. Este laboratório aborda os produtos destacados abaixo: Treinamento e Workbench.
3. Configurar o ambiente
Para executar este codelab, você precisará de um projeto do Google Cloud Platform com o faturamento ativado. Para criar um projeto, siga estas instruções.
Etapa 1: ativar a API Compute Engine
Acesse o Compute Engine e selecione Ativar, caso essa opção ainda não esteja ativada. Você precisará dele para criar sua instância de notebook.
Etapa 2: ativar a API Container Registry
Navegue até o Container Registry e selecione Ativar. Use-o para criar um contêiner de job de treinamento personalizado.
Etapa 3: ativar a API Vertex AI
Navegue até a seção "Vertex AI" do Console do Cloud e clique em Ativar API Vertex AI.
Etapa 4: criar uma instância do Vertex AI Workbench
Na seção Vertex AI do Console do Cloud, clique em "Workbench":
Ative a API Notebooks se ela ainda não tiver sido ativada.
Após a ativação, clique em NOTEBOOK GERENCIADO:
Em seguida, selecione NOVO NOTEBOOK.
Dê um nome ao notebook e clique em Configurações avançadas.
Em "Configurações avançadas", ative o encerramento inativo e defina o número de minutos como 60. Isso significa que o notebook será desligado automaticamente quando não estiver sendo usado.
Em Segurança, selecione "Ativar terminal" se essa opção ainda não estiver ativada.
Você pode manter as outras configurações avançadas como estão.
Em seguida, clique em Criar. O provisionamento da instância levará alguns minutos.
Após a criação da instância, selecione Abrir o JupyterLab.
Na primeira vez que usar uma nova instância, você receberá uma solicitação para autenticar. Siga as etapas na IU para isso.
4. Conteinerizar o código do aplicativo de treinamento
O modelo que você treinará e ajustará neste laboratório é um modelo de classificação de imagens treinado no conjunto de dados de cavalos ou humanos a partir dos Conjuntos de dados do TensorFlow.
Para enviar o job de ajuste de hiperparâmetros para a Vertex AI, coloque o código do aplicativo de treinamento em um contêiner do Docker e envie-o para o Google Container Registry. Com essa abordagem, é possível ajustar hiperparâmetros para um modelo criado com qualquer framework.
Para começar, no menu "Launcher", abra uma janela de terminal na instância do notebook:
Crie um diretório chamado horses_or_humans
e use cd nele:
mkdir horses_or_humans
cd horses_or_humans
Etapa 1: criar um Dockerfile
A primeira etapa para inserir o código em contêiner é criar um Dockerfile. No Dockerfile, inclua todos os comandos necessários para executar a imagem. Ele instalará todas as bibliotecas necessárias, incluindo a biblioteca CloudML Hypertune, e definirá o ponto de entrada para o código de treinamento.
No seu terminal, crie um Dockerfile vazio:
touch Dockerfile
Abra o Dockerfile e copie o seguinte nele:
FROM gcr.io/deeplearning-platform-release/tf2-gpu.2-7
WORKDIR /
# Installs hypertune library
RUN pip install cloudml-hypertune
# Copies the trainer code to the docker image.
COPY trainer /trainer
# Sets up the entry point to invoke the trainer.
ENTRYPOINT ["python", "-m", "trainer.task"]
Esse Dockerfile usa a imagem do Docker do GPU Enterprise Contêiner do TensorFlow 2.7. Os contêineres de aprendizado profundo no Google Cloud vêm com muitos frameworks comuns de ML e ciência de dados pré-instalados. Após o download, o Dockerfile configura o ponto de entrada para o código de treinamento. Você ainda não criou esses arquivos. Na próxima etapa, você adicionará o código para treinar e ajustar o modelo.
Etapa 2: adicionar o código de treinamento de modelo
No seu terminal, execute o seguinte comando para criar um diretório para o código de treinamento e um arquivo Python em que você adicionará o código:
mkdir trainer
touch trainer/task.py
Agora você tem o seguinte no seu diretório horses_or_humans/
:
+ Dockerfile
+ trainer/
+ task.py
Em seguida, abra o arquivo task.py
que você acabou de criar e copie o código abaixo.
import tensorflow as tf
import tensorflow_datasets as tfds
import argparse
import hypertune
NUM_EPOCHS = 10
def get_args():
'''Parses args. Must include all hyperparameters you want to tune.'''
parser = argparse.ArgumentParser()
parser.add_argument(
'--learning_rate',
required=True,
type=float,
help='learning rate')
parser.add_argument(
'--momentum',
required=True,
type=float,
help='SGD momentum value')
parser.add_argument(
'--num_units',
required=True,
type=int,
help='number of units in last hidden layer')
args = parser.parse_args()
return args
def preprocess_data(image, label):
'''Resizes and scales images.'''
image = tf.image.resize(image, (150,150))
return tf.cast(image, tf.float32) / 255., label
def create_dataset():
'''Loads Horses Or Humans dataset and preprocesses data.'''
data, info = tfds.load(name='horses_or_humans', as_supervised=True, with_info=True)
# Create train dataset
train_data = data['train'].map(preprocess_data)
train_data = train_data.shuffle(1000)
train_data = train_data.batch(64)
# Create validation dataset
validation_data = data['test'].map(preprocess_data)
validation_data = validation_data.batch(64)
return train_data, validation_data
def create_model(num_units, learning_rate, momentum):
'''Defines and compiles model.'''
inputs = tf.keras.Input(shape=(150, 150, 3))
x = tf.keras.layers.Conv2D(16, (3, 3), activation='relu')(inputs)
x = tf.keras.layers.MaxPooling2D((2, 2))(x)
x = tf.keras.layers.Conv2D(32, (3, 3), activation='relu')(x)
x = tf.keras.layers.MaxPooling2D((2, 2))(x)
x = tf.keras.layers.Conv2D(64, (3, 3), activation='relu')(x)
x = tf.keras.layers.MaxPooling2D((2, 2))(x)
x = tf.keras.layers.Flatten()(x)
x = tf.keras.layers.Dense(num_units, activation='relu')(x)
outputs = tf.keras.layers.Dense(1, activation='sigmoid')(x)
model = tf.keras.Model(inputs, outputs)
model.compile(
loss='binary_crossentropy',
optimizer=tf.keras.optimizers.SGD(learning_rate=learning_rate, momentum=momentum),
metrics=['accuracy'])
return model
def main():
args = get_args()
train_data, validation_data = create_dataset()
model = create_model(args.num_units, args.learning_rate, args.momentum)
history = model.fit(train_data, epochs=NUM_EPOCHS, validation_data=validation_data)
# DEFINE METRIC
hp_metric = history.history['val_accuracy'][-1]
hpt = hypertune.HyperTune()
hpt.report_hyperparameter_tuning_metric(
hyperparameter_metric_tag='accuracy',
metric_value=hp_metric,
global_step=NUM_EPOCHS)
if __name__ == "__main__":
main()
Antes de criar o contêiner, vamos analisar o código mais a fundo. Há alguns componentes específicos para o uso do serviço de ajuste de hiperparâmetros.
- O script importa a biblioteca
hypertune
. O Dockerfile da etapa 1 incluiu instruções para instalar o pip com essa biblioteca. - A função
get_args()
define um argumento de linha de comando para cada hiperparâmetro que você quer ajustar. Neste exemplo, os hiperparâmetros que serão ajustados são a taxa de aprendizado, o valor do momento no otimizador e o número de unidades na última camada oculta do modelo, mas você pode testar outros. Em seguida, o valor transmitido nesses argumentos é usado para definir o hiperparâmetro correspondente no código. - No final da função
main()
, a bibliotecahypertune
é usada para definir a métrica que você quer otimizar. No TensorFlow, o métodomodel.fit
keras retorna um objetoHistory
. O atributoHistory.history
é um registro dos valores de perda e de métricas de treinamento em períodos sucessivos. Se você transmitir os dados de validação paramodel.fit
, o atributoHistory.history
também incluirá a perda de validação e os valores das métricas. Por exemplo, se você treinou um modelo por três períodos com dados de validação e forneceuaccuracy
como uma métrica, o atributoHistory.history
será semelhante ao dicionário a seguir.
{
"accuracy": [
0.7795261740684509,
0.9471358060836792,
0.9870933294296265
],
"loss": [
0.6340447664260864,
0.16712145507335663,
0.04546636343002319
],
"val_accuracy": [
0.3795261740684509,
0.4471358060836792,
0.4870933294296265
],
"val_loss": [
2.044623374938965,
4.100203514099121,
3.0728273391723633
]
Se você quiser que o serviço de ajuste de hiperparâmetros descubra os valores que maximizam a precisão da validação do modelo, defina a métrica como a última entrada (ou NUM_EPOCS - 1
) da lista val_accuracy
. Depois, transmita essa métrica para uma instância do HyperTune
. Você pode escolher a string que preferir para o hyperparameter_metric_tag
, mas precisará usá-la novamente quando iniciar o job de ajuste de hiperparâmetros.
Etapa 3: criar o contêiner
No terminal, execute o seguinte para definir uma variável de ambiente para seu projeto, substituindo your-cloud-project
pelo ID do projeto:
PROJECT_ID='your-cloud-project'
Defina uma variável com o URI da imagem do contêiner no Google Container Registry:
IMAGE_URI="gcr.io/$PROJECT_ID/horse-human:hypertune"
Em seguida, crie o contêiner executando a seguinte linha a partir da raiz do diretório horses_or_humans
:
docker build ./ -t $IMAGE_URI
Por fim, envie-o para o Google Container Registry:
docker push $IMAGE_URI
Com o contêiner enviado para o Container Registry, está tudo pronto para iniciar um job de ajuste de hiperparâmetros de modelo personalizado.
5. Executar um job de ajuste de hiperparâmetros no Vertex AI
Este laboratório usa treinamento personalizado com um contêiner personalizado no Google Container Registry, mas também é possível executar um job de ajuste de hiperparâmetros com um contêiner pré-criado do Vertex AI.
Para começar, navegue até a seção Training na seção "Vertex" do Console do Cloud:
Etapa 1: configurar o job de treinamento
Clique em Criar para inserir os parâmetros do job de ajuste de hiperparâmetros.
- Em Conjunto de dados, selecione Nenhum conjunto de dados gerenciado.
- Em seguida, selecione Treinamento personalizado (avançado) como o método de treinamento e clique em Continuar.
- Insira
horses-humans-hyptertune
(ou o nome que você quer atribuir ao modelo) em Nome do modelo - Clique em Continuar
Na etapa "Configurações do contêiner", selecione Contêiner personalizado:
Na primeira caixa (Imagem do contêiner), insira o valor da variável IMAGE_URI
da seção anterior. Ele precisa ser: gcr.io/your-cloud-project/horse-human:hypertune
, com o nome do seu projeto. Deixe os outros campos em branco e clique em Continuar.
Etapa 2: configurar o job de ajuste de hiperparâmetros
Selecione Ativar ajuste de hiperparâmetros.
Configurar hiperparâmetros
Em seguida, você precisará adicionar os hiperparâmetros definidos como argumentos de linha de comando no código do aplicativo de treinamento. Ao adicionar um hiperparâmetro, primeiro é necessário informar o nome dele. Ele precisa corresponder ao nome do argumento que você transmitiu para argparse
.
Em seguida, você selecionará o tipo e os limites dos valores que o serviço de ajuste tentará. Se você selecionar o tipo "Duplo" ou "Inteiro", precisará fornecer um valor mínimo e máximo. E, se você selecionar "Categórica" ou "Diversa", precisará fornecer os valores.
Para os tipos duplo e inteiro, você também precisa fornecer o valor de escalonamento.
Depois de adicionar o hiperparâmetro learning_rate
, adicione os parâmetros para momentum
e num_units
.
Configurar métrica
Depois de adicionar os hiperparâmetros, forneça a métrica que você quer otimizar e a meta. Precisa ser igual ao hyperparameter_metric_tag
definido no aplicativo de treinamento.
O serviço de ajuste de hiperparâmetros do Vertex AI executará vários testes do aplicativo de treinamento com os valores configurados nas etapas anteriores. Você precisará estabelecer um limite superior para o número de testes que o serviço executará. Mais testes geralmente levam a melhores resultados, mas haverá um ponto de redução de retornos após o qual os testes adicionais terão pouco ou nenhum efeito sobre a métrica que você está tentando otimizar. É recomendável começar com um número menor de testes e ter uma ideia do impacto dos hiperparâmetros escolhidos antes de expandir para um grande número de testes.
Também será necessário definir um limite superior para o número de testes paralelos. Aumentar o número de testes em paralelo reduzirá o tempo de execução do job de ajuste de hiperparâmetros. mas isso pode reduzir a eficácia da vaga em geral. Isso ocorre porque a estratégia de ajuste padrão usa os resultados de testes anteriores para informar a atribuição de valores nos testes subsequentes. Se você fizer muitos testes em paralelo, haverá testes sem o benefício do resultado dos testes em execução.
Para fins de demonstração, é possível definir o número de testes em 15 e o máximo de 3. Você pode fazer experimentos com números diferentes, mas isso pode resultar em um tempo de ajuste mais longo e custos mais altos.
A última etapa é selecionar "Padrão" como o algoritmo de pesquisa, que usará o Google Vizier para fazer a otimização bayesiana para o ajuste de hiperparâmetros. Saiba mais sobre esse algoritmo neste link.
Clique em Continuar.
Etapa 3: configurar a computação
Em Computação e preços, mantenha a região selecionada e configure o Pool de workers 0 da seguinte maneira.
Clique em Iniciar treinamento para iniciar o job de ajuste de hiperparâmetros. Na seção "Training" do seu console, na guia HYPERPARAMETER TUNING JOBS, você verá algo semelhante a isto:
Quando esse processo for concluído, você poderá clicar no nome do job e ver os resultados dos testes de ajuste.
Parabéns! 🎉
Você aprendeu a usar a Vertex AI para:
- iniciar um job de ajuste de hiperparâmetros para código de treinamento fornecido em um contêiner personalizado. Neste exemplo, você usou um modelo do TensorFlow, mas é possível treinar um modelo criado com qualquer framework usando contêineres personalizados.
Para saber mais sobre diferentes partes do Vertex, confira a documentação.
6. [Opcional] Usar o SDK do Vertex
A seção anterior mostrou como iniciar o job de ajuste de hiperparâmetros por meio da IU. Nesta seção, você verá uma maneira alternativa de enviar o job de ajuste de hiperparâmetros usando a API Vertex Python.
No acesso rápido, crie um notebook do TensorFlow 2.
Importe o SDK da Vertex AI.
from google.cloud import aiplatform
from google.cloud.aiplatform import hyperparameter_tuning as hpt
Para iniciar o job de ajuste de hiperparâmetros, primeiro defina as especificações a seguir. Será necessário substituir {PROJECT_ID}
no image_uri
pelo seu projeto.
# The spec of the worker pools including machine type and Docker image
# Be sure to replace PROJECT_ID in the `image_uri` with your project.
worker_pool_specs = [{
"machine_spec": {
"machine_type": "n1-standard-4",
"accelerator_type": "NVIDIA_TESLA_V100",
"accelerator_count": 1
},
"replica_count": 1,
"container_spec": {
"image_uri": "gcr.io/{PROJECT_ID}/horse-human:hypertune"
}
}]
# Dictionary representing metrics to optimize.
# The dictionary key is the metric_id, which is reported by your training job,
# And the dictionary value is the optimization goal of the metric.
metric_spec={'accuracy':'maximize'}
# Dictionary representing parameters to optimize.
# The dictionary key is the parameter_id, which is passed into your training
# job as a command line argument,
# And the dictionary value is the parameter specification of the metric.
parameter_spec = {
"learning_rate": hpt.DoubleParameterSpec(min=0.001, max=1, scale="log"),
"momentum": hpt.DoubleParameterSpec(min=0, max=1, scale="linear"),
"num_units": hpt.DiscreteParameterSpec(values=[64, 128, 512], scale=None)
}
Em seguida, crie um CustomJob
. Será necessário substituir {YOUR_BUCKET}
por um bucket no seu projeto para preparo.
# Replace YOUR_BUCKET
my_custom_job = aiplatform.CustomJob(display_name='horses-humans-sdk-job',
worker_pool_specs=worker_pool_specs,
staging_bucket='gs://{YOUR_BUCKET}')
Em seguida, crie e execute o HyperparameterTuningJob
.
hp_job = aiplatform.HyperparameterTuningJob(
display_name='horses-humans-sdk-job',
custom_job=my_custom_job,
metric_spec=metric_spec,
parameter_spec=parameter_spec,
max_trial_count=15,
parallel_trial_count=3)
hp_job.run()
7. Limpeza
Como configuramos o notebook para expirar após 60 minutos de inatividade, não precisamos nos preocupar em desligar a instância. Para encerrar a instância manualmente, clique no botão "Stop" na seção "Vertex AI Workbench" do console. Se quiser excluir o notebook completamente, clique no botão Excluir.
Para excluir o bucket do Storage, use o menu de navegação do Console do Cloud, acesse o Storage, selecione o bucket e clique em "Excluir":