请求 Vertex AI Data Labeling Service

训练数据的质量极大影响着所创建的模型的效果,进而影响该模型返回的预测结果的质量。拥有高品质训练数据的关键是确保有训练项准确表示要进行预测的网域,并且训练项准确标记。

您可以通过以下三种方式为训练数据项分配标签:

  • 将数据项添加到已分配标签的数据集(例如,使用商业可用数据集)
  • 使用 Google Cloud 控制台为数据项分配标签
  • 请求人工标签添加者为数据项添加标签

借助 Vertex AI 为数据加标签任务,您可以与人工标签添加者协作,为用于训练机器学习模型的数据集合生成高精确度标签。

如需了解数据标签的价格,请参阅数据标签

如需请求由人工标签添加者加标签的数据,您需要创建一个数据标签作业来为人工标签添加者提供以下内容:

  • 包含要加标签的代表性数据项的数据集
  • 应用到数据项的所有可能标签的列表
  • 此 PDF 文件包含指导人工标签添加者完成添加标签任务的说明

使用这些资源,人工标签添加者会根据您的说明为数据集中的项添加注释。完成后,您可以使用注解集来训练 Vertex AI 模型或导出加标签的数据项,以便在其他机器学习环境中使用。

创建数据集

您可以向人工标签添加者提供要添加标签的数据项,方法是创建数据集并将数据项导入到其中。数据项无需添加标签。数据类型(图片、视频或文本)和目标(例如分类或对象跟踪)决定了人工标签添加者应用于数据项的注释类型。

提供标签

创建数据标签任务时,您可以列出您希望人工标签添加者为您的图片添加的一组标签。举例来说,如果您想要对含有猫或狗的图片进行分类,则可以创建一个包含“Dog”和“Cat”这两个标签的标签集如以下列表所述,您可能还需要使用表示“Neither”和“Both”的标签。

以下是创建优质标签集的几项准则。

  • 将每个标签的显示名设置为有意义的字词,例如“dog”“cat”或“building”。请勿使用“label1”和“label2”之类的抽象名称或冷僻的首字母缩写词。标签名称越有意义,人工标签添加者越容易准确应用标签名称并保持一致性。
  • 确保标签易于彼此区分。对于将单个标签应用到每个数据项的分类任务,请尽量不要使用含义重叠的标签。例如,没有“Sports”和“Baseball”的标签。
  • 通常情况下,对于分类任务,最好包含名为“其他”或“无”的标签,以用于与其他标签不匹配的数据。例如,如果唯一可用的标签是“狗”和“猫”,则标签添加者必须使用这两个标签之一为每张图片加标签。如果自定义模型的训练数据中包含除狗或猫以外的图片,则该模型通常会更加完善。
  • 请注意,为使标签添加者能够以最佳的效率准确地进行工作,建议您将标签集内的标签数量维持在 20 个以内。您最多可以添加 100 个标签。

创建说明

通过说明,添加标签的人员可了解如何将标签应用到数据。说明中应该有已带标签的样本数据和其他明确指示。

说明为 PDF 文件。PDF 说明可以提供精确的指示,例如每种情况的正例和负例或相关说明。PDF 也是一种很方便的格式,可用于为图片边界框或视频对象跟踪等复杂任务提供说明。

撰写说明、创建 PDF 文件,并将 PDF 文件保存在 Cloud Storage 存储桶中。

提供良好的说明

好的说明是获得绝佳人工标签结果的最重要因素。您的使用场景您最了解,因此您需要让添加标签的人员也了解您的需求。下面是创建优秀说明的几项准则:

  • 人工标签添加者并不具备您的相关领域知识。对于不熟悉您的使用场景的人来说,您要求标签添加者做出的区分应该易于理解。

  • 避免创建过于冗长的说明。标签添加者最好能在 20 分钟内查看并理解说明。

  • 说明应描述任务的概念,并详细指出如何为数据添加标签。例如,对于边界框任务,可描述您希望标签添加者如何绘制边界框。边界框应该较紧凑还是较松散?如果对象有多个实例,则标签添加者是该绘制一个边界框,还是该绘制多个边界框?

  • 如果您的说明具有对应的标签集,则应涵盖该标签集中的所有标签。说明中的标签名称应与标签集中的名称一致。

  • 为了创建良好的说明,通常需要进行多次迭代。我们建议首先让人工标签添加者处理一个小数据集,然后根据人工标签添加者的工作与您的期望匹配程度来调整您的说明。

理想的说明文件包含以下几个部分:

  • 标签列表和说明:您要使用的所有标签的列表以及每个标签的含义。
  • 示例:对于每个标签,请提供至少三个正例和一个负例。这些示例应涵盖不同的用例。
  • 涵盖边缘用例。要减少标签添加者解释标签的需求,请尽可能多地阐明边缘情况。例如,如果您需要绘制人物边界框,最好能清楚地说明以下事项:
    • 如果有多个人物,您是否需要为每个人物绘制一个边界框?
    • 如果某个人被遮挡了,您是否需要绘制边界框?
    • 如果图片中只显示了某个人的一部分,您是否需要绘制边界框?
    • 如果某个人在照片或绘画中,您是否需要绘制边界框?
  • 说明如何添加注释。例如:
    • 对于边界框,您需要紧凑型还是松散型的?
    • 对于文本实体提取,相关实体应该从哪里开始、在哪里结束?
  • 阐明标签。如果两个标签相似或易于混淆,请提供示例来阐明区别。

以下示例展示了 PDF 说明可能包含的内容。在开始执行任务之前,标签添加者将查看说明。

PDF 说明 1。

PDF 说明 2。

创建为数据加标签的任务

网页界面

您可以通过 Google Cloud Console 请求数据标签。

  1. 在 Google Cloud Console 中,转到标签任务页面。

    转到“标签任务”

  2. 点击创建

此时会打开新建标签任务窗格。

  1. 为标签任务输入名称。

  2. 选择要为其数据项添加标签的数据集。

    如果您从数据集详情屏幕打开新建标签任务窗格,则无法选择其他数据集。

  3. 确认目标正确无误。

    目标框显示选定数据集的目标,由其默认注释集确定。要更改目标,请选择其他注释集。

  4. 选择要用于已加标签的数据的注释集。

    人工标签添加者应用的标签将保存到所选的注释集中。您可以选择现有的注释集,也可以创建一个新注释。如果您要创建新实例,则需要为其命名。

  5. 指定是否使用主动学习。

    主动学习通过人工标签添加者给部分数据集添加标签,然后应用机器学习技术自动给其余数据集添加标签,从而加快添加标签的过程。

  6. 点击继续

  7. 输入要应用的人工标签添加者的标签。如需了解如何创建高质量的标签集,请参阅设计标签集

  8. 点击继续

  9. 输入人工标签添加者的说明的路径。说明必须是存储在 Cloud Storage 存储桶中的 PDF 文件。如需了解如何创建高质量说明,请参阅为人工标签添加者设计说明

  10. 点击继续

  11. 选择使用 Google 管理的标签添加者提供您自己的标签添加者

    • 如果您选择使用 Google 管理的标签添加者,请选中相应复选框以确认您已阅读价格指南,了解添加标签的费用。

    • 如果要提供自己的标签添加者,则需要使用 DataCompute Console 创建标签添加者组并管理其活动。否则,请选择要用于此标签任务的标签添加者组。

      从下拉列表中选择现有标签添加者组,或选择新建标签添加者组,然后在下拉列表下方的文本框中输入群组名称和群组管理员的逗号分隔的电子邮件地址列表。点击相应复选框以授予指定的管理员查看数据标签信息的权限。

  12. 指定您要查看的每一项标签添加者数量。

    默认情况下,一个人工标签添加者为每个数据项添加注释。但是,您可以要求多个标签添加者对每个项目进行注释和查看。从每个数据项的专家框中选择标签添加者数量。

  13. 点击开始任务

    如果开始任务不可用,请查看新建标签任务窗格中的页面,验证您是否已输入所有必要信息。

您可以在 Google Cloud Console 的标签任务页面中查看数据标签任务的进度。

转到“标签任务”

该页面显示了每一个请求的标签任务的状态。如果进度列显示 100%,则相应数据集会被添加标签,并为训练模型做好准备。

REST

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

  • PROJECT_ID:您的项目 ID
  • DISPLAY_NAME:数据标签作业的名称
  • DATASET_ID:包含待加标签的项的数据集 ID
  • LABELERS:您要逐一审核每个数据项的人工标签添加者的数量;有效值为 1、3 和 5。
  • INSTRUCTIONS:包含人工标签添加者说明的 PDF 文件的路径;该文件必须位于可从项目访问的 Cloud Storage 存储桶中
  • INPUT_SCHEMA_URI:数据项类型的架构文件的路径:
    • 图片分类(单标签):
      gs://google-cloud-aiplatform/schema/dataset/ioformat/image_classification_single_label_io_format_1.0.0.yaml
    • 图片分类(多标签):
      gs://google-cloud-aiplatform/schema/dataset/ioformat/image_classification_multi_label_io_format_1.0.0.yaml
    • 图片对象检测:
      gs://google-cloud-aiplatform/schema/dataset/ioformat/image_bounding_box_io_format_1.0.0.yaml
    • 文本分类(单标签):
      gs://google-cloud-aiplatform/schema/dataset/ioformat/text_classification_single_label_io_format_1.0.0.yaml
    • 文本分类(多标签):
      gs://google-cloud-aiplatform/schema/dataset/ioformat/text_classification_multi_label_io_format_1.0.0.yaml
    • 文本实体提取:
      gs://google-cloud-aiplatform/schema/dataset/ioformat/text_extraction_io_format_1.0.0.yaml
    • 文本情感分析:
      gs://google-cloud-aiplatform/schema/dataset/ioformat/text_sentiment_io_format_1.0.0.yaml
    • 视频分类:
      gs://google-cloud-aiplatform/schema/dataset/ioformat/video_classification_io_format_1.0.0.yaml
    • 视频对象跟踪:
      gs://google-cloud-aiplatform/schema/dataset/ioformat/video_object_tracking_io_format_1.0.0.yaml
  • LABEL_LIST:以英文逗号分隔的字符串列表,枚举适用于数据项的标签
  • ANNOTATION_SET:已加标签数据的注释集名称

HTTP 方法和网址:

POST https://us-central1-aiplatform.googleapis.com/v1/projects/PROJECT_ID/locations/us-central1/dataLabelingJobs

请求 JSON 正文:

{
   "displayName":"DISPLAY_NAME",
   "datasets":"DATASET_ID",
   "labelerCount":LABELERS,
   "instructionUri":"INSTRUCTIONS",
   "inputsSchemaUri":"INPUT_SCHEMA_URI",
   "inputs": {
     "annotation_specs": [LABEL_LIST]
   },
   "annotationLabels": {
     "aiplatform.googleapis.com/annotation_set_name": "ANNOTATION_SET"
   }
}

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

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

{
  "name": "projects/PROJECT_ID/locations/us-central1/dataLabelingJobs/JOB_ID",
  "displayName": "DISPLAY_NAME",
  "datasets": [
    "DATASET_ID"
  ],
  "labelerCount": LABELERS,
  "instructionUri": "INSTRUCTIONS",
  "inputsSchemaUri": "INPUT_SCHEMA_URI",
  "inputs": {
    "annotationSpecs": [
      LABEL_LIST
    ]
  },
  "state": "JOB_STATE_PENDING",
  "labelingProgress": "0",
  "createTime": "2020-05-30T23:13:49.121133Z",
  "updateTime": "2020-05-30T23:13:49.121133Z",
  "savedQuery": {
    "name": "projects/PROJECT_ID/locations/us-central1/datasets/DATASET_ID/savedQueries/ANNOTATION_SET_ID"
  },
  "annotationSpecCount": 2
}
响应为 DataLabelingJob。您可以通过监控 "labelingProgress" 元素(其值为已完成的百分比)来检查作业的进度。

Java

更多代码示例


import com.google.cloud.aiplatform.v1.DataLabelingJob;
import com.google.cloud.aiplatform.v1.DatasetName;
import com.google.cloud.aiplatform.v1.JobServiceClient;
import com.google.cloud.aiplatform.v1.JobServiceSettings;
import com.google.cloud.aiplatform.v1.LocationName;
import com.google.protobuf.Value;
import com.google.protobuf.util.JsonFormat;
import com.google.type.Money;
import java.io.IOException;
import java.util.Map;

public class CreateDataLabelingJobSample {

  public static void main(String[] args) throws IOException {
    // TODO(developer): Replace these variables before running the sample.
    String project = "YOUR_PROJECT_ID";
    String displayName = "YOUR_DATA_LABELING_DISPLAY_NAME";
    String datasetId = "YOUR_DATASET_ID";
    String instructionUri =
        "gs://YOUR_GCS_SOURCE_BUCKET/path_to_your_data_labeling_source/file.pdf";
    String inputsSchemaUri = "YOUR_INPUT_SCHEMA_URI";
    String annotationSpec = "YOUR_ANNOTATION_SPEC";
    createDataLabelingJob(
        project, displayName, datasetId, instructionUri, inputsSchemaUri, annotationSpec);
  }

  static void createDataLabelingJob(
      String project,
      String displayName,
      String datasetId,
      String instructionUri,
      String inputsSchemaUri,
      String annotationSpec)
      throws IOException {
    JobServiceSettings jobServiceSettings =
        JobServiceSettings.newBuilder()
            .setEndpoint("us-central1-aiplatform.googleapis.com:443")
            .build();

    // 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 jobServiceClient = JobServiceClient.create(jobServiceSettings)) {
      String location = "us-central1";
      LocationName locationName = LocationName.of(project, location);

      String jsonString = "{\"annotation_specs\": [ " + annotationSpec + "]}";
      Value.Builder annotationSpecValue = Value.newBuilder();
      JsonFormat.parser().merge(jsonString, annotationSpecValue);

      DatasetName datasetName = DatasetName.of(project, location, datasetId);
      DataLabelingJob dataLabelingJob =
          DataLabelingJob.newBuilder()
              .setDisplayName(displayName)
              .setLabelerCount(1)
              .setInstructionUri(instructionUri)
              .setInputsSchemaUri(inputsSchemaUri)
              .addDatasets(datasetName.toString())
              .setInputs(annotationSpecValue)
              .putAnnotationLabels(
                  "aiplatform.googleapis.com/annotation_set_name", "my_test_saved_query")
              .build();

      DataLabelingJob dataLabelingJobResponse =
          jobServiceClient.createDataLabelingJob(locationName, dataLabelingJob);

      System.out.println("Create Data Labeling Job Response");
      System.out.format("\tName: %s\n", dataLabelingJobResponse.getName());
      System.out.format("\tDisplay Name: %s\n", dataLabelingJobResponse.getDisplayName());
      System.out.format("\tDatasets: %s\n", dataLabelingJobResponse.getDatasetsList());
      System.out.format("\tLabeler Count: %s\n", dataLabelingJobResponse.getLabelerCount());
      System.out.format("\tInstruction Uri: %s\n", dataLabelingJobResponse.getInstructionUri());
      System.out.format("\tInputs Schema Uri: %s\n", dataLabelingJobResponse.getInputsSchemaUri());
      System.out.format("\tInputs: %s\n", dataLabelingJobResponse.getInputs());
      System.out.format("\tState: %s\n", dataLabelingJobResponse.getState());
      System.out.format("\tLabeling Progress: %s\n", dataLabelingJobResponse.getLabelingProgress());
      System.out.format("\tCreate Time: %s\n", dataLabelingJobResponse.getCreateTime());
      System.out.format("\tUpdate Time: %s\n", dataLabelingJobResponse.getUpdateTime());
      System.out.format("\tLabels: %s\n", dataLabelingJobResponse.getLabelsMap());
      System.out.format(
          "\tSpecialist Pools: %s\n", dataLabelingJobResponse.getSpecialistPoolsList());
      for (Map.Entry<String, String> annotationLabelMap :
          dataLabelingJobResponse.getAnnotationLabelsMap().entrySet()) {
        System.out.println("\tAnnotation Level");
        System.out.format("\t\tkey: %s\n", annotationLabelMap.getKey());
        System.out.format("\t\tvalue: %s\n", annotationLabelMap.getValue());
      }
      Money money = dataLabelingJobResponse.getCurrentSpend();

      System.out.println("\tCurrent Spend");
      System.out.format("\t\tCurrency Code: %s\n", money.getCurrencyCode());
      System.out.format("\t\tUnits: %s\n", money.getUnits());
      System.out.format("\t\tNanos: %s\n", money.getNanos());
    }
  }
}

Python

更多代码示例

from google.cloud import aiplatform
from google.protobuf import json_format
from google.protobuf.struct_pb2 import Value

def create_data_labeling_job_sample(
    project: str,
    display_name: str,
    dataset_name: str,
    instruction_uri: str,
    inputs_schema_uri: str,
    annotation_spec: 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)
    inputs_dict = {"annotation_specs": [annotation_spec]}
    inputs = json_format.ParseDict(inputs_dict, Value())

    data_labeling_job = {
        "display_name": display_name,
        # Full resource name: projects/{project_id}/locations/{location}/datasets/{dataset_id}
        "datasets": [dataset_name],
        # labeler_count must be 1, 3, or 5
        "labeler_count": 1,
        "instruction_uri": instruction_uri,
        "inputs_schema_uri": inputs_schema_uri,
        "inputs": inputs,
        "annotation_labels": {
            "aiplatform.googleapis.com/annotation_set_name": "my_test_saved_query"
        },
    }
    parent = f"projects/{project}/locations/{location}"
    response = client.create_data_labeling_job(
        parent=parent, data_labeling_job=data_labeling_job
    )
    print("response:", response)

后续步骤