Demander un étiquetage de données

La qualité de vos données d'entraînement influe fortement sur l'efficacité du modèle que vous créez et, par extension, sur la qualité des prédictions renvoyées par ce modèle. La clé des données d'entraînement de haute qualité consiste à vous assurer que vous disposez d'éléments d'entraînement qui représentent avec précision le domaine sur lequel vous souhaitez faire des prédictions, et que les éléments sont correctement étiquetés.

Pour attribuer des étiquettes à vos éléments de données d'entraînement, trois possibilités s'offrent à vous :

  • Ajoutez les éléments de données à votre ensemble de données avec les étiquettes déjà attribuées, par exemple en utilisant un ensemble de données disponible dans le commerce.
  • Attribuez des étiquettes aux éléments de données à l'aide de la console.
  • Demandez à des étiqueteurs humains d'ajouter des étiquettes aux éléments de données.

Les tâches d'étiquetage de données Vertex AI vous permettent de travailler avec des étiqueteurs humains afin de générer des étiquettes très précises pour un ensemble de données que vous pouvez utiliser pour entraîner vos modèles de machine learning.

Pour demander l'ajout d'étiquettes aux données par des étiqueteurs humains, vous devez créer une tâche d'étiquetage de données qui fournit aux étiqueteurs humains les éléments suivants :

  • L'ensemble de données contenant les éléments de données représentatifs à étiqueter.
  • La liste de toutes les étiquettes possibles à appliquer aux éléments de données.
  • Un fichier PDF contenant des instructions pour guider les étiqueteurs humains dans leurs tâches d'étiquetage.

À l'aide de ces ressources, les étiqueteurs humains annotent les éléments de l'ensemble de données en fonction de vos instructions. Lorsqu'ils ont terminé, vous pouvez utiliser l'ensemble d'annotations pour entraîner un modèle d'IA Vertex, ou exporter les éléments de données étiquetés à utiliser dans un autre environnement de machine learning.

Créer un ensemble de données

Pour fournir aux étiqueteurs les éléments de données à étiqueter, créez un ensemble de données et importez-y des éléments de données. Les éléments de données n'ont pas besoin d'être associés à une étiquette. Le type de données (image, vidéo ou texte) et l'objectif (par exemple, classification ou suivi des objets) déterminent le type d'annotations que les étiqueteurs humains appliquent aux éléments de données.

Fournir des étiquettes

Lorsque vous créez une tâche d'étiquetage de données, vous répertoriez l'ensemble des étiquettes que les étiqueteurs humains doivent utiliser. Par exemple, si vous souhaitez classer des images selon qu'elles contiennent un chien ou un chat, vous devez créer un ensemble contenant deux étiquettes : "chien" et "chat". (Mais vous pourriez aussi avoir besoin d'étiquettes pour "aucun des deux" et pour "les deux", comme indiqué ci-dessous.)

Voici quelques consignes qui vous aideront à créer un ensemble d'étiquettes de haute qualité.

  • Utilisez un mot explicite pour chaque nom d'étiquette, tel que "chien", "chat" ou "bâtiment". N'utilisez pas de noms abstraits tels que "étiquette1" et "étiquette2", ou des acronymes peu courants. Plus les noms des étiquettes seront explicites, plus il sera facile pour les étiqueteurs humains de les appliquer avec précision et cohérence.
  • Assurez-vous que les étiquettes se distinguent facilement les unes des autres. Pour les tâches de classification où une seule étiquette est appliquée par élément de données, essayez de ne pas utiliser d'étiquettes ayant des significations similaires. Par exemple, n'utilisez pas d'étiquette pour "Sport" et "Baseball".
  • Pour les tâches de classification, il est généralement judicieux d'inclure une étiquette nommée "autre" ou "aucune" que vous utiliserez pour les données ne correspondant à aucune autre étiquette. Par exemple, si les étiquettes "chien" et "chat" sont les seules disponibles, les étiqueteurs devront étiqueter chaque image avec l'une de ces deux étiquettes. Votre modèle personnalisé sera généralement plus robuste si vous incluez des images autres que des chiens ou des chats dans ses données d'entraînement.
  • Rappelez-vous que le travail des étiqueteurs est plus efficace et plus précis si vous définissez un maximum de 20 étiquettes dans l'ensemble d'étiquettes. Vous pouvez inclure jusqu'à 100 étiquettes.

Créer des instructions

Les instructions donnent des informations aux étiqueteurs humains quant à la façon dont les étiquettes doivent être appliquées à vos données. Les instructions doivent inclure des exemples de données étiquetées et d'autres instructions explicites.

Les instructions sont des fichiers PDF. Les instructions PDF peuvent fournir des instructions sophistiquées, telles que des descriptions ou exemples positifs et négatifs pour chaque cas. Le format PDF est également pratique, car il permet d'obtenir des instructions sur les tâches complexes telles que les cadres de délimitation d'images ou le suivi d'objets vidéo.

Rédigez les instructions, créez un fichier PDF et enregistrez-le dans votre bucket Google Cloud Storage.

Concevoir des instructions de bonne qualité

Si vous espérez que votre tâche d'ajout d'étiquettes renvoie de bons résultats, vos instructions doivent être de bonne qualité. Personne d'autre que vous ne connaît mieux votre cas d'utilisation : vous devez donc informer les étiqueteurs humains vous-même de ce que vous attendez d'eux. Voici quelques consignes pour créer des instructions de bonne qualité :

  • Les étiqueteurs humains n'ont pas votre connaissance du domaine. Lorsque vous leur demandez de faire certaines distinctions, assurez-vous qu'elles soient faciles à comprendre pour une personne qui ne connaît pas votre cas d'utilisation.

  • Évitez de formuler des instructions trop longues. Il serait préférable qu'un étiqueteur puisse les réviser et les comprendre en moins de 20 minutes.

  • Les instructions doivent décrire le concept de la tâche et donner des détails sur la manière d'étiqueter les données. Par exemple, pour une tâche de cadre de délimitation, décrivez comment vous souhaitez que les étiqueteurs tracent le cadre de délimitation. Le cadre doit-il être restreint ou relativement large ? S'il existe plusieurs instances du même objet, faut-il tracer un grand cadre ou plusieurs petits cadres ?

  • Si vos instructions comportent un ensemble d'étiquettes correspondant, elles doivent couvrir toutes les étiquettes de cet ensemble. Le nom d'étiquette donné dans les instructions doit correspondre à celui donné dans l'ensemble d'étiquettes.

  • Il faut souvent plusieurs itérations avant d'arriver à créer des instructions de bonne qualité. Nous vous recommandons de faire en sorte que les étiqueteurs humains travaillent sur un petit ensemble de données, puis d'ajuster vos instructions en fonction du degré de correspondance du travail des étiqueteurs à vos attentes.

Un fichier d'instructions de bonne qualité doit inclure les sections suivantes :

  • Liste et description des étiquettes : répertoriez toutes les étiquettes que vous souhaitez utiliser et décrivez la signification de chaque étiquette.
  • Exemples : pour chaque étiquette, donnez au moins trois exemples positifs et un exemple négatif. Ces exemples doivent couvrir différents cas.
  • Couvrez les cas spéciaux. Clarifiez autant de cas spéciaux que possible. Cela réduit la nécessité pour l'étiqueteur d'interpréter l'étiquette. Par exemple, si vous devez dessiner un cadre de délimitation pour une personne, il est préférable de préciser les points suivants :
    • S'il y a plusieurs personnes, avez-vous besoin d'un cadre pour chaque personne ?
    • Avez-vous besoin d'un cadre si une personne est cachée ?
    • Avez-vous besoin d'un cadre pour une personne qui n'apparaît que partiellement dans l'image ?
    • Avez-vous besoin d'un cadre pour une personne figurant dans une photo ou un tableau ?
  • Indiquez comment ajouter des annotations. Exemple :
    • Dans le cas d'un cadre de délimitation, avez-vous besoin d'un cadre restreint ou relativement large ?
    • Dans le cas d'une extraction d'entité de texte, où doit commencer et finir l'entité en question ?
  • Clarification concernant les étiquettes. Si deux étiquettes sont similaires ou faciles à confondre, donnez des exemples pour clarifier la différence.

Les exemples ci-dessous présentent ce que peuvent inclure des instructions PDF. Les étiqueteurs examineront les instructions avant de commencer la tâche.

Instructions PDF 1

Instructions PDF 2

Créer une tâche d'étiquetage de données

UI Web

Vous pouvez demander l'ajout d'étiquettes aux données de deux emplacements dans Google Cloud Console :

  • Dans l'écran des informations concernant l'ensemble de données, cliquez sur Créer une tâche d'étiquetage.
  • Dans l'écran de la liste Tâches d'étiquetage, cliquez sur Créer.

Le volet Nouvelle tâche d'étiquetage s'ouvre.

  1. Attribuez un nom à la tâche d'étiquetage.

  2. Sélectionnez l'ensemble de données dont vous souhaitez étiqueter les éléments.

    Si vous avez ouvert le volet Nouvelle tâche d'étiquetage à partir de l'écran des informations concernant l'ensemble de données, vous ne pouvez pas sélectionner un autre ensemble de données.

  3. Vérifiez que l'objectif est correct.

    La zone Objectif affiche l'objectif de l'ensemble de données sélectionné, tel que déterminé par son ensemble d'annotations par défaut. Pour modifier l'objectif, sélectionnez un autre ensemble d'annotations.

  4. Choisissez l'ensemble d'annotations à utiliser pour les données étiquetées.

    Les étiquettes appliquées par les étiqueteurs humains seront enregistrées dans l'ensemble d'annotations sélectionné. Vous pouvez choisir un ensemble d'annotations existant ou en créer un. Si vous en créez un, vous devez lui attribuer un nom.

  5. Indiquez si vous souhaitez utiliser l'apprentissage actif.

    L'apprentissage actif accélère le processus d'étiquetage en utilisant une partie de l'étiquetage manuel de votre ensemble de données, puis en appliquant le machine learning pour étiqueter automatiquement le reste.

    REMARQUE : L'apprentissage actif n'est disponible que pour les objectifs de classification d'images (étiquette unique) et de cadre de délimitation d'images.

  6. Cliquez sur Continuer.

  7. Saisissez les étiquettes que les étiqueteurs humains devront appliquer, puis cliquez sur Continuer.

    Pour obtenir des instructions concernant la création d'un ensemble d'étiquettes de haute qualité, consultez la section Concevoir un ensemble d'étiquettes.

  8. Saisissez le chemin d'accès aux instructions des étiqueteurs humains, puis cliquez sur Continuer.

    Les instructions doivent être contenues dans un fichier PDF stocké dans un bucket Google Cloud Storage. Pour obtenir des instructions concernant la création d'instructions de haute qualité, consultez la section Concevoir des instructions pour les étiqueteurs humains.

  9. Indiquez si vous souhaitez utiliser des étiqueteurs gérés par Google ou opter pour vos propres étiqueteurs.

    Pour faire appel à vos propres étiqueteurs, vous devez créer des groupes d'étiqueteurs et gérer leurs activités à l'aide de la console DataCompute.

  10. Indiquez le nombre d'étiqueteurs qui devront réviser chaque élément.

    Par défaut, un étiqueteur humain annote chaque élément de données. Toutefois, vous pouvez demander à plusieurs étiqueteurs d'annoter et d'examiner chaque élément. Sélectionnez le nombre d'étiqueteurs dans la zone Spécialistes par élément de données.

  11. Si vous avez choisi d'utiliser des étiqueteurs gérés par Google, cochez la case pour confirmer que vous avez lu le guide des tarifs visant la compréhension du coût de l'étiquetage.

  12. Si vous faites appel à vos propres étiqueteurs, choisissez le groupe d'étiqueteurs à utiliser pour cette tâche d'étiquetage.

    Choisissez un groupe d'étiqueteurs existant dans la liste déroulante, ou sélectionnez Nouveau groupe d'étiqueteurs, puis saisissez le nom et les adresses e-mail des gestionnaires du groupe, séparés par des virgules dans la zone de texte sous la liste déroulante. Cochez la case pour autoriser les gestionnaires spécifiés à consulter vos informations d'étiquetage de données.

  13. Cliquez sur Démarrer une tâche.

    Si Démarrer une tâche n'est pas disponible, consultez les pages du volet Nouvelle tâche d'ajout d'étiquettes pour vous assurer que vous avez bien saisi toutes les informations requises.

Vous pouvez suivre la progression de la tâche d'ajout d'étiquetage des données en sélectionnant Tâches d'étiquetage dans la console. La page affiche l'état de chaque tâche d'étiquetage demandée. Lorsque la colonne Progression indique 100 %, l'ensemble de données correspondant est étiqueté et prêt à être utilisé pour entraîner un modèle.

API REST et ligne de commande

Avant d'utiliser les données de requête ci-dessous, effectuez les remplacements suivants :

  • PROJECT_ID : ID de votre projet
  • DISPLAY_NAME : nom de la tâche d'étiquetage des données
  • DATASET_ID : ID de l'ensemble de données contenant les éléments à étiqueter
  • LABELERS : nombre d'étiqueteurs humains souhaité pour examiner chaque élément de données. Les valeurs valides sont 1, 3 et 5.
  • INSTRUCTIONS : chemin d'accès au fichier PDF contenant les instructions destinées aux étiqueteurs humains. Le fichier doit se trouver dans un bucket Google Cloud Storage accessible à partir de votre projet.
  • INPUT_SCHEMA_URI : chemin d'accès au fichier de schéma pour le type d'élément de données :
    • Classification d'images à étiquette unique :
      gs://google-cloud-aiplatform/schema/dataset/ioformat/image_classification_single_label_io_format_1.0.0.yaml
    • Classification d'images multi-étiquette :
      gs://google-cloud-aiplatform/schema/dataset/ioformat/image_classification_multi_label_io_format_1.0.0.yaml
    • Détection d'objets au sein d'images :
      gs://google-cloud-aiplatform/schema/dataset/ioformat/image_bounding_box_io_format_1.0.0.yaml
    • Classification de texte à étiquette unique :
      gs://google-cloud-aiplatform/schema/dataset/ioformat/text_classification_single_label_io_format_1.0.0.yaml
    • Classification de texte multi-étiquette :
      gs://google-cloud-aiplatform/schema/dataset/ioformat/text_classification_multi_label_io_format_1.0.0.yaml
    • Extraction d'entités textuelles :
      gs://google-cloud-aiplatform/schema/dataset/ioformat/text_extraction_io_format_1.0.0.yaml
    • Analyse des sentiments d'après un texte :
      gs://google-cloud-aiplatform/schema/dataset/ioformat/text_sentiment_io_format_1.0.0.yaml
    • Classification de vidéos :
      gs://google-cloud-aiplatform/schema/dataset/ioformat/video_classification_io_format_1.0.0.yaml
    • Suivi des objets vidéo :
      gs://google-cloud-aiplatform/schema/dataset/ioformat/video_object_tracking_io_format_1.0.0.yaml
  • LABEL_LIST : liste de chaînes séparées par une virgule, qui répertorient les étiquettes pouvant être appliqués à un élément de données
  • ANNOTATION_SET : nom de l'ensemble d'annotations pour les données étiquetées

Méthode HTTP et URL :

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

Corps JSON de la requête :

{
   "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"
   }
}

Pour envoyer votre requête, développez l'une des options suivantes :

Vous devriez recevoir une réponse JSON de ce type :

{
  "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
}
La réponse est de type DataLabelingJob. Vous pouvez vérifier la progression de la tâche en surveillant l'élément "labelingProgress", dont la valeur correspond au pourcentage terminé.

Java

Autres exemples de code :


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

Autres exemples de code :

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)

REMARQUE : Le délai maximal pour une tâche d'étiquetage de données est de 63 jours. Si elle n'est pas terminée dans le délai imparti, la tâche expire et est supprimée, ainsi que les tâches attribuées aux étiqueteurs.

Étape suivante