Como usar o ajuste de hiperparâmetro

Nesta página, você verá como usar o ajuste de hiperparâmetro do AI Platform Training ao treinar seu modelo. O ajuste de hiperparâmetro otimiza uma variável desejada, especificada por você. Essa variável é chamada de métrica de hiperparâmetro. Ao iniciar um job com o ajuste de hiperparâmetro, você precisa estabelecer o nome da métrica, que é o nome atribuído por você ao resumo escalar a ser adicionado ao treinador.

Etapas envolvidas no ajuste de hiperparâmetro

Para usar o ajuste de hiperparâmetro em um job de treinamento, é necessário realizar as etapas a seguir:

  1. Especifique a configuração do ajuste de hiperparâmetro para o job de treinamento incluindo HyperparameterSpec no objeto TrainingInput.

  2. Inclua o código a seguir no aplicativo de treinamento:

    • Analise os argumentos de linha de comando que representam os hiperparâmetros que você quer ajustar. Use os valores para definir os hiperparâmetros no teste de treinamento.
    • Adicione sua métrica de hiperparâmetro ao resumo do gráfico.

Veja abaixo mais detalhes de cada etapa.

Especificar a configuração do ajuste de hiperparâmetro para o job de treinamento

Crie um objeto HyperparameterSpec para armazenar a configuração do ajuste de hiperparâmetro para o job de treinamento. Inclua HyperparameterSpec como o objeto hyperparameters no objeto TrainingInput.

O job de ajuste de hiperparâmetros criará jobs de teste. Se você quiser acelerar o processo do job de teste de treinamento, especifique um tipo de máquina personalizado no objeto TrainingInput. Por exemplo, para criar jobs de teste com cada job de teste usando VMs n1-standard-8, especifique masterType como n1-standard-8 e deixe a configuração do worker vazia.

Em HyperparameterSpec, defina hyperparameterMetricTag como um valor que represente a métrica escolhida por você. Se você não especificar um hyperparameterMetricTag, o AI Platform Training procurará uma métrica com o nome training/hptuning/metric. No exemplo a seguir, veja como criar uma configuração para uma métrica chamada metric1:

gcloud

Adicione as informações de configuração do hiperparâmetro ao arquivo YAML da configuração. Veja um exemplo abaixo. Para um arquivo de configuração ativo, consulte hptuning_config.yaml (em inglês) na amostra do estimador de censo.

trainingInput:
  scaleTier: CUSTOM
  masterType: complex_model_m
  workerType: complex_model_m
  parameterServerType: large_model
  workerCount: 9
  parameterServerCount: 3
  hyperparameters:
    goal: MAXIMIZE
    hyperparameterMetricTag: metric1
    maxTrials: 30
    maxParallelTrials: 1
    enableTrialEarlyStopping: True
    params:
    - parameterName: hidden1
      type: INTEGER
      minValue: 40
      maxValue: 400
      scaleType: UNIT_LINEAR_SCALE
    - parameterName: numRnnCells
      type: DISCRETE
      discreteValues:
      - 1
      - 2
      - 3
      - 4
    - parameterName: rnnCellType
      type: CATEGORICAL
      categoricalValues:
      - BasicLSTMCell
      - BasicRNNCell
      - GRUCell
      - LSTMCell
      - LayerNormBasicLSTMCell

Python

Crie um dicionário que represente seu HyperparameterSpec e adicione-o à entrada de treinamento. No exemplo a seguir, pressupomos que você já tenha criado um dicionário TrainingInput, chamado de training_inputs nesse caso, como demonstrado no guia de configuração do job de treinamento.

# Add hyperparameter tuning to the job config.
hyperparams = {
    'goal': 'MAXIMIZE',
    'hyperparameterMetricTag': 'metric1',
    'maxTrials': 30,
    'maxParallelTrials': 1,
    'enableTrialEarlyStopping': True,
    'params': []}

hyperparams['params'].append({
    'parameterName':'hidden1',
    'type':'INTEGER',
    'minValue': 40,
    'maxValue': 400,
    'scaleType': 'UNIT_LINEAR_SCALE'})

hyperparams['params'].append({
    'parameterName':'numRnnCells',
    'type':'DISCRETE',
    'discreteValues': [1, 2, 3, 4]})

hyperparams['params'].append({
    'parameterName':'rnnCellType',
    'type': 'CATEGORICAL',
    'categoricalValues': [
        'BasicLSTMCell',
        'BasicRNNCell',
        'GRUCell',
        'LSTMCell',
        'LayerNormBasicLSTMCell'
    ]
})

# Add hyperparameter specification to the training inputs dictionary.
training_inputs['hyperparameters'] = hyperparams

# Build the job spec.
job_spec = {'jobId': my_job_name, 'trainingInput': training_inputs}

Verifique o código no aplicativo de treinamento

Em seu aplicativo, manipule os argumentos de linha de comando para os hiperparâmetros e relate sua métrica de hiperparâmetro para o AI Platform Training.

Gerencie os argumentos de linha de comando para os hiperparâmetros que serão ajustados

O AI Platform Training define os argumentos de linha de comando quando chama o aplicativo de treinamento. Use os argumentos de linha de comando em seu código:

  1. Defina um nome para cada argumento de hiperparâmetro e analise usando o analisador de argumentos de sua preferência (geralmente argparse). Os nomes dos argumentos precisam coincidir com os nomes de parâmetro que você especificou na configuração do job, conforme descrito acima.

  2. Atribua os valores dos argumentos de linha de comando aos hiperparâmetros em seu código de treinamento.

Informe sua métrica de hiperparâmetros para o AI Platform Training

A maneira de informar sua métrica de hiperparâmetros para o serviço AI Platform Training depende de se você estiver usando o TensorFlow para treinamento ou não. Isso também depende de se você estiver usando uma versão de ambiente de execução ou um contêiner personalizado para treinamento.

Recomendamos que o código de treinamento informe com frequência sua métrica de hiperparâmetros para o AI Platform Training para aproveitar o fechamento antecipado.

TensorFlow com uma versão de ambiente de execução

Se você usa o ambiente de execução da AI Platform Training e treina com o TensorFlow, informe sua métrica de hiperparâmetros no AI Platform Training, gravando a métrica em um resumo do TensorFlow. Use uma das seguintes funções:

O uso de uma API diferente do TensorFlow que chama uma das funções anteriores, como no exemplo de Estimator a seguir, também informa a métrica de hiperparâmetro para o AI Platform Training.

Os exemplos a seguir mostram as noções básicas de duas maneiras diferentes de gravar sua métrica de hiperparâmetros em um resumo. Os dois exemplos presumem que você esteja treinando um modelo de regressão e escrevem a raiz do erro médio quadrado entre os rótulos de informações empíricas e as previsões de avaliação como uma métrica de hiperparâmetros denominada metric1.

Keras

O exemplo a seguir usa um callback de Keras personalizado para gravar um resumo escalar ao final de cada época de treinamento:

class MyMetricCallback(tf.keras.callbacks.Callback):

    def on_epoch_end(self, epoch, logs=None):
        tf.summary.scalar('metric1', logs['RootMeanSquaredError'], epoch)

logdir = "logs/scalars/" + datetime.now().strftime("%Y%m%d-%H%M%S")
file_writer = tf.summary.create_file_writer(logdir + "/metrics")
file_writer.set_as_default()

model = tf.keras.Sequential(
    tf.keras.layers.Dense(1, activation='linear', input_dim=784))
model.compile(
    optimizer='rmsprop',
    loss='mean_squared_error',
    metrics=['RootMeanSquaredError'])

model.fit(
    x_train,
    y_train,
    batch_size=64,
    epochs=10,
    steps_per_epoch=5,
    verbose=0,
    callbacks=[MyMetricCallback()])

Estimator

O exemplo a seguir usa tf.estimator.add_metrics para adicionar a métrica de hiperparâmetros ao resumo do gráfico.

Os Estimators gravam um resumo do gráfico sempre que o método evaluate é executado. Este exemplo usa tf.estimator.EvalSpec com tf.estimator.train_and_evaluate para configurar o estimator para avaliar e gravar resumos a cada 300 segundos durante o treinamento.

# Create metric for hyperparameter tuning
def my_metric(labels, predictions):
    # Note that different types of estimator provide different different
    # keys on the predictions Tensor. predictions['predictions'] is for
    # regression output.
    pred_values = predictions['predictions']
    return {'metric1': tf.compat.v1.metrics.root_mean_squared_error(labels, pred_values)}

# Create estimator to train and evaluate
def train_and_evaluate(output_dir):

    estimator = tf.estimator.DNNLinearCombinedRegressor(...)

    estimator = tf.estimator.add_metrics(estimator, my_metric)

    train_spec = ...
    eval_spec = tf.estimator.EvalSpec(
        start_delay_secs = 60, # start evaluating after 60 seconds
        throttle_secs = 300,  # evaluate every 300 seconds
        ...)
    tf.estimator.train_and_evaluate(estimator, train_spec, eval_spec)

Outros frameworks de machine learning ou contêineres personalizados

Se você usa um contêiner personalizado para treinamento ou se quiser realizar o ajuste de hiperparâmetro com um framework que não seja o TensorFlow, use o pacote Python cloudml-hypertune para informar sua métrica de hiperparâmetro ao AI Platform Training.

Veja um exemplo de uso de cloudml-hypertune.

Como ver os detalhes de um job de ajuste de hiperparâmetro durante a execução

Para monitorar o ajuste de hiperparâmetro, receba o status detalhado do job de treinamento em execução.

O objeto TrainingOutput no recurso do job de resposta tem os seguintes valores configurados durante um job de treinamento com ajuste de hiperparâmetros:

  • isHyperparameterTuningJob definido como True.

  • trials está presente e contém uma lista de objetos HyperparameterOutput, um por teste.

Também é possível recuperar o ID de teste da variável de ambiente TF_CONFIG. Consulte o guia para ver detalhes sobre TF_CONFIG.

Como receber resultados do ajuste de hiperparâmetro

Quando as execuções de treinamento forem concluídas, será possível ver os resultados de cada teste no console do Google Cloud. Se preferir, chame projects.jobs.get para ver os resultados. O objeto TrainingOutput no recurso do job contém as métricas de todas as execuções, incluindo as referentes às execuções com melhor ajuste identificadas.

Para receber essas informações, use a mesma solicitação de status detalhado utilizada para monitorar o job durante o processamento.

Você verá os resultados de cada teste na descrição do job. No console do Google Cloud, é possível filtrar testes por rmse, learning_rate e training steps. Encontre o teste que produziu o valor mais desejável para sua métrica de hiperparâmetro. Se o teste atender ao padrão para o sucesso do modelo, use os valores de hiperparâmetro mostrados nessa avaliação nas execuções subsequentes do modelo.

Às vezes, vários testes fornecem resultados idênticos para a métrica de ajuste. Nesse caso, determine os valores de hiperparâmetro mais vantajosos por outras medições. Por exemplo, se você estiver ajustando o número de nodes em uma camada oculta e receber resultados idênticos quando o valor está definido como 8 ou 20, use o valor 8 porque um número maior de nodes significa um aumento no processamento e no custo sem melhorias para seu modelo.

O estado de teste FAILED em HyperparameterOutput pode significar que o treinamento falhou para esse teste ou que o teste falhou ao relatar a métrica de ajuste de hiperparâmetro. No último caso, o job pai pode ser bem-sucedido mesmo se a avaliação falhar. Você pode ver o registro da avaliação para ver se o treinamento falhou.

Como definir um limite para o número de testes

Decida quantos testes o serviço poderá executar e defina o valor de maxTrials no objeto HyperparameterSpec.

Ao decidir o número permitido de testes, você deverá pensar em dois interesses conflitantes:

  • tempo (e, consequentemente, custo)
  • precisão

Aumentar o número de testes geralmente produz melhores resultados, mas nem sempre é assim. Na maioria dos casos, após um ponto de diminuição dos benefícios, qualquer teste adicional tem pouco ou nenhum efeito sobre a precisão. Talvez seja melhor começar com um número pequeno de testes para avaliar o efeito dos hiperparâmetros escolhidos na precisão do modelo, antes de iniciar um job com uma grande quantidade de testes.

Para aproveitar ao máximo o ajuste de hiperparâmetro, o valor máximo não pode ser inferior a 10 vezes o número de hiperparâmetros utilizados.

Como lidar com testes com falha

Se os testes de ajuste de hiperparâmetro forem encerrados com erros, convém encerrar o job de treinamento antecipadamente. Defina o campo maxFailedTrials no HyperparameterSpec como o número de testes com falha que você quer permitir. Depois que esse número de tentativas falhar, o AI Platform Training encerrará o job de treinamento. O valor de maxFailedTrials precisa ser menor ou igual ao de maxTrials.

Se você não definir maxFailedTrials, ou se definir como 0, o AI Platform Training usará as regras a seguir para lidar com testes com falha:

  • Se o primeiro teste de seu job falhar, o AI Platform Training encerrará o trabalho imediatamente. A falha durante o primeiro teste sugere um problema no código de treinamento. Portanto, outros testes provavelmente também falharão. O encerramento do job oferece a oportunidade de diagnosticar o problema sem esperar outros testes e de não gerar custos maiores.
  • Se a primeira avaliação for bem-sucedida, o AI Platform Training poderá encerrar o job após falhas durante as avaliações subsequentes com base em um dos seguintes critérios:
    • O número de testes com falha aumentou muito.
    • A proporção entre testes com falha e testes bem-sucedidos aumentou muito.

Esses limites internos estão sujeitos a alterações. Para garantir um comportamento específico, defina o campo maxFailedTrials.

Como executar testes em paralelo

É possível especificar um número de testes a serem executados em paralelo definindo maxParallelTrials no objeto HyperparameterSpec.

A execução de testes em paralelo tem a vantagem de reduzir a duração do job de treinamento (tempo real, o tempo de processamento necessário total geralmente não é alterado). No entanto, a execução em paralelo pode reduzir a eficácia do job de ajuste em geral. Isso ocorre porque o ajuste de hiperparâmetro usa os resultados de testes anteriores para informar os valores a serem atribuídos aos hiperparâmetros de testes subsequentes. Quando executados em paralelo, alguns testes são iniciados sem a vantagem de usar os resultados dos testes ainda em execução.

Quando você usa testes em paralelo, o serviço de treinamento provisiona vários clusters de processamento de treinamento (ou várias máquinas individuais, no caso de um treinador de processo único). O nível de escalonamento definido por você para o job é usado para cada cluster de treinamento individual.

Como antecipar a interrupção de testes

É possível especificar que o AI Platform Training interrompa automaticamente um teste que se tornou claramente não promissor. Isso economiza o custo de continuar um teste que provavelmente não será útil.

Para permitir a interrupção antecipada de um teste, defina o valor enableTrialEarlyStopping em HyperparameterSpec como TRUE.

Como retomar um job de ajuste de hiperparâmetro concluído

Você pode retomar um job de ajuste de hiperparâmetro concluído para iniciar a partir de um estado parcialmente otimizado. Isso permite reutilizar o conhecimento adquirido no job de ajuste de hiperparâmetro anterior.

Para retomar um job de ajuste de hiperparâmetro, envie um novo job desse tipo com a configuração a seguir:

  • Defina o valor resumePreviousJobId no HyperparameterSpec como o código da tarefa do teste anterior.
  • Especifique valores para maxTrials e maxParallelTrials.

O AI Platform Training usará o código da tarefa anterior para encontrar e reutilizar os mesmos valores de goal, params e hyperparameterMetricTag e, assim, continuar o job de ajuste de hiperparâmetro.

Use nomes de hyperparameterMetricTag e params consistentes em jobs semelhantes, mesmo se os jobs tiverem parâmetros diferentes. Essa prática possibilita que o AI Platform Training melhore a otimização ao longo do tempo.

Nos exemplos a seguir, você verá o uso da configuração resumePreviousJobId:

gcloud

trainingInput:
  scaleTier: CUSTOM
  masterType: complex_model_m
  workerType: complex_model_m
  parameterServerType: large_model
  workerCount: 9
  parameterServerCount: 3
  hyperparameters:
    enableTrialEarlyStopping: TRUE
    maxTrials: 30
    maxParallelTrials: 1
    resumePreviousJobId: [PREVIOUS_JOB_IDENTIFIER]

Python

# Add hyperparameter tuning to the job config.
hyperparams = {
    'enableTrialEarlyStopping': True,
    'maxTrials': 30,
    'maxParallelTrials': 1,
    'resumePreviousJobId': [PREVIOUS_JOB_IDENTIFIER]}

# Add the hyperparameter specification to the training inputs dictionary.
training_inputs['hyperparameters'] = hyperparams

# Build the job spec.
job_spec = {'jobId': my_job_name, 'trainingInput': training_inputs}

Ajuste de hiperparâmetro com o Cloud TPU

Se você estiver executando o job de ajuste de hiperparâmetro com o Cloud TPU no AI Platform Training, a prática recomendada é usar a propriedade eval_metrics em TPUEstimatorSpec (em inglês).

Consulte a amostra de ajuste de hiperparâmetro da TPU ResNet-50 para um exemplo prático de ajuste de hiperparâmetro com a Cloud TPU.

Em vez de usar a propriedade eval_metrics para o serviço de ajuste de hiperparâmetro, uma alternativa é chamar tf.summary em host_call. Para detalhes, consulte TPUEstimatorSpec.

A seguir