使用超参数调节

超参数是控制模型训练流程的变量,例如批量大小或深度神经网络中的隐藏层数。超参数调节通过在一系列试验中优化指标值来搜寻超参数值的最佳组合。指标是添加到训练程序中的标量摘要,例如模型准确率。

详细了解 Vertex AI 上的超参数调节。如需查看分步示例,请参阅 Vertex AI:超参数调节 Codelab

本页介绍如何执行以下操作:

准备训练应用

在超参数调节作业中,Vertex AI 使用不同的超参数集创建训练作业的试验,并使用您指定的指标评估试验的有效性。Vertex AI 将超参数值作为命令行参数传递给训练应用。要让 Vertex AI 评估试验的有效性,您的训练应用必须向 Vertex AI 告您的指标。

以下部分介绍了以下内容:

  • Vertex AI 如何将超参数传递给训练应用。
  • 将指标从训练应用传递给 Vertex AI 的选项。

如需详细了解在 Vertex AI 上运行自定义训练应用的要求,请参阅训练代码要求

处理要调节的超参数的命令行参数

Vertex AI 在调用您的训练应用时设置命令行参数。因此请在代码中使用命令行参数:

  1. 为每个超参数定义一个名称,并使用您喜欢的任何参数解析器(例如 argparse)对其进行解析。配置超参数训练作业时,请使用相同的参数名称。

    例如,如果您的训练应用是名为 my_trainer 的 Python 模块,并且您想要调整名为 learning_rate 的超参数,则 Vertex AI 会在每次试验中启动如下所示的命令:

    python3 -m my_trainer --learning_rate learning-rate-in-this-trial
    

    Vertex AI 确定 learning-rate-in-this-trial 并使用 learning_rate 参数传入它。

  2. 将命令行参数中的值分配给训练代码中的超参数。

详细了解解析命令行参数的要求

向 AI Platform 报告指标

如需向 Vertex AI 告您的指标,请使用 cloudml-hypertune Python 软件包。此库提供用于向 Vertex AI 告指标的辅助函数。

详细了解如何报告超参数指标

创建超参数调节作业

根据您要用于创建 HyperparameterTuningJob 的工具,选择以下标签页之一:

控制台

在 Google Cloud 控制台中,您无法直接创建 HyperparameterTuningJob 资源。但是,您可以创建一个创建 HyperparameterTuningJobTrainingPipeline 资源。

以下说明介绍了如何创建 TrainingPipeline,用于创建 HyperparameterTuningJob 且不执行其他操作。如果您想使用其他 TrainingPipeline 功能(例如使用托管数据集进行训练),请参阅创建训练流水线

  1. 在 Cloud 控制台的 Vertex AI 部分中,转到训练流水线页面。

    转到“训练流水线”

  2. 点击 创建以打开训练新模型窗格。

  3. 训练方法步骤中,指定以下设置:

    1. 数据集下拉列表中,选择无代管式数据集

    2. 选择自定义训练(高级)

    点击继续

  4. 模型详情步骤中,选择训练新模型训练新版本。如果您选择训练新模型,请为模型输入一个名称 MODEL_NAME。点击继续

  5. 训练容器步骤中,指定以下设置:

    1. 选择要使用预构建容器还是自定义容器进行训练。

    2. 根据您的选择,执行以下相应操作:

    3. Model output directory 字段中,您可以指定您有权访问的存储分区中的目录的 Cloud Storage URI。目录不需要已经存在。

      此值会在 baseOutputDirectory API 字段中传递给 Vertex AI,该字段设置训练应用在其运行时可以访问的几个环境变量

    4. 参数字段中,您可以视需要指定 Vertex AI 开始运行训练代码时要使用的参数。这些参数的行为因您使用的容器类型而异:

      • 如果您使用的是预构建容器,Vertex AI 会将参数作为命令行标志传递给 Python 模块

      • 如果您使用的是自定义容器,则 Vertex AI 会使用参数替换容器的 CMD 指令

    点击继续

  6. 超参数调节步骤中,选中启用超参数调节复选框,并指定以下设置:

    1. 新建超参数部分中,指定要调节的超参数的参数名称类型。配置您指定的其他超参数设置,具体取决于您指定的类型。

      详细了解超参数类型及其配置

    2. 如果要调整多个超参数,请点击添加新参数,然后在随即显示的新部分中重复上一步。

      对要调节的每个超参数重复此步骤。

    3. 要优化的指标字段和进球下拉列表中,指定其名称和目标要优化的指标

    4. 试验数量上限字段中,指定您希望 Vertex AI 为超参数调节作业运行的试验数上限

    5. 并行试验数上限字段中,指定允许 Vertex AI 同时运行的最大试验次数

    6. 搜索算法下拉列表中,指定供 Vertex AI 使用的搜索算法

    7. 忽略启用提前停止切换开关,该操作不起作用。

    点击继续

  7. 计算和价格步骤中,指定以下设置:

    1. 区域下拉列表中,选择一个支持自定义训练的区域

    2. 工作器池 0 部分中,指定用于训练的计算资源

      如果指定加速器,请确保所选加速器类型在所选区域可用

      如果您要执行分布式训练,则点击 Add more worker pools,并为您需要的每个额外工作器池指定一组额外的计算资源。

    点击继续

  8. 预测容器步骤中,选择 No prediction container

  9. 点击开始训练以启动自定义训练流水线。

gcloud

以下步骤展示了如何使用 Google Cloud CLI 来创建具有相对最低配置的 HyperparameterTuningJob。如需了解可用于此任务的所有配置选项,请参阅 gcloud ai hp-tuning-jobs create 命令HyperparameterTuningJob API 资源的参考文档。

  1. 创建一个名为 config.yaml 的 YAML 文件,其中包含您要为新的 HyerparameterTuningJob 指定的某些 API 字段:

    config.yaml
    studySpec:
      metrics:
      - metricId: METRIC_ID
        goal: METRIC_GOAL
      parameters:
      - parameterId: HYPERPARAMETER_ID
        doubleValueSpec:
          minValue: DOUBLE_MIN_VALUE
          maxValue: DOUBLE_MAX_VALUE
    trialJobSpec:
      workerPoolSpecs:
        - machineSpec:
            machineType: MACHINE_TYPE
          replicaCount: 1
          containerSpec:
            imageUri: CUSTOM_CONTAINER_IMAGE_URI
    

    替换以下内容:

    • METRIC_ID:要优化的超参数指标的名称。您的训练代码在运行时必须报告此指标

    • METRIC_GOAL:超参数指标的目标,即 MAXIMIZEMINIMIZE

    • HYPERPARAMETER_ID:要调节的超参数的名称。 您的训练代码必须使用此名称解析命令行标志。在此示例中,超参数必须采用浮点值。了解其他超参数数据类型

    • DOUBLE_MIN_VALUE:您希望 Vertex AI 尝试用于此超参数的最小值(数字)。

    • DOUBLE_MAX_VALUE:您希望 Vertex AI 尝试用于此超参数的最大值(数字)。

    • MACHINE_TYPE:用于训练的虚拟机类型

    • CUSTOM_CONTAINER_IMAGE_URI:包含训练代码的 Docker 容器映像的 URI。了解如何创建自定义容器映像

      在此示例中,您必须使用自定义容器。HyperparameterTuningJob 资源还支持在 Python 源代码发行版中训练代码,但不支持在自定义容器进行训练。

  2. config.yaml 文件所在的目录中,运行以下 shell 命令:

    gcloud ai hp-tuning-jobs create \
        --region=LOCATION \
        --display-name=DISPLAY_NAME \
        --max-trial-count=MAX_TRIAL_COUNT \
        --parallel-trial-count=PARALLEL_TRIAL_COUNT \
        --config=config.yaml
    

    替换以下内容:

REST 和命令行

通过以下代码示例使用 hyperparameterTuningJob 资源的 create 方法创建超参数调节作业。

在使用任何请求数据之前,请先进行以下替换:

  • LOCATION:要在其中创建 HyperparameterTuningJob 的区域。使用支持自定义训练的区域
  • PROJECT:您的项目 ID 或项目编号。
  • DISPLAY_NAME:您为 HyperparameterTuningJob 选择的容易记住的显示名。了解资源名称要求
  • 指定指标:
    • METRIC_ID:要优化的超参数指标的名称。您的训练代码在运行时必须报告此指标
    • METRIC_GOAL:超参数指标的目标,即 MAXIMIZEMINIMIZE
  • 指定超参数:
    • HYPERPARAMETER_ID:要调节的超参数的名称。 您的训练代码必须使用此名称解析命令行标志
    • PARAMETER_SCALE:(可选)应如何扩缩参数。不对分类参数进行设置。可以是 UNIT_LINEAR_SCALEUNIT_LOG_SCALEUNIT_REVERSE_LOG_SCALESCALE_TYPE_UNSPECIFIED
    • 如果此超参数的类型是 DOUBLE,请指定此超参数的最小值 (DOUBLE_MIN_VALUE) 和最大值 (DOUBLE_MAX_VALUE)。
    • 如果此超参数的类型是 INTEGER,请指定此超参数的最小值 (INTEGER_MIN_VALUE) 和最大值 (INTEGER_MAX_VALUE)。
    • 如果此超参数的类型是 CATEGORICAL,请指定可接受的值 (CATEGORICAL_VALUES) 作为字符串数组。
    • 如果此超参数的类型是 DISCRETE,则可接受的值 (DISCRETE_VALUES) 指定为数字数组。
    • 指定条件超参数。当父超参数的值与您指定的条件匹配时,条件超参数会添加到试验中。详细了解条件超参数
      • CONDITIONAL_PARAMETER:条件参数的 ParameterSpec。此规范包括参数的名称、容量、值范围以及依赖于此超参数的任何条件参数。
      • 如果父级超参数的类型为 INTEGER,请将整数列表指定为 INTEGERS_TO_MATCH。如果父超参数的值与指定的值之一,系统会将此条件参数添加到试验中。
      • 如果父级超参数的类型是 CATEGORICAL,请将类别列表指定为 CATEGORIES_TO_MATCH。如果父超参数的值与指定的值之一,系统会将此条件参数添加到试验中。
      • 如果父级超参数的类型为 DISCRETE,请将整数列表指定为 DISCRETE_VALUES_TO_MATCH。如果父超参数的值与指定的值之一,系统会将此条件参数添加到试验中。
  • ALGORITHM:(可选)在此超参数调节作业中使用的搜索算法。可以是 ALGORITHM_UNSPECIFIEDGRID_SEARCHRANDOM_SEARCH
  • MAX_TRIAL_COUNT运行的试验数上限
  • PARALLEL_TRIAL_COUNT并行运行的试验数上限
  • MAX_FAILED_TRIAL_COUNT:超参数调节作业失败前可能会失败的作业数量。
  • 定义试验自定义训练作业:
    • MACHINE_TYPE:用于训练的虚拟机类型
    • ACCELERATOR_TYPE:(可选)要附加到每个试验的加速器类型。
    • ACCELERATOR_COUNT:(可选)要附加到每个试验的加速器数量。
    • REPLICA_COUNT:每次试验要使用的工作器副本数。
    • 如果训练应用在自定义容器中运行,请指定以下内容:
      • CUSTOM_CONTAINER_IMAGE_URI:包含训练代码的 Docker 容器映像的 URI。了解如何创建自定义容器映像
      • CUSTOM_CONTAINER_COMMAND:(可选)启动容器时要调用的命令。此命令会替换容器的默认入口点。
      • CUSTOM_CONTAINER_ARGS:(可选)启动容器时要传递的参数。
    • 如果训练应用是在预构建容器中运行的 Python 软件包,请指定以下内容:
      • PYTHON_PACKAGE_EXECUTOR_IMAGE_URI:运行提供的 Python 软件包的容器映像的 URI。详细了解用于训练的预构建容器
      • PYTHON_PACKAGE_URIS:Python 软件包文件的 Cloud Storage 位置,这些文件是训练程序及其从属软件包。软件包 URI 的数量上限为 100。
      • PYTHON_MODULE:安装软件包后要运行的 Python 模块名称。
      • PYTHON_PACKAGE_ARGS:(可选)要传递给 Python 模块的命令行参数。
    • SERVICE_ACCOUNT:(可选)Vertex AI 将用于运行您的代码的服务帐号。详细了解如何关联自定义服务帐号
    • TIMEOUT:(可选)每次试验的最长运行时间。
  • 指定要应用于此超参数调节作业的任何标签的 LABEL_NAMELABEL_VALUE

HTTP 方法和网址:

POST https://LOCATION-aiplatform-googleapis.com/v1/projects/PROJECT/locations/LOCATION/hyperparameterTuningJobs

请求 JSON 正文:

{
  "displayName": DISPLAY_NAME,
  "studySpec": {
    "metrics": [
      {
        "metricId": METRIC_ID,
        "goal": METRIC_GOAL
      }
    ],
    "parameters": [
      {
        "parameterId": PARAMETER_ID,
        "scaleType": PARAMETER_SCALE,

        // Union field parameter_value_spec can be only one of the following:
        "doubleValueSpec": {
            "minValue": DOUBLE_MIN_VALUE,
            "maxValue": DOUBLE_MAX_VALUE
        },
        "integerValueSpec": {
            "minValue": INTEGER_MIN_VALUE,
            "maxValue": INTEGER_MAX_VALUE
        },
        "categoricalValueSpec": {
            "values": [
              CATEGORICAL_VALUES
            ]
        },
        "discreteValueSpec": {
            "values": [
              DISCRETE_VALUES
            ]
        }
        // End of list of possible types for union field parameter_value_spec.

        "conditionalParameterSpecs": [
            "parameterSpec": {
              CONDITIONAL_PARAMETER
            }

            // Union field parent_value_condition can be only one of the following:
            "parentIntValues": {
                "values": [INTEGERS_TO_MATCH]
            }
            "parentCategoricalValues": {
                "values": [CATEGORIES_TO_MATCH]
            }
            "parentDiscreteValues": {
                "values": [DISCRETE_VALUES_TO_MATCH]
            }
            // End of list of possible types for union field parent_value_condition.
        ]
      }
    ],
    "ALGORITHM": ALGORITHM
  },
  "maxTrialCount": MAX_TRIAL_COUNT,
  "parallelTrialCount": PARALLEL_TRIAL_COUNT,
  "maxFailedTrialCount": MAX_FAILED_TRIAL_COUNT,
  "trialJobSpec": {
      "workerPoolSpecs": [
        {
          "machineSpec": {
            "machineType": MACHINE_TYPE,
            "acceleratorType": ACCELERATOR_TYPE,
            "acceleratorCount": ACCELERATOR_COUNT
          },
          "replicaCount": REPLICA_COUNT,

          // Union field task can be only one of the following:
          "containerSpec": {
            "imageUri": CUSTOM_CONTAINER_IMAGE_URI,
            "command": [
              CUSTOM_CONTAINER_COMMAND
            ],
            "args": [
              CUSTOM_CONTAINER_ARGS
            ]
          },
          "pythonPackageSpec": {
            "executorImageUri": PYTHON_PACKAGE_EXECUTOR_IMAGE_URI,
            "packageUris": [
              PYTHON_PACKAGE_URIS
            ],
            "pythonModule": PYTHON_MODULE,
            "args": [
              PYTHON_PACKAGE_ARGS
            ]
          }
          // End of list of possible types for union field task.
        }
      ],
      "scheduling": {
        "TIMEOUT": TIMEOUT
      },
      "serviceAccount": SERVICE_ACCOUNT
  },
  "labels": {
    LABEL_NAME_1": LABEL_VALUE_1,
    LABEL_NAME_2": LABEL_VALUE_2
  }
}

如需发送您的请求,请展开以下选项之一:

您应会收到如下所示的 JSON 响应:

{
  "name": "projects/12345/locations/us-central1/hyperparameterTuningJobs/6789",
  "displayName": "myHyperparameterTuningJob",
  "studySpec": {
    "metrics": [
      {
        "metricId": "myMetric",
        "goal": "MINIMIZE"
      }
    ],
    "parameters": [
      {
        "parameterId": "myParameter1",
        "integerValueSpec": {
          "minValue": "1",
          "maxValue": "128"
        },
        "scaleType": "UNIT_LINEAR_SCALE"
      },
      {
        "parameterId": "myParameter2",
        "doubleValueSpec": {
          "minValue": 1e-07,
          "maxValue": 1
        },
        "scaleType": "UNIT_LINEAR_SCALE"
      }
    ],
    "ALGORITHM": "RANDOM_SEARCH"
  },
  "maxTrialCount": 20,
  "parallelTrialCount": 1,
  "trialJobSpec": {
    "workerPoolSpecs": [
      {
        "machineSpec": {
          "machineType": "n1-standard-4"
        },
        "replicaCount": "1",
        "pythonPackageSpec": {
          "executorImageUri": "us-docker.pkg.dev/vertex-ai/training/training-tf-cpu.2-1:latest",
          "packageUris": [
            "gs://my-bucket/my-training-application/trainer.tar.bz2"
          ],
          "pythonModule": "my-trainer.trainer"
        }
      }
    ]
  }
}

Java

如需了解如何安装和使用 Vertex AI 客户端库,请参阅 Vertex AI 客户端库。如需了解详情,请参阅 Vertex AI Java API 参考文档

import com.google.cloud.aiplatform.v1.AcceleratorType;
import com.google.cloud.aiplatform.v1.CustomJobSpec;
import com.google.cloud.aiplatform.v1.HyperparameterTuningJob;
import com.google.cloud.aiplatform.v1.JobServiceClient;
import com.google.cloud.aiplatform.v1.JobServiceSettings;
import com.google.cloud.aiplatform.v1.LocationName;
import com.google.cloud.aiplatform.v1.MachineSpec;
import com.google.cloud.aiplatform.v1.PythonPackageSpec;
import com.google.cloud.aiplatform.v1.StudySpec;
import com.google.cloud.aiplatform.v1.StudySpec.MetricSpec;
import com.google.cloud.aiplatform.v1.StudySpec.MetricSpec.GoalType;
import com.google.cloud.aiplatform.v1.StudySpec.ParameterSpec;
import com.google.cloud.aiplatform.v1.StudySpec.ParameterSpec.ConditionalParameterSpec;
import com.google.cloud.aiplatform.v1.StudySpec.ParameterSpec.ConditionalParameterSpec.DiscreteValueCondition;
import com.google.cloud.aiplatform.v1.StudySpec.ParameterSpec.DiscreteValueSpec;
import com.google.cloud.aiplatform.v1.StudySpec.ParameterSpec.DoubleValueSpec;
import com.google.cloud.aiplatform.v1.StudySpec.ParameterSpec.ScaleType;
import com.google.cloud.aiplatform.v1.WorkerPoolSpec;
import java.io.IOException;
import java.util.Arrays;

public class CreateHyperparameterTuningJobPythonPackageSample {

  public static void main(String[] args) throws IOException {
    // TODO(developer): Replace these variables before running the sample.
    String project = "PROJECT";
    String displayName = "DISPLAY_NAME";
    String executorImageUri = "EXECUTOR_IMAGE_URI";
    String packageUri = "PACKAGE_URI";
    String pythonModule = "PYTHON_MODULE";
    createHyperparameterTuningJobPythonPackageSample(
        project, displayName, executorImageUri, packageUri, pythonModule);
  }

  static void createHyperparameterTuningJobPythonPackageSample(
      String project,
      String displayName,
      String executorImageUri,
      String packageUri,
      String pythonModule)
      throws IOException {
    JobServiceSettings settings =
        JobServiceSettings.newBuilder()
            .setEndpoint("us-central1-aiplatform.googleapis.com:443")
            .build();
    String location = "us-central1";

    // Initialize client that will be used to send requests. This client only needs to be created
    // once, and can be reused for multiple requests. After completing all of your requests, call
    // the "close" method on the client to safely clean up any remaining background resources.
    try (JobServiceClient client = JobServiceClient.create(settings)) {
      // study spec
      MetricSpec metric =
          MetricSpec.newBuilder().setMetricId("val_rmse").setGoal(GoalType.MINIMIZE).build();

      // decay
      DoubleValueSpec doubleValueSpec =
          DoubleValueSpec.newBuilder().setMinValue(1e-07).setMaxValue(1).build();
      ParameterSpec parameterDecaySpec =
          ParameterSpec.newBuilder()
              .setParameterId("decay")
              .setDoubleValueSpec(doubleValueSpec)
              .setScaleType(ScaleType.UNIT_LINEAR_SCALE)
              .build();
      Double[] decayValues = {32.0, 64.0};
      DiscreteValueCondition discreteValueDecay =
          DiscreteValueCondition.newBuilder().addAllValues(Arrays.asList(decayValues)).build();
      ConditionalParameterSpec conditionalParameterDecay =
          ConditionalParameterSpec.newBuilder()
              .setParameterSpec(parameterDecaySpec)
              .setParentDiscreteValues(discreteValueDecay)
              .build();

      // learning rate
      ParameterSpec parameterLearningSpec =
          ParameterSpec.newBuilder()
              .setParameterId("learning_rate")
              .setDoubleValueSpec(doubleValueSpec) // Use the same min/max as for decay
              .setScaleType(ScaleType.UNIT_LINEAR_SCALE)
              .build();

      Double[] learningRateValues = {4.0, 8.0, 16.0};
      DiscreteValueCondition discreteValueLearning =
          DiscreteValueCondition.newBuilder()
              .addAllValues(Arrays.asList(learningRateValues))
              .build();
      ConditionalParameterSpec conditionalParameterLearning =
          ConditionalParameterSpec.newBuilder()
              .setParameterSpec(parameterLearningSpec)
              .setParentDiscreteValues(discreteValueLearning)
              .build();

      // batch size
      Double[] batchSizeValues = {4.0, 8.0, 16.0, 32.0, 64.0, 128.0};

      DiscreteValueSpec discreteValueSpec =
          DiscreteValueSpec.newBuilder().addAllValues(Arrays.asList(batchSizeValues)).build();
      ParameterSpec parameter =
          ParameterSpec.newBuilder()
              .setParameterId("batch_size")
              .setDiscreteValueSpec(discreteValueSpec)
              .setScaleType(ScaleType.UNIT_LINEAR_SCALE)
              .addConditionalParameterSpecs(conditionalParameterDecay)
              .addConditionalParameterSpecs(conditionalParameterLearning)
              .build();

      // trial_job_spec
      MachineSpec machineSpec =
          MachineSpec.newBuilder()
              .setMachineType("n1-standard-4")
              .setAcceleratorType(AcceleratorType.NVIDIA_TESLA_K80)
              .setAcceleratorCount(1)
              .build();

      PythonPackageSpec pythonPackageSpec =
          PythonPackageSpec.newBuilder()
              .setExecutorImageUri(executorImageUri)
              .addPackageUris(packageUri)
              .setPythonModule(pythonModule)
              .build();

      WorkerPoolSpec workerPoolSpec =
          WorkerPoolSpec.newBuilder()
              .setMachineSpec(machineSpec)
              .setReplicaCount(1)
              .setPythonPackageSpec(pythonPackageSpec)
              .build();

      StudySpec studySpec =
          StudySpec.newBuilder()
              .addMetrics(metric)
              .addParameters(parameter)
              .setAlgorithm(StudySpec.Algorithm.RANDOM_SEARCH)
              .build();
      CustomJobSpec trialJobSpec =
          CustomJobSpec.newBuilder().addWorkerPoolSpecs(workerPoolSpec).build();
      // hyperparameter_tuning_job
      HyperparameterTuningJob hyperparameterTuningJob =
          HyperparameterTuningJob.newBuilder()
              .setDisplayName(displayName)
              .setMaxTrialCount(4)
              .setParallelTrialCount(2)
              .setStudySpec(studySpec)
              .setTrialJobSpec(trialJobSpec)
              .build();
      LocationName parent = LocationName.of(project, location);
      HyperparameterTuningJob response =
          client.createHyperparameterTuningJob(parent, hyperparameterTuningJob);
      System.out.format("response: %s\n", response);
      System.out.format("Name: %s\n", response.getName());
    }
  }
}

Python

如需了解如何安装和使用 Vertex AI 客户端库,请参阅 Vertex AI 客户端库。如需了解详情,请参阅 Vertex AI Python API 参考文档

from google.cloud import aiplatform

def create_hyperparameter_tuning_job_python_package_sample(
    project: str,
    display_name: str,
    executor_image_uri: str,
    package_uri: str,
    python_module: str,
    location: str = "us-central1",
    api_endpoint: str = "us-central1-aiplatform.googleapis.com",
):
    # The AI Platform services require regional API endpoints.
    client_options = {"api_endpoint": api_endpoint}
    # Initialize client that will be used to create and send requests.
    # This client only needs to be created once, and can be reused for multiple requests.
    client = aiplatform.gapic.JobServiceClient(client_options=client_options)

    # study_spec
    metric = {
        "metric_id": "val_rmse",
        "goal": aiplatform.gapic.StudySpec.MetricSpec.GoalType.MINIMIZE,
    }

    conditional_parameter_decay = {
        "parameter_spec": {
            "parameter_id": "decay",
            "double_value_spec": {"min_value": 1e-07, "max_value": 1},
            "scale_type": aiplatform.gapic.StudySpec.ParameterSpec.ScaleType.UNIT_LINEAR_SCALE,
        },
        "parent_discrete_values": {"values": [32, 64]},
    }
    conditional_parameter_learning_rate = {
        "parameter_spec": {
            "parameter_id": "learning_rate",
            "double_value_spec": {"min_value": 1e-07, "max_value": 1},
            "scale_type": aiplatform.gapic.StudySpec.ParameterSpec.ScaleType.UNIT_LINEAR_SCALE,
        },
        "parent_discrete_values": {"values": [4, 8, 16]},
    }
    parameter = {
        "parameter_id": "batch_size",
        "discrete_value_spec": {"values": [4, 8, 16, 32, 64, 128]},
        "scale_type": aiplatform.gapic.StudySpec.ParameterSpec.ScaleType.UNIT_LINEAR_SCALE,
        "conditional_parameter_specs": [
            conditional_parameter_decay,
            conditional_parameter_learning_rate,
        ],
    }

    # trial_job_spec
    machine_spec = {
        "machine_type": "n1-standard-4",
        "accelerator_type": aiplatform.gapic.AcceleratorType.NVIDIA_TESLA_K80,
        "accelerator_count": 1,
    }
    worker_pool_spec = {
        "machine_spec": machine_spec,
        "replica_count": 1,
        "python_package_spec": {
            "executor_image_uri": executor_image_uri,
            "package_uris": [package_uri],
            "python_module": python_module,
            "args": [],
        },
    }

    # hyperparameter_tuning_job
    hyperparameter_tuning_job = {
        "display_name": display_name,
        "max_trial_count": 4,
        "parallel_trial_count": 2,
        "study_spec": {
            "metrics": [metric],
            "parameters": [parameter],
            "algorithm": aiplatform.gapic.StudySpec.Algorithm.RANDOM_SEARCH,
        },
        "trial_job_spec": {"worker_pool_specs": [worker_pool_spec]},
    }
    parent = f"projects/{project}/locations/{location}"
    response = client.create_hyperparameter_tuning_job(
        parent=parent, hyperparameter_tuning_job=hyperparameter_tuning_job
    )
    print("response:", response)

超参数训练作业配置

超参数调节作业会搜索超参数的最佳组合以优化您的指标。超参数调节通过使用不同的超参数集运行训练应用的多次试验来实现此目的。

配置超参数调节作业时,您必须指定以下详细信息:

限制试验次数

确定您希望服务运行的试验次数,并在 HyperparameterTuningJob 对象中设置 maxTrialCount 值。

在决定允许的试验次数时,需要作出以下权衡:

  • 时间(以及相应的费用)
  • 准确性

增加试验次数通常会产生更好的结果,但也有例外情况。通常情况下,会有一个回报递减点,在此之后进行的试验几乎不会再提高准确性。在开始进行大量试验的作业之前,您可能需要从少量试验开始,以衡量所选超参数对模型准确率的影响。

要充分利用超参数调节,切勿将最大值设置为低于您使用的超参数数量的十倍。

并行试验

通过在 HyperparameterTuningJob 中设置 parallelTrialCount,您可以指定可并行运行的次数。

运行并行试验有利于减少训练作业所需的时间(实时 - 需要的总处理时间通常不会改变)。但是,并行运行试验会降低调节作业的整体效率。这是因为超参数调节使用先前试验的结果来获取应分配给后续试验的超参数的值。如果并行运行试验,则一些试验会在未知晓仍在运行试验的结果的情况下开始运行。

如果您使用并行试验,超参数调节服务预配多个训练处理集群(如果是单一流程培训程序,则提供多个单独的机器)。这些训练均会使用您为(用于每一独立训练集群)作业设置的工作池规范。

处理失败的试验

如果您的超参数调节试验由于出现错误而退出,您可能希望尽早结束训练作业。请将 HyperparameterTuningJob 中的 maxFailedTrialCount 字段设置为您要允许的失败试验次数。试验失败的次数达到此值后,Vertex AI 便会结束训练作业。maxFailedTrialCount 值必须小于或等于 maxTrialCount

如果您未设置 maxFailedTrialCount,或将其设置为 0,则 Vertex AI 会使用以下规则处理失败的试验:

  • 如果作业的第一次试验失败,Vertex AI 会立即结束作业。第一次试验失败表明训练代码存在问题,因此后续试验也可能会失败。结束作业让您可以诊断问题,而无需等待更多的试验,并且不会产生更高的费用。
  • 如果第一次试验成功,Vertex AI 可能会根据以下标准之一在后续试验失败后结束作业:
    • 失败的试验次数过多。
    • 失败的试验次数与成功的试验次数之比过高。

这些规则随时可能更改。为确保特定的行为,请设置 maxFailedTrialCount 字段。

管理超参数调节作业

以下部分介绍如何管理超参数调节作业。

检索超参数调节作业的相关信息

以下代码示例演示了如何检索超参数调节作业。

gcloud

使用 gcloud ai hp-tuning-jobs describe 命令

gcloud ai hp-tuning-jobs describe ID_OR_NAME \
    --region=LOCATION

替换以下内容:

  • ID_OR_NAME名称HyperparameterTuningJob 的数字 ID。(此 ID 是名称的最后一部分。)

    您在创建 HyperparameterTuningJob 时可能已看到 ID 或名称。如果您不知道 ID 或名称,则可以运行 gcloud ai hp-tuning-jobs list 命令并查找相应的资源。

  • LOCATIONHyperparameterTuningJob 的创建区域。

REST 和命令行

通过以下代码示例使用 hyperparameterTuningJob 资源的 get 方法检索超参数调节作业。

在使用任何请求数据之前,请先进行以下替换:

  • LOCATIONHyperparameterTuningJob 的创建区域。
  • NAME:超参数调节作业的名称。作业名称使用以下格式 projects/{project}/LOCATIONS/{LOCATION}/hyperparameterTuningJobs/{hyperparameterTuningJob}

HTTP 方法和网址:

GET https://LOCATION-aiplatform-googleapis.com/v1/NAME

如需发送您的请求,请展开以下选项之一:

您应该收到类似以下内容的 JSON 响应:

{
  "name": "projects/12345/LOCATIONs/us-central1/hyperparameterTuningJobs/6789",
  "displayName": "my-hyperparameter-tuning-job",
  "studySpec": {
    "metrics": [
      {
        "metricId": "my_metric",
        "goal": "MINIMIZE"
      }
    ],
    "parameters": [
      {
        "parameterId": "my_parameter",
        "doubleValueSpec": {
          "minValue": 1e-05,
          "maxValue": 1
        }
      }
    ]
  },
  "maxTrialCount": 3,
  "parallelTrialCount": 1,
  "trialJobSpec": {
    "workerPoolSpecs": [
      {
        "machineSpec": {
          "machineType": "n1-standard-4"
        },
        "replicaCount": "1",
        "pythonPackageSpec": {
          "executorImageUri": "us-docker.pkg.dev/vertex-ai/training/training-tf-cpu.2-1:latest",
          "packageUris": [
            "gs://my-bucket/my-training-application/trainer.tar.bz2"
          ],
          "pythonModule": "my-trainer.trainer"
        }
      }
    ]
  },
  "trials": [
    {
      "id": "2",
      "state": "SUCCEEDED",
      "parameters": [
        {
          "parameterId": "my_parameter",
          "value": 0.71426874725564571
        }
      ],
      "finalMeasurement": {
        "stepCount": "2",
        "metrics": [
          {
            "metricId": "my_metric",
            "value": 0.30007445812225342
          }
        ]
      },
      "startTime": "2020-09-09T23:39:15.549112551Z",
      "endTime": "2020-09-09T23:47:08Z"
    },
    {
      "id": "3",
      "state": "SUCCEEDED",
      "parameters": [
        {
          "parameterId": "my_parameter",
          "value": 0.3078893356622992
        }
      ],
      "finalMeasurement": {
        "stepCount": "2",
        "metrics": [
          {
            "metricId": "my_metric",
            "value": 0.30000102519989014
          }
        ]
      },
      "startTime": "2020-09-09T23:49:22.451699360Z",
      "endTime": "2020-09-09T23:57:15Z"
    },
    {
      "id": "1",
      "state": "SUCCEEDED",
      "parameters": [
        {
          "parameterId": "my_parameter",
          "value": 0.500005
        }
      ],
      "finalMeasurement": {
        "stepCount": "2",
        "metrics": [
          {
            "metricId": "my_metric",
            "value": 0.30005377531051636
          }
        ]
      },
      "startTime": "2020-09-09T23:23:12.283374629Z",
      "endTime": "2020-09-09T23:36:56Z"
    }
  ],
  "state": "JOB_STATE_SUCCEEDED",
  "createTime": "2020-09-09T23:22:31.777386Z",
  "startTime": "2020-09-09T23:22:34Z",
  "endTime": "2020-09-10T01:31:24.271307Z",
  "updateTime": "2020-09-10T01:31:24.271307Z"
}

Java

如需了解如何安装和使用 Vertex AI 客户端库,请参阅 Vertex AI 客户端库。如需了解详情,请参阅 Vertex AI Java API 参考文档

import com.google.cloud.aiplatform.v1.HyperparameterTuningJob;
import com.google.cloud.aiplatform.v1.HyperparameterTuningJobName;
import com.google.cloud.aiplatform.v1.JobServiceClient;
import com.google.cloud.aiplatform.v1.JobServiceSettings;
import java.io.IOException;

public class GetHyperparameterTuningJobSample {

  public static void main(String[] args) throws IOException {
    // TODO(developer): Replace these variables before running the sample.
    String project = "PROJECT";
    String hyperparameterTuningJobId = "HYPERPARAMETER_TUNING_JOB_ID";
    getHyperparameterTuningJobSample(project, hyperparameterTuningJobId);
  }

  static void getHyperparameterTuningJobSample(String project, String hyperparameterTuningJobId)
      throws IOException {
    JobServiceSettings settings =
        JobServiceSettings.newBuilder()
            .setEndpoint("us-central1-aiplatform.googleapis.com:443")
            .build();
    String location = "us-central1";

    // Initialize client that will be used to send requests. This client only needs to be created
    // once, and can be reused for multiple requests. After completing all of your requests, call
    // the "close" method on the client to safely clean up any remaining background resources.
    try (JobServiceClient client = JobServiceClient.create(settings)) {
      HyperparameterTuningJobName name =
          HyperparameterTuningJobName.of(project, location, hyperparameterTuningJobId);
      HyperparameterTuningJob response = client.getHyperparameterTuningJob(name);
      System.out.format("response: %s\n", response);
    }
  }
}

Python

如需了解如何安装和使用 Vertex AI 客户端库,请参阅 Vertex AI 客户端库。如需了解详情,请参阅 Vertex AI Python API 参考文档

from google.cloud import aiplatform

def get_hyperparameter_tuning_job_sample(
    project: str,
    hyperparameter_tuning_job_id: str,
    location: str = "us-central1",
    api_endpoint: str = "us-central1-aiplatform.googleapis.com",
):
    # The AI Platform services require regional API endpoints.
    client_options = {"api_endpoint": api_endpoint}
    # Initialize client that will be used to create and send requests.
    # This client only needs to be created once, and can be reused for multiple requests.
    client = aiplatform.gapic.JobServiceClient(client_options=client_options)
    name = client.hyperparameter_tuning_job_path(
        project=project,
        location=location,
        hyperparameter_tuning_job=hyperparameter_tuning_job_id,
    )
    response = client.get_hyperparameter_tuning_job(name=name)
    print("response:", response)

取消超参数调节作业

以下代码示例演示了如何取消超参数调节作业。

gcloud

使用 gcloud ai hp-tuning-jobs cancel 命令

gcloud ai hp-tuning-jobs cancel ID_OR_NAME \
    --region=LOCATION

替换以下内容:

  • ID_OR_NAME名称HyperparameterTuningJob 的数字 ID。(此 ID 是名称的最后一部分。)

    您在创建 HyperparameterTuningJob 时可能已看到 ID 或名称。如果您不知道 ID 或名称,则可以运行 gcloud ai hp-tuning-jobs list 命令并查找相应的资源。

  • LOCATIONHyperparameterTuningJob 的创建区域。

REST 和命令行

通过以下代码示例使用 hyperparameterTuningJob 资源的 cancel 方法取消超参数调节作业。

在使用任何请求数据之前,请先进行以下替换:

  • LOCATIONHyperparameterTuningJob 的创建区域。
  • NAME:超参数调节作业的名称。作业名称使用以下格式 projects/{project}/locations/{location}/hyperparameterTuningJobs/{hyperparameterTuningJob}

HTTP 方法和网址:

POST https://LOCATION-aiplatform-googleapis.com/v1/NAME:cancel

如需发送您的请求,请展开以下选项之一:

您应该会收到一个成功的状态代码 (2xx) 和一个空响应。

Python

如需了解如何安装和使用 Vertex AI 客户端库,请参阅 Vertex AI 客户端库。如需了解详情,请参阅 Vertex AI Python API 参考文档

from google.cloud import aiplatform

def cancel_hyperparameter_tuning_job_sample(
    project: str,
    hyperparameter_tuning_job_id: str,
    location: str = "us-central1",
    api_endpoint: str = "us-central1-aiplatform.googleapis.com",
):
    # The AI Platform services require regional API endpoints.
    client_options = {"api_endpoint": api_endpoint}
    # Initialize client that will be used to create and send requests.
    # This client only needs to be created once, and can be reused for multiple requests.
    client = aiplatform.gapic.JobServiceClient(client_options=client_options)
    name = client.hyperparameter_tuning_job_path(
        project=project,
        location=location,
        hyperparameter_tuning_job=hyperparameter_tuning_job_id,
    )
    response = client.cancel_hyperparameter_tuning_job(name=name)
    print("response:", response)

删除超参数调节作业

以下代码示例演示了如何使用 Python 版 Vertex AI SDK 和 REST API 删除超参数调节作业。

REST 和命令行

通过以下代码示例使用 hyperparameterTuningJob 资源的 delete 方法删除超参数调节作业。

在使用任何请求数据之前,请先进行以下替换:

  • LOCATION:您的区域。
  • NAME:超参数调节作业的名称。作业名称使用以下格式 projects/{project}/LOCATIONs/{LOCATION}/hyperparameterTuningJobs/{hyperparameterTuningJob}

HTTP 方法和网址:

DELETE https://LOCATION-aiplatform-googleapis.com/v1/NAME

如需发送您的请求,请展开以下选项之一:

您应该会收到一个成功的状态代码 (2xx) 和一个空响应。

Python

如需了解如何安装和使用 Vertex AI 客户端库,请参阅 Vertex AI 客户端库。如需了解详情,请参阅 Vertex AI Python API 参考文档

from google.cloud import aiplatform

def delete_hyperparameter_tuning_job_sample(
    project: str,
    hyperparameter_tuning_job_id: str,
    location: str = "us-central1",
    api_endpoint: str = "us-central1-aiplatform.googleapis.com",
    timeout: int = 300,
):
    # The AI Platform services require regional API endpoints.
    client_options = {"api_endpoint": api_endpoint}
    # Initialize client that will be used to create and send requests.
    # This client only needs to be created once, and can be reused for multiple requests.
    client = aiplatform.gapic.JobServiceClient(client_options=client_options)
    name = client.hyperparameter_tuning_job_path(
        project=project,
        location=location,
        hyperparameter_tuning_job=hyperparameter_tuning_job_id,
    )
    response = client.delete_hyperparameter_tuning_job(name=name)
    print("Long running operation:", response.operation.name)
    delete_hyperparameter_tuning_job_response = response.result(timeout=timeout)
    print(
        "delete_hyperparameter_tuning_job_response:",
        delete_hyperparameter_tuning_job_response,
    )

后续步骤