Usa el ajuste de hiperparámetros

En esta página se muestra cómo usar el ajuste de hiperparámetros de AI Platform Training para entrenar tu modelo. El ajuste de hiperparámetros optimiza una variable de destino que especificaste. La variable de destino se llama métrica de hiperparámetro. Cuando inicias un trabajo con ajuste de hiperparámetros, debes establecer el nombre de tu métrica de hiperparámetro. Este es el nombre que asignas al resumen escalar que agregas a tu entrenador.

Pasos del ajuste de hiperparámetros

Para usar el ajuste de hiperparámetros en tu trabajo de entrenamiento, debes realizar los siguientes pasos:

  1. Especifica la configuración del ajuste de hiperparámetros en el trabajo de entrenamiento. Para ello, agrega un HyperparameterSpec al objeto TrainingInput.

  2. Incluye el siguiente código en tu aplicación de entrenamiento:

    • Analiza los argumentos de la línea de comandos que representan los hiperparámetros que deseas ajustar y usa los valores para establecer los hiperparámetros en tu prueba de entrenamiento.
    • Agrega tu métrica de hiperparámetro al resumen de tu grafo.

A continuación, se presentan más detalles de cada paso.

Especifica la configuración del ajuste de hiperparámetros en tu trabajo de entrenamiento

Crea un objeto HyperparameterSpec para conservar la configuración del ajuste de hiperparámetros del trabajo de entrenamiento y agrega el HyperparameterSpec como el objeto hyperparameters al objeto TrainingInput.

En tu HyperparameterSpec, establece hyperparameterMetricTag en un valor que represente la métrica elegida. Si no especificas una hyperparameterMetricTag, AI Platform Training buscará una métrica con el nombre training/hptuning/metric. En el siguiente ejemplo, se muestra cómo crear una configuración para una métrica llamada metric1:

gcloud

Agrega la información de configuración de hiperparámetros a tu archivo YAML de configuración. A continuación, se muestra un ejemplo. Para obtener un archivo de configuración que funcione, consulta hptuning_config.yaml en la muestra del 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

Crea un diccionario que represente tu HyperparameterSpec y agrégalo a tu información de entrenamiento. En el siguiente ejemplo, se supone que ya creaste un diccionario TrainingInput (en este caso, se llama training_inputs), como se muestra en la guía de configuración de trabajos de entrenamiento.

# 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}

Comprueba el código en tu aplicación de entrenamiento

En tu aplicación, controla los argumentos de la línea de comandos para los hiperparámetros y, luego, informa la métrica de hiperparámetro a AI Platform Training.

Controla los argumentos de la línea de comandos de los hiperparámetros que deseas ajustar

AI Platform Training establece argumentos de la línea de comandos cuando llama a la aplicación de entrenamiento. Usa los argumentos de la línea de comandos en tu código:

  1. Define un nombre para cada argumento de hiperparámetro y analízalo mediante cualquier analizador de argumentos que prefieras (por lo general, argparse). Los nombres de los argumentos deben coincidir con los nombres de los parámetros que especificaste en la configuración del trabajo, como se describió antes.

  2. Asigna los valores de los argumentos de la línea de comandos a los hiperparámetros en el código de entrenamiento.

Informa la métrica de hiperparámetro a AI Platform Training

La manera de informar la métrica de hiperparámetro al servicio de AI Platform Training depende de si usas TensorFlow para el entrenamiento o no. También depende de si usas una versión del entorno de ejecución o un contenedor personalizado para el entrenamiento.

Recomendamos que el código de entrenamiento informe la métrica de hiperparámetro a AI Platform Training con frecuencia para aprovechar la interrupción anticipada.

TensorFlow con una versión del entorno de ejecución

Si usas una versión del entorno de ejecución de AI Platform Training y entrenas con TensorFlow, puedes informar la métrica de hiperparámetro a AI Platform Training si la escribes en un resumen de TensorFlow. Usa una de las siguientes funciones:

Mediante una API de TensorFlow diferente que llame a una de las funciones anteriores, como en el siguiente ejemplo de Estimador, también se informa la métrica de hiperparámetro a AI Platform Training.

En los siguientes ejemplos, se muestran los conceptos básicos de dos formas diferentes de escribir la métrica de hiperparámetro en un resumen. En ambos ejemplos se supone que entrenas un modelo de regresión, y se escribe la raíz cuadrada del error cuadrático medio entre las etiquetas de verdad fundamental y las predicciones de evaluación como una métrica de hiperparámetro llamada metric1.

Keras

En el siguiente ejemplo, se usa una devolución de llamada personalizada de Keras para escribir un resumen escalar al final de cada ciclo de entrenamiento:

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()])

Estimador

En el siguiente ejemplo, se usa tf.estimator.add_metrics para agregar la métrica de hiperparámetro al resumen del grafo.

Ten en cuenta que los Estimadores escriben un resumen del grafo cada vez que se ejecuta su método evaluate. En este ejemplo se usa tf.estimator.EvalSpec con tf.estimator.train_and_evaluate a fin de configurar el Estimador para evaluar y escribir resúmenes cada 300 segundos durante el entrenamiento.

# 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)

Otros frameworks de aprendizaje automático o contenedores personalizados

Si usas un contenedor personalizado para el entrenamiento o si deseas realizar el ajuste de hiperparámetros con un framework que no sea TensorFlow, debes usar el paquete cloudml-hypertune de Python a fin de informar la métrica de hiperparámetro en AI Platform Training.

Consulta un ejemplo del uso de cloudml-hypertune.

Obtén detalles de un trabajo de ajuste de hiperparámetros mientras se ejecuta

Puedes supervisar el ajuste de hiperparámetros si obtienes el estado detallado de tu trabajo de entrenamiento en ejecución.

El objeto TrainingOutput en el recurso Job de la respuesta tiene los siguientes valores configurados durante un trabajo de entrenamiento con ajuste de hiperparámetros:

  • isHyperparameterTuningJob está establecido en True.

  • trials está presente y contiene una lista de objetos HyperparameterOutput, uno por prueba.

También puedes recuperar el ID de prueba de la variable de entorno TF_CONFIG. Consulta la guía para obtener detalles de TF_CONFIG.

Obtén resultados del ajuste de hiperparámetros

Cuando finaliza la ejecución del entrenamiento, puedes ver los resultados de cada prueba en Cloud Console. También puedes llamar a projects.jobs.get para obtener los resultados. El objeto TrainingOutput del recurso de trabajo contiene las métricas para todas las ejecuciones y se identifican las métricas de la ejecución mejor ajustada.

Usa la misma solicitud de estado detallado que usas a fin de supervisar el trabajo durante el procesamiento para obtener esta información.

Puedes ver los resultados de cada prueba en la descripción del trabajo. En Cloud Console, puedes filtrar las pruebas por rmse, learning_rate y training steps. Busca la prueba que produjo el valor más conveniente para tu métrica de hiperparámetro. Si la prueba cumple con tu estándar para el éxito del modelo, puedes usar los valores de hiperparámetro que se muestran en esa prueba en las ejecuciones posteriores de tu modelo.

A veces, varias pruebas dan resultados idénticos para tu métrica de ajuste. En tal caso, debes determinar cuáles de los valores del hiperparámetro son más ventajosos en otras medidas. Por ejemplo, si ajustas la cantidad de nodos en una capa oculta y obtienes resultados idénticos cuando el valor está establecido en 8 que cuando está establecido en 20, debes usar 8, porque más nodos significa más procesamiento y costo sin ninguna mejora en tu modelo

El estado de prueba FAILED en HyperparameterOutput puede significar que el entrenamiento falló para esa prueba o que la prueba no pudo informar la métrica de ajuste de hiperparámetros. En el último caso, el trabajo principal puede tener éxito incluso si falla la prueba. Puedes ver el registro de prueba para ver si el entrenamiento falló.

Establece un límite para la cantidad de intentos

Debes decidir cuántas pruebas quieres que ejecute el servicio y configurar el valor maxTrials en el objeto HyperparameterSpec.

Hay dos intereses que compiten entre sí y que se deben tener en cuenta cuando decides cuántas pruebas se deben permitir:

  • tiempo (y en consecuencia costo)
  • precisión

Por lo general, aumentar la cantidad de pruebas produce mejores resultados, pero no siempre es así. En la mayoría de los casos, hay un punto a partir del cual el rendimiento decrece, y las pruebas adicionales tienen poco o ningún efecto en la precisión. Es posible que la mejor opción sea comenzar con una pequeña cantidad de pruebas para evaluar el efecto que tienen los hiperparámetros que elegiste en la precisión de tu modelo, antes de comenzar un trabajo con una gran cantidad de pruebas.

Para aprovechar al máximo el ajuste del hiperparámetro, no debes establecer tu valor máximo inferior a diez veces la cantidad de hiperparámetros que usas.

Controla las pruebas con errores

Si las pruebas de ajuste de hiperparámetros generan errores, es posible que desees finalizar el trabajo de entrenamiento antes de tiempo. Configura el campo maxFailedTrials de HyperparameterSpec en la cantidad de pruebas con errores que deseas permitir. Una vez que se alcanza esta cantidad de pruebas con errores, AI Platform Training finaliza el trabajo de entrenamiento. El valor maxFailedTrials debe ser menor o igual que maxTrials.

Si no estableces el valor maxFailedTrials, o si lo estableces en 0, AI Platform Training usa las siguientes reglas para procesar las pruebas con errores:

  • Si la primera prueba de tu trabajo falla, AI Platform Training finaliza el trabajo de inmediato. Un error durante la primera prueba sugiere la existencia de un problema en tu código de entrenamiento, por lo que es probable que otras pruebas también fallen. Terminar el trabajo te permite diagnosticar el problema sin esperar más pruebas y, además, sin que se generen más costos.
  • Si la primera prueba se completa, AI Platform Training puede finalizar el trabajo después de que se generen errores durante pruebas posteriores según uno de los siguientes criterios:
    • La cantidad de pruebas con errores aumentó demasiado.
    • La proporción de pruebas con errores frente a pruebas exitosas aumentó demasiado.

Estos umbrales internos están sujetos a cambios. Para garantizar un comportamiento específico, configura el campo maxFailedTrials.

Ejecuta pruebas paralelas

Puedes especificar una cantidad de pruebas que se ejecutarán en paralelo si configuras maxParallelTrials en el objeto HyperparameterSpec.

La ejecución de pruebas paralelas tiene el beneficio de reducir el tiempo que toma el trabajo de entrenamiento (nos referimos al tiempo real, ya que el tiempo total de procesamiento requerido no suele cambiar). Sin embargo, ejecutar en paralelo puede reducir la efectividad del trabajo de ajuste en general. Esto se debe a que el ajuste de hiperparámetros usa los resultados de las pruebas anteriores para informar los valores que se les deben asignar a los hiperparámetros de las pruebas posteriores. Cuando se ejecutan en paralelo, algunas pruebas comienzan sin tener el beneficio de los resultados de cualquier prueba que aún se esté ejecutando.

Si usas pruebas paralelas, el servicio de capacitación aprovisiona varios clústeres de procesamiento de capacitación (o varias máquinas individuales en el caso de un entrenador de un solo proceso). El nivel de escala que establezcas para tu trabajo lo usa cada clúster de entrenamiento individual.

Detén las pruebas antes de tiempo

Puedes especificar que AI Platform Training detenga de manera automática una prueba que, sin dudas, se volvió poco prometedora. Esto te ahorra el costo de continuar una prueba que tiene pocas posibilidades de resultar útil.

Para permitir que una prueba se detenga antes de tiempo, establece el valor enableTrialEarlyStopping en el HyperparameterSpec como TRUE.

Reanuda un trabajo de ajuste de hiperparámetros que se completó

Puedes continuar un trabajo de ajuste de hiperparámetros que ya se completó para comenzar desde un estado que está optimizado de forma parcial. De este modo, puedes reutilizar el conocimiento adquirido en el trabajo de ajuste de hiperparámetros anterior.

Para reanudar un trabajo de ajuste de hiperparámetros, envía uno nuevo con la siguiente configuración:

  • Establece el valor resumePreviousJobId en el HyperparameterSpec como el ID del trabajo de la prueba anterior.
  • Especifica los valores de maxTrials y maxParallelTrials.

AI Platform Training usa el ID del trabajo anterior para buscar y volver a usar los mismos valores de goal, params y hyperparameterMetricTag a fin de continuar con el trabajo de ajuste de hiperparámetros.

Usa nombres de hyperparameterMetricTag y params coherentes para trabajos similares, incluso cuando los trabajos tengan parámetros diferentes. Esta práctica permite que AI Platform Training mejore la optimización con el tiempo.

En los siguientes ejemplos, se muestra el uso de la configuración 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}

Ajusta el hiperparámetro con Cloud TPU

Si ejecutas el trabajo de ajuste de hiperparámetros mediante Cloud TPU en AI Platform Training, la práctica recomendada es usar la propiedad eval_metrics en TPUEstimatorSpec.

Consulta la muestra de ajuste de hiperparámetros de TPU de ResNet-50 para ver un ejemplo práctico de ajuste de hiperparámetros con Cloud TPU.

En lugar de recurrir a la propiedad eval_metrics para usar el servicio de ajuste de hiperparámetros, una alternativa es llamar a tf.summary in host_call. Para obtener detalles, consulta TPUEstimatorSpec.

Próximos pasos