

Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.

# Flux de travail d’étiquetage personnalisés
<a name="sms-custom-templates"></a>

Ces rubriques vous aident à configurer une tâche d’étiquetage Ground Truth qui utilise un modèle d’étiquetage personnalisé. Un modèle d’étiquetage personnalisé vous permet de créer une interface utilisateur du portail d’employé personnalisée que les employés utiliseront pour étiqueter les données. Le modèle peut être créé à l'aide du HTML, du CSS JavaScript, du [langage de modèle Liquid](https://shopify.github.io/liquid/) et des [éléments Crowd HTML](https://docs.aws.amazon.com/sagemaker/latest/dg/sms-ui-template-reference.html).

## Présentation de
<a name="sms-custom-templates-overview"></a>

Si c’est la première fois que vous créez un flux de travail d’étiquetage personnalisé dans Ground Truth, la liste suivante est un résumé détaillé des étapes requises.

1. *Configuration de votre main-d’œuvre* : pour créer un flux de travail d’étiquetage personnalisé, vous avez besoin d’une main-d’œuvre. Cette rubrique explique comment configurer une main-d’œuvre.

1. *Création d’un modèle personnalisé* : pour créer un modèle personnalisé, vous devez mapper correctement les données de votre fichier manifeste d’entrée aux variables de votre modèle.

1. *Utilisation de fonctions Lambda de traitement facultatives* : pour contrôler la manière dont les données de votre manifeste d’entrée sont ajoutées à votre modèle de travail et la manière dont les annotations des employés sont enregistrées dans le fichier de sortie de votre tâche.

Cette rubrique propose également trois end-to-end démonstrations pour vous aider à mieux comprendre comment utiliser les modèles d'étiquetage personnalisés.

**Note**  
Les exemples contenus dans les liens ci-dessous incluent tous des fonctions Lambda de pré-annotation et de post-annotation. Ces fonctions Lambda sont facultatives.
+ [Modèle de démonstration : annotation d’images avec `crowd-bounding-box`](sms-custom-templates-step2-demo1.md)
+ [Modèle de démonstration : étiquetage des intentions avec `crowd-classifier`](sms-custom-templates-step2-demo2.md)
+ [Créez un flux de travail d'étiquetage des données personnalisé avec Amazon SageMaker Ground Truth](https://aws.amazon.com/blogs/machine-learning/build-a-custom-data-labeling-workflow-with-amazon-sagemaker-ground-truth/)

**Topics**
+ [Présentation de](#sms-custom-templates-overview)
+ [Configuration de votre main-d’œuvre](sms-custom-templates-step1.md)
+ [Création d’un modèle de tâche d’employé personnalisé](sms-custom-templates-step2.md)
+ [Ajout de l’automatisation avec Liquid](sms-custom-templates-step2-automate.md)
+ [Traitement des données dans un flux de travail d'étiquetage personnalisé avec AWS Lambda](sms-custom-templates-step3.md)
+ [Modèle de démonstration : annotation d’images avec `crowd-bounding-box`](sms-custom-templates-step2-demo1.md)
+ [Modèle de démonstration : étiquetage des intentions avec `crowd-classifier`](sms-custom-templates-step2-demo2.md)
+ [Création d’un flux de travail personnalisé à l’aide de l’API](sms-custom-templates-step4.md)

# Configuration de votre main-d’œuvre
<a name="sms-custom-templates-step1"></a>

Au cours de cette étape, vous utilisez la console pour établir le type d’employé auquel vous allez faire appel et effectuez les sous-sélections nécessaires pour le type d’employé. Nous partons du principe que vous avez déjà réalisé les étapes de la section [Mise en route : création d’une tâche d’étiquetage de cadre de délimitation avec Ground Truth](sms-getting-started.md) et que vous avez choisi la **tâche d’étiquetage personnalisée** comme **type de tâche**.

**Pour configurer votre main-d’œuvre.**

1. Choisissez tout d’abord une option sous **Types d’employé**. Il existe trois types d’employés :
   + **Public** fait appel à une main-d’œuvre à la demande d’entrepreneurs indépendants, alimentée par Amazon Mechanical Turk. Ils sont payés à la tâche.
   + **Privé** fait appel à vos employés ou sous-traitants pour traiter les données qui doivent rester au sein de votre organisation.
   + **Le fournisseur** fait appel à des fournisseurs tiers spécialisés dans la fourniture de services d'étiquetage de données, disponibles via le AWS Marketplace.

1. Si vous choisissez l’option **Public**, il vous sera demandé de définir le **nombre d’employés par objet de jeu de données**. Le fait de faire appel à plusieurs employés pour effectuer la même tâche sur le même objet peut augmenter la précision de vos résultats. La valeur par défaut est 3. Vous pouvez l’augmenter ou la diminuer en fonction de la précision dont vous avez besoin.

   Vous êtes également invité à définir un **prix par tâche** à l’aide d’un menu déroulant. Le menu recommande des niveaux de tarification basés sur le temps nécessaire pour terminer la tâche.

   La méthode recommandée pour la déterminer consiste à d’abord tester brièvement votre tâche avec une main-d’œuvre **privée**. Ce test donne une estimation réaliste de la durée nécessaire pour effectuer la tâche. Vous pouvez ensuite sélectionner la fourchette dans laquelle se situe votre estimation dans le menu **Prix par tâche**. Si la durée moyenne est de plus de 5 minutes, envisagez de scinder votre tâche en unités plus petites.

## Suivant
<a name="templates-step1-next"></a>

[Création d’un modèle de tâche d’employé personnalisé](sms-custom-templates-step2.md)

# Création d’un modèle de tâche d’employé personnalisé
<a name="sms-custom-templates-step2"></a>

Pour créer une tâche d’étiquetage personnalisée, vous devez mettre à jour le modèle de tâche d’employé, mapper les données d’entrée de votre fichier manifeste aux variables utilisées dans le modèle et mapper les données de sortie à Amazon S3. Pour en savoir plus sur les fonctionnalités avancées qui utilisent l’automatisation Liquid, consultez [Ajout de l’automatisation avec Liquid](sms-custom-templates-step2-automate.md).

Les sections suivantes décrivent chacune des étapes requises.

## Modèle de tâche d’employé
<a name="sms-custom-templates-step2-template"></a>

Un *modèle de tâche d’employé* est un fichier utilisé par Ground Truth pour personnaliser l’interface utilisateur employé (UI). Vous pouvez créer un modèle de tâche de travail à l'aide de HTML, de CSS JavaScript, du [langage de modèle Liquid](https://shopify.github.io/liquid/) et d'[éléments HTML Crowd](https://docs.aws.amazon.com/sagemaker/latest/dg/sms-ui-template-reference.html). Liquid est utilisé pour automatiser le modèle. Les éléments HTML Crowd sont utilisés pour inclure des outils d’annotation courants et fournir la logique à envoyer à Ground Truth.

Consultez les rubriques suivantes pour apprendre à créer un modèle de tâche d’employé. Vous pouvez consulter un référentiel d'exemples de modèles de tâches de travail de Ground Truth sur [GitHub](https://github.com/aws-samples/amazon-sagemaker-ground-truth-task-uis).

### Utilisation du modèle de tâches du travailleur de base dans la console SageMaker AI
<a name="sms-custom-templates-step2-base"></a>

Vous pouvez utiliser un éditeur de modèles dans la console Ground Truth pour commencer à créer un modèle. Cet éditeur inclut un certain nombre de modèles de base préconçus. Il prend en charge le remplissage automatique pour le code HTML et les éléments HTML Crowd.

**Pour accéder à l’éditeur de modèles personnalisés Ground Truth :**

1. Suivez les instructions incluses dans [Création d’une tâche d’étiquetage (Console)](sms-create-labeling-job-console.md).

1. Sélectionnez ensuite **Personnalisé** pour le **Type de tâche** d’étiquetage.

1. Sélectionnez **Suivant** et vous pouvez alors accéder à l’éditeur de modèles et aux modèles de base dans la section **Configuration des tâches d’étiquetage personnalisées**. 

1. (Facultatif) Sélectionnez un modèle de base dans le menu déroulant sous **Modèles**. Si vous préférez créer un modèle à partir de zéro, choisissez **Personnalisé** dans le menu déroulant pour un squelette de modèle minimal.

Utilisez la section suivante pour savoir comment visualiser un modèle développé localement dans la console.

#### Visualisation locale des modèles de tâches d’employé
<a name="sms-custom-template-step2-UI-local"></a>

Vous devez utiliser la console pour tester la manière dont votre modèle traite les données entrantes. Pour tester l’apparence du code HTML et des éléments personnalisés de votre modèle, vous pouvez utiliser votre navigateur.

**Note**  
Les variables ne seront pas analysées. Vous devrez peut-être les remplacer par des exemples de contenu lorsque vous visionnerez votre contenu localement.

L’exemple d’extrait de code suivant charge le code nécessaire pour afficher les éléments HTML personnalisés. Utilisez cela si vous voulez développer l’apparence de votre modèle dans votre éditeur préféré plutôt que dans la console.

**Example**  

```
<script src="https://assets.crowd.aws/crowd-html-elements.js"></script>
```

### Création d’un exemple de tâche HTML simple
<a name="sms-custom-templates-step2-sample"></a>

Maintenant que vous disposez du modèle de tâche d’employé de base, vous pouvez utiliser cette rubrique pour créer un modèle de tâche HTML simple.

Voici un exemple d’entrée d’un fichier manifeste d’entrée.

```
{
  "source": "This train is really late.",
  "labels": [ "angry" , "sad", "happy" , "inconclusive" ],
  "header": "What emotion is the speaker feeling?"
}
```

Dans le modèle de tâche HTML, nous devons mapper les variables du fichier manifeste d’entrée au modèle. La variable de l’exemple de manifeste d’entrée serait mappée à l’aide de la syntaxe suivante **task.input.source**, **task.input.labels** et **task.input.header**.

Voici un exemple simple de modèle de tâche d’employé HTML pour l’analyse de tweets. Toutes les tâches commencent et se terminent par les éléments `<crowd-form> </crowd-form>`. Comme les éléments HTML `<form>` standard, tout votre code de formulaire doit figurer entre ces éléments. Ground Truth génère les tâches des employés directement à partir du contexte spécifié dans le modèle, sauf si vous implémentez une fonction Lambda de pré-annotation. L’objet `taskInput` renvoyé par Ground Truth ou [Lambda de pré-annotation](sms-custom-templates-step3-lambda-requirements.md#sms-custom-templates-step3-prelambda) est l’objet `task.input` de vos modèles.

Pour une simple tâche d’analyse de tweets , utilisez l’élément `<crowd-classifier>`. Il exige les attributs suivants :
+ *name* : nom de votre variable de sortie. Les annotations d’employé sont enregistrées sous ce nom de variable dans votre manifeste de sortie.
+ *categories* : tableau au format JSON des réponses possibles.
+ *header* : titre pour l’outil d’annotation

L’élément `<crowd-classifier>` nécessite au moins les trois éléments enfants suivants.
+ *<classification-target>* : texte que l’employé classera en fonction des options spécifiées dans l’attribut `categories` ci-dessus.
+ *<full-instructions>* : instructions disponibles à partir du lien « Afficher les instructions complètes » de l’outil. Cet attribut peut rester vide, mais nous vous recommandons de donner de bonnes instructions pour obtenir de meilleurs résultats.
+ *<short-instructions>* : brève description de la tâche qui s’affiche dans la barre latérale de l’outil. Cet attribut peut rester vide, mais nous vous recommandons de donner de bonnes instructions pour obtenir de meilleurs résultats.

Une version simple de cet outil se présenterait comme suit. La variable **\$1\$1 task.input.source \$1\$1** est ce qui spécifie les données source de votre fichier manifeste d’entrée. **\$1\$1 task.input.labels \$1 to\$1json \$1\$1** est un exemple de filtre de variable pour transformer le tableau en représentation JSON. L’attribut `categories` doit être JSON.

**Example Exemple d’utilisation de `crowd-classifier` avec l’exemple de représentation json du manifeste d’entrée**  

```
<script src="https://assets.crowd.aws/crowd-html-elements.js"></script>
<crowd-form>
  <crowd-classifier
    name="tweetFeeling"
    categories="='{{ task.input.labels | to_json }}'"
    header="{{ task.input.header }}'"
  >
     <classification-target>
       {{ task.input.source }}
     </classification-target>

    <full-instructions header="Sentiment Analysis Instructions">
      Try to determine the sentiment the author
      of the tweet is trying to express.
      If none seem to match, choose "cannot determine."
    </full-instructions>

    <short-instructions>
      Pick the term that best describes the sentiment of the tweet.
    </short-instructions>

  </crowd-classifier>
</crowd-form>
```

Vous pouvez copier et coller le code dans l'éditeur du flux de travail de création de tâches d'étiquetage de Ground Truth pour avoir un aperçu de l'outil, ou essayer une [démonstration de ce code sur CodePen.](https://codepen.io/MTGT/full/OqBvJw)

 [https://codepen.io/MTGT/full/OqBvJw](https://codepen.io/MTGT/full/OqBvJw) 

## Données d’entrée, actifs externes et votre modèle de tâches
<a name="sms-custom-templates-step2-template-input"></a>

Les sections suivantes décrivent l’utilisation d’actifs externes, les exigences relatives au format des données d’entrée et les circonstances dans lesquelles il convient d’envisager d’utiliser des fonctions Lambda de pré-annotation.

### Exigences de format des données d’entrée
<a name="sms-custom-template-input-manifest"></a>

Lorsque vous créez un fichier manifeste d’entrée à utiliser dans votre tâche d’étiquetage Ground Truth personnalisée, vous devez stocker les données dans Amazon S3. Les fichiers manifestes d'entrée doivent également être enregistrés dans le même fichier que celui Région AWS dans lequel votre tâche d'étiquetage Ground Truth personnalisée doit être exécutée. En outre, il peut être stocké dans n’importe quel compartiment Amazon S3 accessible au rôle de service IAM que vous utilisez pour exécuter votre tâche d’étiquetage personnalisée dans Ground Truth.

Les fichiers manifestes d’entrée doivent utiliser le format JSON ou lignes JSON délimité par de nouvelles lignes. Chaque ligne est délimitée par un saut de ligne standard, **\$1n** ou **\$1r\$1n**. Chaque ligne doit également être un objet JSON valide. 

En outre, chaque objet JSON du fichier manifeste doit contenir l’une des clés suivantes : `source-ref` ou `source`. La valeur des clés est interprétée comme suit :
+ `source-ref` : la source de l’objet est l’objet Amazon S3 spécifié dans la valeur. Utilisez cette valeur lorsque l’objet est un objet binaire, comme une image.
+ `source` : la source de l’objet est la valeur. Utilisez cette valeur lorsque l’objet est une valeur de texte.

Pour en savoir plus sur le formatage de vos fichiers manifestes d’entrée, consultez [Fichiers manifestes source](sms-input-data-input-manifest.md).

### Fonction Lambda de pré-annotation
<a name="sms-custom-template-input-lambda"></a>

Vous pouvez éventuellement spécifier une fonction *Lambda de pré-annotation* pour gérer la manière dont les données de votre fichier manifeste d’entrée sont traitées avant l’étiquetage. Si vous avez spécifié la paire clé-valeur `isHumanAnnotationRequired`, vous devez utiliser une fonction Lambda de pré-annotation. Lorsque Ground Truth envoie à la fonction Lambda de pré-annotation une requête au format JSON, elle utilise les schémas suivants.

**Example objet de données identifié par la paire clé-valeur `source-ref`**  

```
{
  "version": "2018-10-16",
  "labelingJobArn": arn:aws:lambda:us-west-2:555555555555:function:my-function
  "dataObject" : {
    "source-ref": s3://input-data-bucket/data-object-file-name
  }
}
```

**Example objet de données identifié par la paire clé-valeur `source`**  

```
{
      "version": "2018-10-16",
      "labelingJobArn" : arn:aws:lambda:us-west-2:555555555555:function:my-function
      "dataObject" : {
        "source": Sue purchased 10 shares of the stock on April 10th, 2020
      }
    }
```

Voici la réponse attendue de la fonction Lambda lorsque `isHumanAnnotationRequired` est utilisé.

```
{
  "taskInput": {
    "source": "This train is really late.",
    "labels": [ "angry" , "sad" , "happy" , "inconclusive" ],
    "header": "What emotion is the speaker feeling?"
  },
  "isHumanAnnotationRequired": False
}
```

### Utilisation de ressources externes
<a name="sms-custom-template-step2-UI-external"></a>

Les modèles personnalisés Amazon SageMaker Ground Truth permettent d'intégrer des scripts externes et des feuilles de style. Par exemple, le bloc de code suivant montre comment ajouter une feuille de style située dans `https://www.example.com/my-enhancement-styles.css` à votre modèle.

**Example**  

```
<script src="https://www.example.com/my-enhancment-script.js"></script>
<link rel="stylesheet" type="text/css" href="https://www.example.com/my-enhancement-styles.css">
```

Si vous rencontrez des erreurs, veillez à ce que votre serveur d’origine envoie le type MIME et les en-têtes d’encodage corrects avec les ressources.

Par exemple, types d’encodage et MIME pour les scripts distants : `application/javascript;CHARSET=UTF-8`.

Type d’encodage et MIME pour les feuilles de style distantes : `text/css;CHARSET=UTF-8`.

## Les données de sortie et votre modèle de tâche
<a name="sms-custom-templates-step2-template-output"></a>

Les sections suivantes décrivent les données de sortie d’une tâche d’étiquetage personnalisée et indiquent dans quels cas envisager d’utiliser une fonction Lambda de post-annotation.

### Données de sortie
<a name="sms-custom-templates-data"></a>

Une fois votre tâche d’étiquetage personnalisée terminée, les données sont enregistrées dans le compartiment Amazon S3 spécifié au moment où la tâche d’étiquetage a été créée. Les données sont enregistrées dans un fichier `output.manifest`.

**Note**  
*labelAttributeName*est une variable d'espace réservé. Dans votre sortie, il s’agit soit du nom de votre tâche d’étiquetage, soit du nom de l’attribut d’étiquette que vous spécifiez lorsque vous créez la tâche d’étiquetage.
+ `source` ou `source-ref` : il a été demandé aux employés d’étiqueter la chaîne ou une URI S3. 
+ `labelAttributeName` : un dictionnaire contenant le contenu d’étiquette consolidé issu de la [fonction Lambda de post-annotation](sms-custom-templates-step3-lambda-requirements.md#sms-custom-templates-step3-postlambda). Si aucune fonction Lambda de post-annotation n’est spécifiée, ce dictionnaire sera vide.
+ `labelAttributeName-metadata` : les métadonnées de votre tâche d’étiquetage personnalisée ont été ajoutées par Ground Truth. 
+ `worker-response-ref` : l’URI S3 du compartiment dans lequel les données sont enregistrées. Si une fonction Lambda de post-annotation est spécifiée, cette paire clé-valeur ne sera pas présente.

Dans cet exemple, l’objet JSON est mis en forme afin de faciliter la lecture. Dans le fichier de sortie proprement dit, l’objet JSON se trouve sur une seule ligne.

```
{
  "source" : "This train is really late.",
  "labelAttributeName" : {},
  "labelAttributeName-metadata": { # These key values pairs are added by Ground Truth
    "job_name": "test-labeling-job",
    "type": "groundTruth/custom",
    "human-annotated": "yes",
    "creation_date": "2021-03-08T23:06:49.111000",
    "worker-response-ref": "s3://amzn-s3-demo-bucket/test-labeling-job/annotations/worker-response/iteration-1/0/2021-03-08_23:06:49.json"
  }
}
```

### Utilisation d’une fonction Lambda de post-annotation pour consolider les résultats de vos employés
<a name="sms-custom-templates-consolidation"></a>

Par défaut, Ground Truth enregistre les réponses des employés non traitées dans Amazon S3. Pour avoir un contrôle plus précis sur le traitement des réponses, vous pouvez spécifier une *fonction Lambda de post-annotation*. Par exemple, une fonction Lambda de post-annotation peut être utilisée pour consolider les annotations si plusieurs employés ont étiqueté le même objet de données. Pour en savoir plus sur la création de fonctions Lambda de post-annotation, consultez [Lambda de post-annotation](sms-custom-templates-step3-lambda-requirements.md#sms-custom-templates-step3-postlambda).

Si vous souhaitez utiliser une fonction Lambda de post-annotation, elle doit être spécifiée dans le [https://docs.aws.amazon.com//sagemaker/latest/APIReference/API_AnnotationConsolidationConfig.html](https://docs.aws.amazon.com//sagemaker/latest/APIReference/API_AnnotationConsolidationConfig.html) d’une demande `CreateLabelingJob`.

Pour en savoir plus sur le fonctionnement de la consolidation des annotations, consultez [Consolidation d’annotation](sms-annotation-consolidation.md).

# Ajout de l’automatisation avec Liquid
<a name="sms-custom-templates-step2-automate"></a>

Notre système de modèle personnalisé utilise [Liquid](https://shopify.github.io/liquid/) pour l’automatisation. Il s’agit d’un langage de balisage open source en ligne. Dans Liquid, le texte entre accolades simples et symboles de pourcentage est une instruction ou *balise* qui exécute une opération telle qu’un flux de contrôle ou une itération. Le texte entre accolades doubles est une variable ou un *objet* qui génère sa valeur.

L’utilisation la plus courante de Liquid consistera à analyser les données provenant de votre fichier manifeste d’entrée et à en extraire les variables appropriées pour créer la tâche. Ground Truth génère automatiquement les tâches, sauf si une fonction Lambda de pré-annotation est spécifiée. L’objet `taskInput` renvoyé par Ground Truth ou votre [Lambda de pré-annotation](sms-custom-templates-step3-lambda-requirements.md#sms-custom-templates-step3-prelambda) est l’objet `task.input` de vos modèles.

Les propriétés de votre manifeste d’entrée sont transmises à votre modèle en tant que `event.dataObject`.

**Example objet des données de manifeste**  

```
{
  "source": "This is a sample text for classification",
  "labels": [ "angry" , "sad" , "happy" , "inconclusive" ],
  "header": "What emotion is the speaker feeling?"
}
```

**Example exemple de code HTML à l’aide des variables**  

```
<crowd-classifier 
  name='tweetFeeling'
  categories='{{ task.input.labels | to_json }}'
  header='{{ task.input.header }}' >
<classification-target>
  {{ task.input.source }}
</classification-target>
```

Notez l’ajout de ` | to_json` à la propriété `labels` ci-dessus. C’est un filtre qui transforme le tableau manifeste d’entrée en représentation JSON du tableau. Les filtres de variables sont expliqués en la section suivante.

La liste suivante comprend deux types de balises Liquid qui peuvent être utiles pour automatiser le traitement des données source de modèle. La sélection de l’un des types de balises suivants vous redirige vers la documentation Liquid.
+ [Contrôle de flux](https://shopify.github.io/liquid/tags/control-flow/) : inclut des opérateurs logiques de programmation tels que `if/else`, `unless` et `case/when`.
+ [Itération](https://shopify.github.io/liquid/tags/iteration/) : vous permet d’exécuter des blocs de code de façon répétée en utilisant des instructions comme les boucles for. 

  Pour un exemple de modèle HTML qui utilise des éléments Liquid pour créer une boucle for, voir [translation-review-and-correction.liquid.html](https://github.com/aws-samples/amazon-sagemaker-ground-truth-task-uis/blob/8ae02533ea5a91087561b1daecd0bc22a37ca393/text/translation-review-and-correction.liquid.html) dans. GitHub 

Pour obtenir plus d’informations et la documentation, consultez la [page d’accueil de Liquid](https://shopify.github.io/liquid/).

## Filtres de variables
<a name="sms-custom-templates-step2-automate-filters"></a>

Outre les actions et [filtres Liquid](https://shopify.github.io/liquid/filters/abs/) standard, Ground Truth propose quelques filtres supplémentaires. Les filtres sont appliqués en plaçant une barre verticale (`|`) après le nom de la variable, puis en spécifiant un nom de filtre. Les filtres peuvent être associés sous la forme de :

**Example**  

```
{{ <content> | <filter> | <filter> }}
```

### Échappement automatique et échappement explicite
<a name="sms-custom-templates-step2-automate-filters-autoescape"></a>

Par défaut, les entrées seront placées dans une séquence d’échappement HTML pour éviter toute confusion entre le texte de votre variable et le code HTML. Vous pouvez ajouter explicitement le filtre `escape` afin que les personnes qui lisent la source de votre modèle comprennent qu’il s’agit d’un échappement.

### escape\$1once
<a name="sms-custom-templates-step2-automate-escapeonce"></a>

`escape_once` s’assure que votre code ne sera pas placé dans une seconde séquence d’échappement alors qu’il l’est déjà. Par exemple, afin que &amp; ne devienne pas &amp;amp;.

### skip\$1autoescape
<a name="sms-custom-templates-step2-automate-skipautoescape"></a>

`skip_autoescape` est utile si votre contenu est destiné à être utilisé en tant que code HTML. Par exemple, vous pouvez avoir quelques paragraphes de texte et des images dans les instructions complètes d’un cadre de délimitation.

**Utilisez `skip_autoescape` avec modération**  
La bonne pratique consiste à éviter de transmettre du code fonctionnel ou du balisage avec `skip_autoescape`, sauf si vous êtes absolument certain que vous maîtrisez parfaitement ce qui est transmis. Si vous transmettez l’entrée d’un utilisateur, vous risquez d’exposer vos employés à une attaque de script intersite.

### to\$1json
<a name="sms-custom-templates-step2-automate-tojson"></a>

`to_json`encodera ce que vous lui transmettez en JSON (JavaScript Object Notation). Si vous lui fournissez un objet, il va le sérialiser.

### grant\$1read\$1access
<a name="sms-custom-templates-step2-automate-grantreadaccess"></a>

`grant_read_access` prend un URI S3 et l’encode dans une URL HTTPS avec un jeton d’accès de courte durée pour cette ressource. Cela permet de montrer aux employés les objets photo, audio ou vidéo stockés dans des compartiments S3 qui ne sont pas autrement accessibles publiquement.

### s3\$1presign
<a name="sms-custom-templates-step2-automate-s3"></a>

 Le filtre `s3_presign` fonctionne de la même manière que le filtre `grant_read_access`. `s3_presign` prend un URI Amazon S3 et l’encode dans une URL HTTPS avec un jeton d’accès de courte durée pour cette ressource. Cela permet de montrer des objets photo, audio ou vidéo stockés dans des compartiments S3 qui ne sont pas autrement accessibles publiquement aux employés.

**Example des filtres de variables**  
Input  

```
auto-escape: {{ "Have you read 'James & the Giant Peach'?" }}
explicit escape: {{ "Have you read 'James & the Giant Peach'?" | escape }}
explicit escape_once: {{ "Have you read 'James &amp; the Giant Peach'?" | escape_once }}
skip_autoescape: {{ "Have you read 'James & the Giant Peach'?" | skip_autoescape }}
to_json: {{ jsObject | to_json }}                
grant_read_access: {{ "s3://amzn-s3-demo-bucket/myphoto.png" | grant_read_access }}
s3_presign: {{ "s3://amzn-s3-demo-bucket/myphoto.png" | s3_presign }}
```

**Example**  
Output  

```
auto-escape: Have you read &#39;James &amp; the Giant Peach&#39;?
explicit escape: Have you read &#39;James &amp; the Giant Peach&#39;?
explicit escape_once: Have you read &#39;James &amp; the Giant Peach&#39;?
skip_autoescape: Have you read 'James & the Giant Peach'?
to_json: { "point_number": 8, "coords": [ 59, 76 ] }
grant_read_access: https://s3.amazonaws.com/amzn-s3-demo-bucket/myphoto.png?<access token and other params>
s3_presign: https://s3.amazonaws.com/amzn-s3-demo-bucket/myphoto.png?<access token and other params>
```

**Example d’un modèle de classification automatique.**  
Pour automatiser l’exemple de classification de texte simple, remplacez le texte du tweet par une variable.  
Le modèle de classification de texte se trouve ci-dessous et comprend l’automatisation. Ils changes/additions sont surlignés en gras.  

```
<script src="https://assets.crowd.aws/crowd-html-elements.js"></script>
<crowd-form>
  <crowd-classifier 
    name="tweetFeeling"
    categories="['positive', 'negative', 'neutral', 'cannot determine']"
    header="Which term best describes this tweet?" 
  >
    <classification-target>
       {{ task.input.source }}
    </classification-target>

    <full-instructions header="Analyzing a sentiment">
      Try to determine the feeling the author 
      of the tweet is trying to express. 
      If none seem to match, choose "other."
    </full-instructions>

    <short-instructions>
      Pick the term best describing the sentiment 
      of the tweet. 
    </short-instructions>

  </crowd-classifier>
</crowd-form>
```
Le texte du tweet de l’exemple précédent est désormais remplacé par un objet. L’objet `entry.taskInput` utilise `source` (ou un autre nom que vous spécifiez dans votre fonction de prétraitement Lambda) comme nom de propriété pour le texte et est inséré directement dans le code HTML puisqu’il se trouve entre accolades doubles.

# Traitement des données dans un flux de travail d'étiquetage personnalisé avec AWS Lambda
<a name="sms-custom-templates-step3"></a>

Dans cette rubrique, vous découvrirez comment déployer des fonctions [AWS Lambda](https://aws.amazon.com/lambda/) facultatives lors de la création d’un flux de travail d’étiquetage personnalisé. Vous pouvez spécifier deux types de fonctions Lambda à utiliser avec votre flux de travail d’étiquetage personnalisé.
+ *Lambda de pré-annotation* : cette fonction prétraite chaque objet de données envoyé à votre tâche d’étiquetage avant de l’envoyer aux employés.
+ *Post-annotation Lambda* : cette fonction traite les résultats une fois que les employés soumettent une tâche. Si vous spécifiez plusieurs employés par objet de données, cette fonction peut inclure une logique de consolidation des annotations.

Si vous êtes un nouvel utilisateur de Lambda et de Ground Truth, nous vous recommandons d’utiliser les pages de cette section comme suit :

1. Tout d’abord, examinez [Utilisation des fonctions Lambda de pré-annotation et post-annotationUtilisation des fonctions Lambda](sms-custom-templates-step3-lambda-requirements.md).

1. Ensuite, utilisez la page [Ajoutez les autorisations requises à utiliser AWS Lambda avec Ground Truth](sms-custom-templates-step3-lambda-permissions.md) pour en savoir plus sur les exigences en matière de sécurité et d’autorisation pour utiliser vos fonctions Lambda de pré-annotation et post-annotation dans une tâche d’étiquetage personnalisée Ground Truth.

1. Ensuite, vous devez accéder à la console Lambda ou utiliser celle de Lambda APIs pour créer vos fonctions. Utiliser la section [Création de fonctions Lambda à l’aide des modèles Ground Truth](sms-custom-templates-step3-lambda-create.md) pour apprendre à créer des fonctions Lambda.

1. Pour savoir comment vérifier vos fonctions Lambda, consultez [Test de fonctions Lambda de pré-annotation et post-annotation](sms-custom-templates-step3-lambda-test.md).

1. Après avoir créé les fonctions Lambda de pré-annotation et post-traitement, sélectionnez-les dans la section **Lambda functions (Fonctions Lambda)** qui se trouve après l’éditeur de code pour votre code HTML personnalisé dans la console Ground Truth. Pour savoir comment utiliser ces fonctions dans une demande d’API `CreateLabelingJob`, consultez [Création d’une tâche d’étiquetage (API)](sms-create-labeling-job-api.md).

Pour un didacticiel de flux de travail d’étiquetage personnalisé qui inclut des fonctions Lambda de pré-annotation et post-annotation, consultez [Modèle de démonstration : annotation d’images avec `crowd-bounding-box`](sms-custom-templates-step2-demo1.md).

**Topics**
+ [Utilisation des fonctions Lambda de pré-annotation et post-annotation](sms-custom-templates-step3-lambda-requirements.md)
+ [Ajoutez les autorisations requises à utiliser AWS Lambda avec Ground Truth](sms-custom-templates-step3-lambda-permissions.md)
+ [Création de fonctions Lambda à l’aide des modèles Ground Truth](sms-custom-templates-step3-lambda-create.md)
+ [Test de fonctions Lambda de pré-annotation et post-annotation](sms-custom-templates-step3-lambda-test.md)

# Utilisation des fonctions Lambda de pré-annotation et post-annotation
<a name="sms-custom-templates-step3-lambda-requirements"></a>

Utilisez ces rubriques pour en savoir plus sur la syntaxe des requêtes envoyées aux fonctions Lambda pré-annotation et post-annotation, ainsi que sur la syntaxe de réponse requise que Ground Truth utilise dans des flux de travail d’étiquetage personnalisés.

**Topics**
+ [Lambda de pré-annotation](#sms-custom-templates-step3-prelambda)
+ [Lambda de post-annotation](#sms-custom-templates-step3-postlambda)

## Lambda de pré-annotation
<a name="sms-custom-templates-step3-prelambda"></a>

Avant qu’une tâche d’étiquetage ne soit envoyée à l’employé, une fonction Lambda de pré-annotation facultative peut être invoquée.

Ground Truth envoie à votre fonction Lambda une requête au format JSON pour fournir des détails sur la tâche d’étiquetage et l’objet de données.

Les exemples suivants sont deux exemples de requêtes au format JSON.

------
#### [ Data object identified with "source-ref" ]

```
{
    "version": "2018-10-16",
    "labelingJobArn": <labelingJobArn>
    "dataObject" : {
        "source-ref": <s3Uri>
    }
}
```

------
#### [ Data object identified with "source" ]

```
{
    "version": "2018-10-16",
    "labelingJobArn": <labelingJobArn>
    "dataObject" : {
        "source": <string>
    }
}
```

------

 La liste suivante contient les schémas de requête de pré-annotation. Chaque paramètre est décrit ci-dessous.
+ `version` (chaîne) : il s’agit d’un numéro de version utilisé en interne par Ground Truth.
+ `labelingJobArn` (chaîne) : il s’agit du Amazon Resource Name, ou ARN, de votre tâche d’étiquetage. Cet ARN peut être utilisé pour référencer la tâche d’étiquetage lors de l’utilisation d’opérations d’API Ground Truth telles que `DescribeLabelingJob`.
+ La propriété `dataObject` (objet JSON) : la clé contient une seule ligne JSON, provenant de votre fichier manifeste source ou envoyée par Amazon SNS. Les objets de ligne JSON de votre manifeste peuvent comporter jusqu’à 100 kilo-octets de taille et contenir une grande variété de données. Pour une tâche très basique d’annotation d’image, la propriété `dataObject` JSON peut simplement contenir une clé `source-ref`, identifiant l’image à annoter. Si l’objet de données (par exemple, une ligne de texte) est inclus directement dans le fichier manifeste source, l’objet de données est identifié par `source`. Si vous créez une tâche de vérification ou d’ajustement, cette ligne peut contenir des données d’étiquettes et des métadonnées provenant de la tâche d’étiquetage précédente.

Les onglets d’exemples suivants présentent des exemples de requête de pré-annotation. Chaque paramètre de ces exemples de requêtes est expliqué sous le tableau à onglets.

------
#### [ Data object identified with "source-ref" ]

```
{
    "version": "2018-10-16",
    "labelingJobArn": "arn:aws:sagemaker:us-west-2:111122223333:labeling-job/<labeling_job_name>"
    "dataObject" : {
        "source-ref": "s3://input-data-bucket/data-object-file-name"
    }
}
```

------
#### [ Data object identified with "source" ]

```
{
    "version": "2018-10-16",
    "labelingJobArn": "arn:aws:sagemaker:<aws_region>:111122223333:labeling-job/<labeling_job_name>"
    "dataObject" : {
        "source": "Sue purchased 10 shares of the stock on April 10th, 2020"
    }
}
```

------

En retour, Ground Truth nécessite une réponse formatée comme suit :

**Example de données de retour attendues**  

```
{
    "taskInput": <json object>,
    "isHumanAnnotationRequired": <boolean> # Optional
}
```

Dans l’exemple précédent, `<json object>` doit contenir *toutes* les données dont votre modèle de tâche d’employé a besoin. Si vous accomplissez une tâche de cadre de délimitation où les instructions restent toujours les mêmes, il peut s’agir simplement de la ressource HTTP(S) ou Amazon S3 de votre fichier image. S’il s’agit d’une tâche d’analyse de ressenti et que différents objets peuvent comporter des choix différents, la référence de l’objet est une chaîne de caractères et les choix sont un tableau de chaînes de caractères.

**Implications de `isHumanAnnotationRequired`**  
Cette valeur est facultative, car elle prend par défaut la valeur `true`. Vous paramétrez cette valeur de manière explicite principalement lorsque vous souhaitez empêcher cet objet de données d’être étiquetés par des employés humains. 

Si vous avez un mélange d’objets dans votre manifeste, certains d’entre eux nécessitant une annotation humaine et d’autres pas, vous pouvez inclure une valeur `isHumanAnnotationRequired` dans chaque objet de données. Vous pouvez ajouter une logique à votre pré-annotation Lambda pour déterminer dynamiquement si un objet nécessite une annotation, et définir cette valeur booléenne en conséquence.

### Exemples de fonctions Lambda de pré-annotation
<a name="sms-custom-templates-step3-prelambda-example"></a>

La fonction Lambda de pré-annotation de base suivante accède à l’objet JSON dans `dataObject` à partir de la requête initiale, et le renvoie dans le paramètre `taskInput`.

```
import json

def lambda_handler(event, context):
    return {
        "taskInput":  event['dataObject']
    }
```

En supposant que le fichier manifeste source utilise `"source-ref"` pour identifier les objets de données, le modèle de tâche d’employé utilisé dans la même tâche d’étiquetage que cette pré-annotation Lambda doit inclure un élément Liquid comme le suivant pour intégrer (les données) `dataObject` :

```
{{ task.input.source-ref | grant_read_access }}
```

Si le fichier manifeste source a utilisé `source` pour identifier l’objet de données, le modèle de tâche employé peut intégrer (les données) `dataObject` avec les éléments suivants :

```
{{ task.input.source }}
```

L’exemple Lambda de pré-annotation suivant inclut une logique pour identifier la clé utilisée dans `dataObject`, et pour pointer vers cet objet de données en utilisant `taskObject` dans la déclaration de retour de Lambda.

```
import json

def lambda_handler(event, context):

    # Event received
    print("Received event: " + json.dumps(event, indent=2))

    # Get source if specified
    source = event['dataObject']['source'] if "source" in event['dataObject'] else None

    # Get source-ref if specified
    source_ref = event['dataObject']['source-ref'] if "source-ref" in event['dataObject'] else None

    # if source field present, take that otherwise take source-ref
    task_object = source if source is not None else source_ref

    # Build response object
    output = {
        "taskInput": {
            "taskObject": task_object
        },
        "humanAnnotationRequired": "true"
    }

    print(output)
    # If neither source nor source-ref specified, mark the annotation failed
    if task_object is None:
        print(" Failed to pre-process {} !".format(event["labelingJobArn"]))
        output["humanAnnotationRequired"] = "false"

    return output
```

## Lambda de post-annotation
<a name="sms-custom-templates-step3-postlambda"></a>

Lorsque tous les employés ont annoté l’objet de données ou lorsque [https://docs.aws.amazon.com/sagemaker/latest/APIReference/API_HumanLoopConfig.html#SageMaker-Type-HumanLoopConfig-TaskAvailabilityLifetimeInSeconds](https://docs.aws.amazon.com/sagemaker/latest/APIReference/API_HumanLoopConfig.html#SageMaker-Type-HumanLoopConfig-TaskAvailabilityLifetimeInSeconds) a été atteint, selon la première éventualité, Ground Truth envoie ces annotations à votre fonction Lambda de post-annotation. Cette fonction Lambda est généralement utilisée pour [Consolidation d’annotation](sms-annotation-consolidation.md).

**Note**  
Pour voir un exemple de fonction Lambda post-consolidation, [consultez](https://github.com/aws-samples/aws-sagemaker-ground-truth-recipe/blob/master/aws_sagemaker_ground_truth_sample_lambda/annotation_consolidation_lambda.py) le fichier annotation\$1consolidation\$1lambda.py dans [aws-sagemaker-ground-truthle](https://github.com/aws-samples/aws-sagemaker-ground-truth-recipe) GitHub référentiel -recipe.

Le bloc de code suivant contient le schéma de requête de post-annotation. Chaque paramètre est décrit dans la liste à puces suivante.

```
{
    "version": "2018-10-16",
    "labelingJobArn": <string>,
    "labelCategories": [<string>],
    "labelAttributeName": <string>,
    "roleArn" : <string>,
    "payload": {
        "s3Uri": <string>
    }
 }
```
+ `version` (chaîne) : un numéro de version utilisé en interne par Ground Truth.
+ `labelingJobArn` (chaîne) : l’Amazon Resource Name, ou ARN, de votre tâche d’étiquetage. Cet ARN peut être utilisé pour référencer la tâche d'étiquetage lors de l'utilisation d'opérations d'API Ground Truth telles que `DescribeLabelingJob`.
+ `labelCategories` (liste des chaînes) : inclut les catégories d’étiquettes et les autres attributs que vous avez spécifiés dans la console ou que vous incluez dans le fichier de configuration des catégories d’étiquettes.
+ `labelAttributeName` (chaîne) : soit le nom de votre tâche d’étiquetage, soit le nom de l’attribut d’étiquette que vous spécifiez lorsque vous créez la tâche d’étiquetage.
+ `roleArn` (chaîne) : Amazon Resource Name (ARN) du rôle d’exécution IAM que vous spécifiez lorsque vous créez la tâche d’étiquetage. 
+ `payload` (objet JSON) : un JSON qui inclut une clé `s3Uri`, identifiant l’emplacement des données d’annotation pour cet objet de données dans Amazon S3. Le deuxième bloc de code ci-dessous présente un exemple de ce fichier d’annotation.

Le bloc de code suivant contient un exemple de requête de post-annotation. Chaque paramètre de cet exemple de requête est expliqué sous le bloc de code.

**Example d’une requête Lambda de post-annotation**  

```
{
    "version": "2018-10-16",
    "labelingJobArn": "arn:aws:sagemaker:us-west-2:111122223333:labeling-job/labeling-job-name",
    "labelCategories": ["Ex Category1","Ex Category2", "Ex Category3"],
    "labelAttributeName": "labeling-job-attribute-name",
    "roleArn" : "arn:aws:iam::111122223333:role/role-name",
    "payload": {
        "s3Uri": "s3://amzn-s3-demo-bucket/annotations.json"
    }
 }
```

**Note**  
Si aucun employé n’utilise l’objet de données et que `TaskAvailabilityLifetimeInSeconds` a été atteint, l’objet de données est marqué comme ayant échoué et n’est pas inclus dans l’invocation Lambda de post-annotation.

Le bloc de code suivant contient le schéma de charge utile. Il s’agit du fichier qui est indiqué par le paramètre `s3Uri` dans l’objet JSON `payload` de requête Lambda de post-annotation. Par exemple, si le bloc de code précédent est la requête Lambda post-annotation, le fichier d’annotation suivant se trouve dans `s3://amzn-s3-demo-bucket/annotations.json`.

Chaque paramètre est décrit dans la liste à puces suivante.

**Example d’un fichier d’annotation**  

```
[
    {
        "datasetObjectId": <string>,
        "dataObject": {
            "s3Uri": <string>,
            "content": <string>
        },
        "annotations": [{
            "workerId": <string>,
            "annotationData": {
                "content": <string>,
                "s3Uri": <string>
            }
       }]
    }
]
```
+ `datasetObjectId` (chaîne) : identifie un ID unique que Ground Truth attribue à chaque objet de données que vous envoyez à la tâche d’étiquetage.
+ `dataObject` (objet JSON) : l’objet de données étiqueté. Si l’objet de données est inclus dans le fichier manifeste source et est identifié à l’aide de la clé `source` (par exemple, une chaîne), `dataObject` inclut une clé `content`, qui identifie l’objet de données. Sinon, l’emplacement de l’objet de données (par exemple, un lien ou un URI S3) est identifié par `s3Uri`.
+ `annotations` (liste des objets JSON) : cette liste contient un objet JSON unique pour chaque annotation soumise par les employés pour ce `dataObject`. Un seul objet JSON contient un `workerId` qui peut être utilisé pour identifier l’employé qui a soumis cette annotation. La clé `annotationData` contient l’un des éléments suivants :
  + `content` (string) : contient les données d’annotation. 
  + `s3Uri` (chaîne) : contient un URI S3 qui identifie l’emplacement des données d’annotation.

Le tableau suivant contient des exemples de contenu que vous pouvez trouver dans les données utiles pour différents types d’annotations.

------
#### [ Named Entity Recognition Payload ]

```
[
    {
      "datasetObjectId": "1",
      "dataObject": {
        "content": "Sift 3 cups of flour into the bowl."
      },
      "annotations": [
        {
          "workerId": "private.us-west-2.ef7294f850a3d9d1",
          "annotationData": {
            "content": "{\"crowd-entity-annotation\":{\"entities\":[{\"endOffset\":4,\"label\":\"verb\",\"startOffset\":0},{\"endOffset\":6,\"label\":\"number\",\"startOffset\":5},{\"endOffset\":20,\"label\":\"object\",\"startOffset\":15},{\"endOffset\":34,\"label\":\"object\",\"startOffset\":30}]}}"
          }
        }
      ]
    }
]
```

------
#### [ Semantic Segmentation Payload ]

```
[
    {
      "datasetObjectId": "2",
      "dataObject": {
        "s3Uri": "s3://amzn-s3-demo-bucket/gt-input-data/images/bird3.jpg"
      },
      "annotations": [
        {
          "workerId": "private.us-west-2.ab1234c5678a919d0",
          "annotationData": {
            "content": "{\"crowd-semantic-segmentation\":{\"inputImageProperties\":{\"height\":2000,\"width\":3020},\"labelMappings\":{\"Bird\":{\"color\":\"#2ca02c\"}},\"labeledImage\":{\"pngImageData\":\"iVBOR...\"}}}"
          }
        }
      ]
    }
  ]
```

------
#### [ Bounding Box Payload ]

```
[
    {
      "datasetObjectId": "0",
      "dataObject": {
        "s3Uri": "s3://amzn-s3-demo-bucket/gt-input-data/images/bird1.jpg"
      },
      "annotations": [
        {
          "workerId": "private.us-west-2.ab1234c5678a919d0",
          "annotationData": {
            "content": "{\"boundingBox\":{\"boundingBoxes\":[{\"height\":2052,\"label\":\"Bird\",\"left\":583,\"top\":302,\"width\":1375}],\"inputImageProperties\":{\"height\":2497,\"width\":3745}}}"
          }
        }
      ]
    }
 ]
```

------

Votre fonction Lambda de post-annotation peut contenir une logique similaire à la suivante pour parcourir et accéder à toutes les annotations contenues dans la requête. Pour un exemple complet, consultez le [fichier annotation\$1consolidation\$1lambda.py](https://github.com/aws-samples/aws-sagemaker-ground-truth-recipe/blob/master/aws_sagemaker_ground_truth_sample_lambda/annotation_consolidation_lambda.py) dans le GitHub référentiel [aws-sagemaker-ground-truth-recipe](https://github.com/aws-samples/aws-sagemaker-ground-truth-recipe). Dans cet GitHub exemple, vous devez ajouter votre propre logique de consolidation des annotations. 

```
for i in range(len(annotations)):
    worker_id = annotations[i]["workerId"]
    annotation_content = annotations[i]['annotationData'].get('content')
    annotation_s3_uri = annotations[i]['annotationData'].get('s3uri')
    annotation = annotation_content if annotation_s3_uri is None else s3_client.get_object_from_s3(
        annotation_s3_uri)
    annotation_from_single_worker = json.loads(annotation)

    print("{} Received Annotations from worker [{}] is [{}]"
            .format(log_prefix, worker_id, annotation_from_single_worker))
```

**Astuce**  
Lorsque vous exécutez des algorithmes de consolidation sur les données, vous pouvez utiliser un service de base de données AWS pour stocker les résultats, ou vous pouvez renvoyer les résultats traités à Ground Truth. Les données que vous renvoyez à Ground Truth sont stockées dans des manifestes d’annotation consolidés dans le compartiment S3 spécifié pour la sortie lors de la configuration de la tâche d’étiquetage.

En retour, Ground Truth nécessite une réponse formatée comme suit :

**Example de données de retour attendues**  

```
[
   {        
        "datasetObjectId": <string>,
        "consolidatedAnnotation": {
            "content": {
                "<labelattributename>": {
                    # ... label content
                }
            }
        }
    },
   {        
        "datasetObjectId": <string>,
        "consolidatedAnnotation": {
            "content": {
                "<labelattributename>": {
                    # ... label content
                }
            }
        }
    }
    .
    .
    .
]
```
À ce stade, toutes les données que vous envoyez à votre compartiment S3, autres que `datasetObjectId`, sont dans l’objet `content`.

Lorsque vous retournez des annotations dans `content`, cela génère une entrée dans le manifeste de sortie de votre tâche, comme suit :

**Example de format d’étiquette dans le manifeste de sortie**  

```
{  "source-ref"/"source" : "<s3uri or content>", 
   "<labelAttributeName>": {
        # ... label content from you
    },   
   "<labelAttributeName>-metadata": { # This will be added by Ground Truth
        "job_name": <labelingJobName>,
        "type": "groundTruth/custom",
        "human-annotated": "yes", 
        "creation_date": <date> # Timestamp of when received from Post-labeling Lambda
    }
}
```

En raison de la nature potentiellement complexe d’un modèle personnalisé et des données qu’il collecte, Ground Truth n’offre pas de traitement ou d’analyse des données.

# Ajoutez les autorisations requises à utiliser AWS Lambda avec Ground Truth
<a name="sms-custom-templates-step3-lambda-permissions"></a>

Vous devrez peut-être configurer tout ou partie des éléments suivants pour créer et utiliser AWS Lambda avec Ground Truth. 
+ Vous devez accorder à un rôle ou à un utilisateur IAM (collectivement, une entité IAM) l'autorisation de créer les fonctions Lambda avant et après l'annotation à l'aide de AWS Lambda, et de les choisir lors de la création de la tâche d'étiquetage. 
+ Le rôle d’exécution IAM spécifié, lorsque la tâche d’étiquetage est configurée, doit être autorisé à invoquer les fonctions Lambda de pré-annotation et de post-annotation. 
+ Les fonctions Lambda post-annotation peuvent avoir besoin d’une autorisation pour accéder à Amazon S3.

Utilisez les sections suivantes pour apprendre comment créer les entités IAM et accorder des autorisations décrites ci-dessus.

**Topics**
+ [Autoriser la création et la sélection d'une AWS Lambda fonction](#sms-custom-templates-step3-postlambda-create-perms)
+ [Accorder au rôle d'exécution IAM l'autorisation d'invoquer AWS Lambda des fonctions](#sms-custom-templates-step3-postlambda-execution-role-perms)
+ [Accorder des autorisations Lambda de post-annotation pour accéder à l’annotation](#sms-custom-templates-step3-postlambda-perms)

## Autoriser la création et la sélection d'une AWS Lambda fonction
<a name="sms-custom-templates-step3-postlambda-create-perms"></a>

Si vous n'avez pas besoin d'autorisations granulaires pour développer des fonctions Lambda avant et après l'annotation, vous pouvez associer AWS la `AWSLambda_FullAccess` politique gérée à un utilisateur ou à un rôle. Cette politique accorde des autorisations étendues pour utiliser toutes les fonctionnalités Lambda, ainsi que l'autorisation d'effectuer des actions dans d'autres AWS services avec lesquels Lambda interagit.

Pour créer une politique plus précise pour les cas d'utilisation sensibles à la sécurité, reportez-vous à la documentation [Politiques IAM basées sur l'identité pour Lambda](https://docs.aws.amazon.com/lambda/latest/dg/access-control-identity-based.html) dans le guide du AWS Lambda développeur pour savoir comment créer une politique IAM adaptée à votre cas d'utilisation. 

**Stratégies d’utilisation de la console Lambda**

Si vous souhaitez autoriser une entité IAM à utiliser la console Lambda, [consultez la section Utilisation de la console Lambda dans le](https://docs.aws.amazon.com/lambda/latest/dg/security_iam_id-based-policy-examples.html#security_iam_id-based-policy-examples-console) manuel du développeur. AWS Lambda 

En outre, si vous souhaitez que l'utilisateur puisse accéder aux fonctions de pré-annotation et de post-annotation de Ground Truth Starter et les déployer AWS Serverless Application Repository à l'aide de la console Lambda, vous devez spécifier l'*`<aws-region>`*endroit où vous souhaitez déployer les fonctions (il doit s'agir de la même AWS région que celle utilisée pour créer la tâche d'étiquetage) et ajouter la politique suivante au rôle IAM.

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "serverlessrepo:ListApplicationVersions",
                "serverlessrepo:GetApplication",
                "serverlessrepo:CreateCloudFormationTemplate"
            ],
            "Resource": "arn:aws:serverlessrepo:us-east-1:838997950401:applications/aws-sagemaker-ground-truth-recipe"
        },
        {
            "Sid": "VisualEditor1",
            "Effect": "Allow",
            "Action": "serverlessrepo:SearchApplications",
            "Resource": "*"
        }
    ]
}
```

------

**Stratégies accordant l’affichage des fonctions Lambda dans la console Ground Truth**

Pour accorder à une entité IAM l’autorisation d’afficher les fonctions Lambda dans la console Ground Truth lorsque l’utilisateur crée une tâche d’étiquetage personnalisée, l’entité doit disposer des autorisations décrites dans [Autoriser IAM à utiliser la console Amazon SageMaker Ground Truth](sms-security-permission-console-access.md), y compris les autorisations décrites dans la section [Autorisations de flux de travail d’étiquetage personnalisées](sms-security-permission-console-access.md#sms-security-permissions-custom-workflow).

## Accorder au rôle d'exécution IAM l'autorisation d'invoquer AWS Lambda des fonctions
<a name="sms-custom-templates-step3-postlambda-execution-role-perms"></a>

Si vous ajoutez la politique gérée par IAM [AmazonSageMakerGroundTruthExecution](https://console.aws.amazon.com/iam/home?#/policies/arn:aws:iam::aws:policy/AmazonSageMakerGroundTruthExecution)au rôle d'exécution IAM utilisé pour créer la tâche d'étiquetage, ce rôle est autorisé à répertorier et à invoquer des fonctions Lambda avec l'une des chaînes suivantes dans le nom de la fonction :`GtRecipe`,,`SageMaker`, `Sagemaker` ou. `sagemaker` `LabelingFunction` 

Si les noms de fonction Lambda de pré-annotation ou de post-annotation n’incluent pas l’un des termes du paragraphe précédent, ou si vous avez besoin d’une autorisation plus détaillée que celles de la stratégie gérée `AmazonSageMakerGroundTruthExecution`, vous pouvez ajouter une stratégie similaire à la suivante pour donner au rôle d’exécution l’autorisation d’appeler des fonctions de pré-annotation et de post-annotation.

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "lambda:InvokeFunction",
            "Resource": [
                "arn:aws:lambda:us-east-1:111122223333:function:<pre-annotation-lambda-name>",
                "arn:aws:lambda:us-east-1:111122223333:function:<post-annotation-lambda-name>"
            ]
        }
    ]
}
```

------

## Accorder des autorisations Lambda de post-annotation pour accéder à l’annotation
<a name="sms-custom-templates-step3-postlambda-perms"></a>

Comme décrit dans [Lambda de post-annotation](sms-custom-templates-step3-lambda-requirements.md#sms-custom-templates-step3-postlambda), la requête Lambda de post-annotation inclut l’emplacement des données d’annotation dans Amazon S3. Cet emplacement est identifié par la chaîne `s3Uri` dans l’objet `payload`. Pour traiter les annotations au fur et à mesure de leur arrivée, même pour une simple fonction de passage, vous devez attribuer les autorisations nécessaires au [rôle d’exécution Lambda](https://docs.aws.amazon.com/lambda/latest/dg/lambda-intro-execution-role.html) de post-annotation pour lire les fichiers depuis Amazon S3.

Il existe de nombreuses façons de configurer votre Lambda pour accéder aux données d’annotation dans Amazon S3. Deux façons communes sont :
+ Permettez au rôle d'exécution Lambda d'assumer le rôle d'exécution de l' SageMaker IA identifié `roleArn` dans la demande Lambda postérieure à l'annotation. Ce rôle d'exécution d' SageMaker IA est celui utilisé pour créer la tâche d'étiquetage et a accès au compartiment de sortie Amazon S3 dans lequel les données d'annotation sont stockées.
+ Accordez au rôle d’exécution Lambda l’autorisation d’accéder directement au compartiment de sortie Amazon S3.

Utilisez les sections suivantes pour en savoir plus sur ces options. 

**Accorder à Lambda l'autorisation d'assumer le rôle d'exécution de SageMaker l'IA**

Pour permettre à une fonction Lambda d'assumer un rôle d'exécution d' SageMaker IA, vous devez associer une politique au rôle d'exécution de la fonction Lambda et modifier la relation de confiance du rôle d'exécution d' SageMaker IA pour permettre à Lambda de l'assumer.

1. [Associez la politique IAM suivante](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_manage-attach-detach.html) au rôle d'exécution de votre fonction Lambda pour assumer SageMaker le rôle d'exécution AI identifié dans. `Resource` Remplacez `222222222222` par votre [ID de compte AWS](https://docs.aws.amazon.com/general/latest/gr/acct-identifiers.html). Remplacez `sm-execution-role` par le nom du rôle assumé.

------
#### [ JSON ]

****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": {
           "Effect": "Allow",
           "Action": "sts:AssumeRole",
           "Resource": "arn:aws:iam::222222222222:role/sm-execution-role"
       }
   }
   ```

------

1. [Modifiez la politique de confiance](https://docs.aws.amazon.com/IAM/latest/UserGuide/roles-managingrole-editing-console.html#roles-managingrole_edit-trust-policy) du rôle d'exécution de l' SageMaker IA pour inclure les éléments suivants`Statement`. Remplacez `222222222222` par votre [ID de compte AWS](https://docs.aws.amazon.com/general/latest/gr/acct-identifiers.html). Remplacez `my-lambda-execution-role` par le nom du rôle assumé.

------
#### [ JSON ]

****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": [
           {
               "Effect": "Allow",
               "Principal": {
                   "AWS": "arn:aws:iam::222222222222:role/my-lambda-execution-role"
               },
               "Action": "sts:AssumeRole"
           }
       ]
   }
   ```

------

**Accorder au rôle d’exécution Lambda l’autorisation d’accéder à S3**

Vous pouvez ajouter une stratégie similaire à la suivante au rôle d’exécution de la fonction Lambda de post-annotation pour lui donner des autorisations de lecture S3. *amzn-s3-demo-bucket*Remplacez-le par le nom du compartiment de sortie que vous spécifiez lorsque vous créez une tâche d'étiquetage.

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:GetObject"
            ],
            "Resource": "arn:aws:s3:::amzn-s3-demo-bucket/*"
        }
    ]
}
```

------

Pour ajouter des autorisations de lecture S3 à un rôle d’exécution Lambda dans la console Lambda, procédez comme suit. 

**Ajouter des autorisations de lecture S3 à la fonction Lambda de post-annotation :**

1. Ouvrez la [page **Functions (Fonctions)**](https://console.aws.amazon.com/lambda/home#/functions) de la console Lambda.

1. Choisissez le nom de la fonction de post-annotation.

1. Choisissez **Configuration (Configuration)**, puis **Permissions (Autorisations)**.

1. Sélectionnez le **Role name (Nom de rôle)** et la page de résumé de ce rôle s’ouvre dans la console IAM dans un nouvel onglet. 

1. Sélectionnez **Attach policies (Attacher des stratégies)**.

1. Effectuez l’une des actions suivantes :
   + Recherchez et sélectionnez **`AmazonS3ReadOnlyAccess`** pour donner à la fonction l’autorisation de lire tous les compartiments et objets du compte. 
   + Si vous avez besoin d’autorisations plus détaillées, sélectionnez **Create policy (Créer une stratégie)** et utilisez l’exemple de stratégie de la section précédente pour créer une stratégie. Notez que vous devez revenir à la page récapitulative du rôle d’exécution après avoir créé la stratégie.

1. Si vous avez utilisé la stratégie gérée par `AmazonS3ReadOnlyAccess`, sélectionnez **Attacher une stratégie**. 

   Si vous avez créé une nouvelle stratégie, revenez à la page récapitulative du rôle d’exécution Lambda et attachez la stratégie que vous venez de créer.

# Création de fonctions Lambda à l’aide des modèles Ground Truth
<a name="sms-custom-templates-step3-lambda-create"></a>

Vous pouvez créer une fonction Lambda à l'aide de la console Lambda AWS CLI, du ou d'un AWS SDK dans le langage de programmation pris en charge de votre choix. Consultez le guide du AWS Lambda développeur pour en savoir plus sur chacune de ces options :
+ Pour savoir comment créer une fonction Lambda à l’aide de la console, consultez [Création d’une fonction Lambda avec la console](https://docs.aws.amazon.com/lambda/latest/dg/getting-started-create-function.html).
+ Pour savoir comment créer une fonction Lambda à l'aide de AWS CLI, voir Utilisation de [AWS Lambda avec l'interface de ligne de AWS](https://docs.aws.amazon.com/lambda/latest/dg/gettingstarted-awscli.html) commande.
+ Sélectionnez la section appropriée de la table des matières pour en savoir plus sur l’utilisation de Lambda dans la langue de votre choix. Par exemple, sélectionnez [Travail avec Python](https://docs.aws.amazon.com/lambda/latest/dg/lambda-python.html) pour en savoir plus sur l’utilisation de Lambda avec le kit AWS SDK pour Python (Boto3).

*Ground Truth fournit des modèles de pré-annotation et de post-annotation via une recette AWS Serverless Application Repository (SAR).* Utilisez la procédure suivante pour sélectionner la recette Ground Truth dans la console Lambda.

**Utilisez la recette SAR de Ground Truth pour créer des fonctions Lambda de pré-annotation et de post-annotation :**

1. Ouvrez la [page **Functions (Fonctions)**](https://console.aws.amazon.com/lambda/home#/functions) dans la console Lambda.

1. Sélectionnez **Create function (Créer une fonction)**.

1. Sélectionnez **Browse serverless app repository (Parcourir le répertoire d’applis sans serveur)**.

1. Dans la zone de texte de recherche, entrez **aws-sagemaker-ground-truth-recipe** et sélectionnez cette application.

1. Sélectionnez **Deploy (Déployer)**. Le déploiement de l’appli peut prendre quelques minutes. 

   Une fois que l’appli est déployée, deux fonctions apparaissent dans la section **Functions (Fonctions)** de la console Lambda : `serverlessrepo-aws-sagema-GtRecipePreHumanTaskFunc-<id>` et `serverlessrepo-aws-sagema-GtRecipeAnnotationConsol-<id>`. 

1. Sélectionnez l’une de ces fonctions et ajoutez votre logique personnalisée dans la section **Code**.

1. Une fois les modifications terminées, sélectionnez **Deploy (Déployer)** pour les déployer.

# Test de fonctions Lambda de pré-annotation et post-annotation
<a name="sms-custom-templates-step3-lambda-test"></a>

Vous pouvez tester vos fonctions Lambda de pré-annotation et de post-annotation dans la console Lambda. Si vous débutez avec Lambda, vous pouvez apprendre à tester, ou *invoquer*, vos fonctions Lambda dans la console à l’aide du tutoriel [Créer une fonction Lambda](https://docs.aws.amazon.com/lambda/latest/dg/getting-started-create-function.html#gettingstarted-zip-function) avec la console dans le Guide du développeur AWS Lambda . Vous pouvez utiliser les sections de cette page pour apprendre à tester les modèles de pré-annotation et de post-annotation de Ground Truth fournis via un AWS Serverless Application Repository (SAR). 

**Topics**
+ [Conditions préalables](#sms-custom-templates-step3-lambda-test-pre)
+ [Tester la fonction Lambda de pré-annotation](#sms-custom-templates-step3-lambda-test-pre-annotation)
+ [Tester la fonction Lambda de post-annotation](#sms-custom-templates-step3-lambda-test-post-annotation)

## Conditions préalables
<a name="sms-custom-templates-step3-lambda-test-pre"></a>

Vous devez effectuer les opérations suivantes pour utiliser les tests décrits sur cette page.
+ Vous devez accéder à la console Lambda, et vous avez besoin d’une autorisation pour créer et invoquer des fonctions Lambda. Pour savoir comment configurer ces autorisations, consultez [Autoriser la création et la sélection d'une AWS Lambda fonction](sms-custom-templates-step3-lambda-permissions.md#sms-custom-templates-step3-postlambda-create-perms).
+ Si vous n’avez pas déployé la recette SAR Ground Truth, utilisez la procédure décrite dans [Création de fonctions Lambda à l’aide des modèles Ground Truth](sms-custom-templates-step3-lambda-create.md) pour le faire.
+ Pour tester la fonction Lambda de post-annotation, vous devez disposer d’un fichier de données dans Amazon S3 avec des exemples de données d’annotation. Pour un test simple, vous pouvez copier et coller le code suivant dans un fichier et l’enregistrer sous `sample-annotations.json` et [télécharger ce fichier sur Amazon S3](https://docs.aws.amazon.com/AmazonS3/latest/userguide/upload-objects.html). Notez l’URI S3 de ce fichier : vous avez besoin de ces informations pour configurer le test Lambda de post-annotation.

  ```
  [{"datasetObjectId":"0","dataObject":{"content":"To train a machine learning model, you need a large, high-quality, labeled dataset. Ground Truth helps you build high-quality training datasets for your machine learning models."},"annotations":[{"workerId":"private.us-west-2.0123456789","annotationData":{"content":"{\"crowd-entity-annotation\":{\"entities\":[{\"endOffset\":8,\"label\":\"verb\",\"startOffset\":3},{\"endOffset\":27,\"label\":\"adjective\",\"startOffset\":11},{\"endOffset\":33,\"label\":\"object\",\"startOffset\":28},{\"endOffset\":51,\"label\":\"adjective\",\"startOffset\":46},{\"endOffset\":65,\"label\":\"adjective\",\"startOffset\":53},{\"endOffset\":74,\"label\":\"adjective\",\"startOffset\":67},{\"endOffset\":82,\"label\":\"adjective\",\"startOffset\":75},{\"endOffset\":102,\"label\":\"verb\",\"startOffset\":97},{\"endOffset\":112,\"label\":\"verb\",\"startOffset\":107},{\"endOffset\":125,\"label\":\"adjective\",\"startOffset\":113},{\"endOffset\":134,\"label\":\"adjective\",\"startOffset\":126},{\"endOffset\":143,\"label\":\"object\",\"startOffset\":135},{\"endOffset\":169,\"label\":\"adjective\",\"startOffset\":153},{\"endOffset\":176,\"label\":\"object\",\"startOffset\":170}]}}"}}]},{"datasetObjectId":"1","dataObject":{"content":"Sift 3 cups of flour into the bowl."},"annotations":[{"workerId":"private.us-west-2.0123456789","annotationData":{"content":"{\"crowd-entity-annotation\":{\"entities\":[{\"endOffset\":4,\"label\":\"verb\",\"startOffset\":0},{\"endOffset\":6,\"label\":\"number\",\"startOffset\":5},{\"endOffset\":20,\"label\":\"object\",\"startOffset\":15},{\"endOffset\":34,\"label\":\"object\",\"startOffset\":30}]}}"}}]},{"datasetObjectId":"2","dataObject":{"content":"Jen purchased 10 shares of the stock on Janurary 1st, 2020."},"annotations":[{"workerId":"private.us-west-2.0123456789","annotationData":{"content":"{\"crowd-entity-annotation\":{\"entities\":[{\"endOffset\":3,\"label\":\"person\",\"startOffset\":0},{\"endOffset\":13,\"label\":\"verb\",\"startOffset\":4},{\"endOffset\":16,\"label\":\"number\",\"startOffset\":14},{\"endOffset\":58,\"label\":\"date\",\"startOffset\":40}]}}"}}]},{"datasetObjectId":"3","dataObject":{"content":"The narrative was interesting, however the character development was weak."},"annotations":[{"workerId":"private.us-west-2.0123456789","annotationData":{"content":"{\"crowd-entity-annotation\":{\"entities\":[{\"endOffset\":29,\"label\":\"adjective\",\"startOffset\":18},{\"endOffset\":73,\"label\":\"adjective\",\"startOffset\":69}]}}"}}]}]
  ```
+ Vous devez suivre les instructions [Accorder des autorisations Lambda de post-annotation pour accéder à l’annotation](sms-custom-templates-step3-lambda-permissions.md#sms-custom-templates-step3-postlambda-perms) pour autoriser le rôle d'exécution de votre fonction Lambda post-annotation à assumer SageMaker le rôle d'exécution AI que vous utilisez pour créer la tâche d'étiquetage. La fonction Lambda post-annotation utilise SageMaker le rôle d'exécution AI pour accéder au fichier de données d'annotation`sample-annotations.json`, dans S3.



## Tester la fonction Lambda de pré-annotation
<a name="sms-custom-templates-step3-lambda-test-pre-annotation"></a>

Utilisez la procédure suivante pour tester la fonction Lambda de pré-annotation créée lors du déploiement de la recette Ground AWS Serverless Application Repository Truth (SAR). 

**Tester la fonction Lambda de pré-annotation de la recette SAR Ground Truth**

1. Ouvrez la [page **Functions (Fonctions)**](https://console.aws.amazon.com/lambda/home#/functions) de la console Lambda.

1. Sélectionnez la fonction de pré-annotation qui a été déployée à partir de la recette SAR Ground Truth. Le nom de cette fonction est similaire à `serverlessrepo-aws-sagema-GtRecipePreHumanTaskFunc-<id>`.

1. Dans la section **Code source**, sélectionnez la flèche en regard de **Test**.

1. Sélectionnez **Configure test event (Configurer l’événement de test)**.

1. Conserver l’option **Create new test event (Création d’un événement de test)** sélectionnée.

1. Sous **Modèle d'événement**, sélectionnez **SageMakerGround Truth PreHumanTask**. 

1. Donnez à votre test un **Event name (Nom d’événement)**.

1. Sélectionnez **Créer**.

1. Sélectionnez à nouveau la flèche en regard de **Test** et vous devriez voir que le test que vous avez créé est sélectionné, ce qui est indiqué par un point par le nom de l’événement. S’il n’est pas sélectionné, sélectionnez-le. 

1. Sélectionnez **Test** pour l’exécuter. 

Après avoir exécuté le test, vous pouvez voir les **Execution results (Résultats de l’exécution)**. Dans **Function logs (Journaux de fonctions)**, la réponse devrait être similaire à ce qui suit :

```
START RequestId: cd117d38-8365-4e1a-bffb-0dcd631a878f Version: $LATEST
Received event: {
  "version": "2018-10-16",
  "labelingJobArn": "arn:aws:sagemaker:us-east-2:123456789012:labeling-job/example-job",
  "dataObject": {
    "source-ref": "s3://sagemakerexample/object_to_annotate.jpg"
  }
}
{'taskInput': {'taskObject': 's3://sagemakerexample/object_to_annotate.jpg'}, 'isHumanAnnotationRequired': 'true'}
END RequestId: cd117d38-8365-4e1a-bffb-0dcd631a878f
REPORT RequestId: cd117d38-8365-4e1a-bffb-0dcd631a878f	Duration: 0.42 ms	Billed Duration: 1 ms	Memory Size: 128 MB	Max Memory Used: 43 MB
```

Dans cette réponse, nous pouvons voir que la sortie de la fonction Lambda correspond à la syntaxe de réponse de pré-annotation requise :

```
{'taskInput': {'taskObject': 's3://sagemakerexample/object_to_annotate.jpg'}, 'isHumanAnnotationRequired': 'true'}
```

## Tester la fonction Lambda de post-annotation
<a name="sms-custom-templates-step3-lambda-test-post-annotation"></a>

Utilisez la procédure suivante pour tester la fonction Lambda post-annotation créée lors du déploiement de la recette Ground AWS Serverless Application Repository Truth (SAR). 

**Tester la fonction Lambda de post-annotation de la recette SAR Ground Truth**

1. Ouvrez la [page **Functions (Fonctions)**](https://console.aws.amazon.com/lambda/home#/functions) de la console Lambda.

1. Sélectionnez la fonction post-annotation qui a été déployée à partir de la recette SAR Ground Truth. Le nom de cette fonction est similaire à `serverlessrepo-aws-sagema-GtRecipeAnnotationConsol-<id>`.

1. Dans la section **Code source**, sélectionnez la flèche en regard de **Test**.

1. Sélectionnez **Configure test event (Configurer l’événement de test)**.

1. Conserver l’option **Create new test event (Création d’un événement de test)** sélectionnée.

1. Sous **Modèle d'événement**, sélectionnez **SageMakerGround Truth AnnotationConsolidation**.

1. Donnez à votre test un **Event name (Nom d'événement)**.

1. Modifiez le code du modèle fourni comme suit :
   + Remplacez l'Amazon Resource Name (ARN) `roleArn` par l'ARN du rôle d'exécution SageMaker AI que vous avez utilisé pour créer la tâche d'étiquetage.
   + Remplacez l’URI S3 dans `s3Uri` avec l’URI du fichier `sample-annotations.json` que vous avez ajouté à Amazon S3.

   Après avoir apporté ces modifications, votre test doit se présenter comme suit :

   ```
   {
     "version": "2018-10-16",
     "labelingJobArn": "arn:aws:sagemaker:us-east-2:123456789012:labeling-job/example-job",
     "labelAttributeName": "example-attribute",
     "roleArn": "arn:aws:iam::222222222222:role/sm-execution-role",
     "payload": {
       "s3Uri": "s3://your-bucket/sample-annotations.json"
     }
   }
   ```

1. Sélectionnez **Créer**.

1. Sélectionnez à nouveau la flèche en regard de **Test** et vous devriez voir que le test que vous avez créé est sélectionné, ce qui est indiqué par un point par le nom de l’événement. S'il n'est pas sélectionné, sélectionnez-le. 

1. Sélectionnez le **Test** pour l’exécuter. 

Une fois le test exécuté, vous devriez voir une section `-- Consolidated Output --` dans les **Function Logs (Journaux de fonctions)**, qui contient une liste de toutes les annotations incluses dans `sample-annotations.json`.

# Modèle de démonstration : annotation d’images avec `crowd-bounding-box`
<a name="sms-custom-templates-step2-demo1"></a>

Lorsque vous avez choisi d'utiliser un modèle personnalisé comme type de tâche dans la console Amazon SageMaker Ground Truth, vous accédez au **panneau de tâches d'étiquetage personnalisé**. Vous pouvez alors choisir parmi plusieurs modèles de base. Les modèles représentent certaines des tâches les plus courantes et fournissent un échantillon de base à utiliser au fur et à mesure que vous créez votre modèle de tâche. Si vous n'utilisez pas la console, ou si vous avez un autre recours, consultez [Amazon SageMaker AI Ground Truth Sample Task UIs ](https://github.com/aws-samples/amazon-sagemaker-ground-truth-task-uis) pour obtenir un référentiel de modèles de démonstration pour différents types de tâches d'étiquetage.

Cette démonstration fonctionne avec le **BoundingBox**modèle. La démonstration fonctionne également avec les AWS Lambda fonctions nécessaires au traitement de vos données avant et après la tâche. Dans le référentiel Github ci-dessus, pour trouver des modèles compatibles avec des AWS Lambda fonctions, recherchez `{{ task.input.<property name> }}` dans le modèle.

**Topics**
+ [Modèle personnalisé de cadre de délimitation de démarrage.](#sms-custom-templates-step2-demo1-base-template)
+ [Votre modèle personnalisé de cadre de délimitation de base](#sms-custom-templates-step2-demo1-your-own-template)
+ [Votre fichier manifeste](#sms-custom-templates-step2-demo1-manifest)
+ [Votre fonction Lambda de pré-annotation](#sms-custom-templates-step2-demo1-pre-annotation)
+ [Votre fonction Lambda post-annotation](#sms-custom-templates-step2-demo1-post-annotation)
+ [La sortie de votre tâche d’étiquetage](#sms-custom-templates-step2-demo1-job-output)

## Modèle personnalisé de cadre de délimitation de démarrage.
<a name="sms-custom-templates-step2-demo1-base-template"></a>

Voici le modèle de cadre de délimitation de démarrage qui est fourni.

```
<script src="https://assets.crowd.aws/crowd-html-elements.js"></script>

<crowd-form>
  <crowd-bounding-box
    name="boundingBox"
    src="{{ task.input.taskObject | grant_read_access }}"
    header="{{ task.input.header }}"
    labels="{{ task.input.labels | to_json | escape }}"
  >

    <!-- The <full-instructions> tag is where you will define the full instructions of your task. -->
    <full-instructions header="Bounding Box Instructions" >
      <p>Use the bounding box tool to draw boxes around the requested target of interest:</p>
      <ol>
        <li>Draw a rectangle using your mouse over each instance of the target.</li>
        <li>Make sure the box does not cut into the target, leave a 2 - 3 pixel margin</li>
        <li>
          When targets are overlapping, draw a box around each object,
          include all contiguous parts of the target in the box.
          Do not include parts that are completely overlapped by another object.
        </li>
        <li>
          Do not include parts of the target that cannot be seen,
          even though you think you can interpolate the whole shape of the target.
        </li>
        <li>Avoid shadows, they're not considered as a part of the target.</li>
        <li>If the target goes off the screen, label up to the edge of the image.</li>
      </ol>
    </full-instructions>

    <!-- The <short-instructions> tag allows you to specify instructions that are displayed in the left hand side of the task interface.
    It is a best practice to provide good and bad examples in this section for quick reference. -->
    <short-instructions>
      Use the bounding box tool to draw boxes around the requested target of interest.
    </short-instructions>
  </crowd-bounding-box>
</crowd-form>
```

Les modèles personnalisés utilisent le [langage du modèle Liquid](https://shopify.github.io/liquid/) et chacun des éléments entre accolades doubles est une variable. La AWS Lambda fonction de pré-annotation doit fournir un objet nommé `taskInput` et les propriétés de cet objet sont accessibles comme `{{ task.input.<property name> }}` dans votre modèle.

## Votre modèle personnalisé de cadre de délimitation de base
<a name="sms-custom-templates-step2-demo1-your-own-template"></a>

Par exemple, supposons que vous avez une large gamme de photos dans laquelle vous connaissez le type d’animal dans une image à partir d’une image préalable de classification de tâche. À présent, vous souhaitez avoir un cadre de délimitation dessiné autour de celle-ci.

L’exemple de base comporte trois variables : `taskObject`, `header` et `labels`.

Chacune d’elles est représentée dans différentes parties du cadre de délimitation.
+ `taskObject` est une URL HTTP(S) ou un URI S3 pour la photo à annoter. Le code `| grant_read_access` ajouté est un filtre qui va convertir un URI S3 en URL HTTPS avec un accès de courte durée à cette ressource. Si vous utilisez une URL HTTP(S), il n’est pas nécessaire.
+ `header` est le texte situé au-dessus de la photo à étiqueter, par exemple « Dessiner un cadre autour de l’oiseau de la photo ».
+ `labels` est un tableau, représenté sous la forme `['item1', 'item2', ...]`. Ce sont des étiquettes que l’employé peut affecter aux différents cadres qu’il dessine. Vous pouvez en avoir une ou plusieurs.

Chacun des noms de variable provient de l’objet JSON dans la réponse de votre fonction de prétraitement Lambda. Les noms ci-dessus sont simplement suggérés. Utilisez les noms de variable qui ont un sens pour vous et facilitent la lecture du code au sein de votre équipe.

**Utilisez des variables uniquement lorsque cela est nécessaire**  
Si un champ ne change pas, vous pouvez supprimer la variable du modèle et la remplacer par du texte. Sinon, vous devez répéter ce texte en tant que valeur dans chaque objet de votre manifeste ou le coder dans votre fonction Lambda de pré-annotation.

**Example Modèle de cadre de délimitation final personnalisé**  
Dans un souci de simplification, ce modèle aura une variable, une étiquette et des instructions très basiques. En supposant que votre manifeste dispose d’une propriété « animal » dans chaque objet de données, cette valeur peut être réutilisé dans les deux parties du modèle.  

```
<script src="https://assets.crowd.aws/crowd-html-elements.js"></script>
<crowd-form>
  <crowd-bounding-box
    name="boundingBox"
    labels="[ '{{ task.input.animal }}' ]"
    src="{{ task.input.source-ref | grant_read_access }}"
    header="Draw a box around the {{ task.input.animal }}."
  >
    <full-instructions header="Bounding Box Instructions" >
      <p>Draw a bounding box around the {{ task.input.animal }} in the image. If 
      there is more than one {{ task.input.animal }} per image, draw a bounding 
      box around the largest one.</p>
      <p>The box should be tight around the {{ task.input.animal }} with 
      no more than a couple of pixels of buffer around the 
      edges.</p>
      <p>If the image does not contain a {{ task.input.animal }}, check the <strong>
      Nothing to label</strong> box.
    </full-instructions>
    <short-instructions>
      <p>Draw a bounding box around the {{ task.input.animal }} in each image. If 
      there is more than one {{ task.input.animal }} per image, draw a bounding 
      box around the largest one.</p>
    </short-instructions>
  </crowd-bounding-box>
</crowd-form>
```
Notez la réutilisation de `{{ task.input.animal }}` tout au long du modèle. Si tous les noms d’animaux de votre manifeste commencent par une lettre majuscule, vous pouvez utiliser `{{ task.input.animal | downcase }}`, en intégrant l’un des filtres intégrés de Liquid dans les phrases où les minuscules sont nécessaires.

## Votre fichier manifeste
<a name="sms-custom-templates-step2-demo1-manifest"></a>

Votre fichier manifeste doit fournir les valeurs de variables que vous utilisez dans votre modèle. Vous pouvez modifier un peu les données de votre manifeste dans votre fonction de prétraitement Lambda, mais si vous n’avez pas besoin de le faire, vous réduisez le risque d’erreurs et votre fonction de prétraitement Lambda fonctionnera plus rapidement. Voici un exemple de fichier manifeste pour le modèle.

```
{"source-ref": "<S3 image URI>", "animal": "horse"}
{"source-ref": "<S3 image URI>", "animal" : "bird"}
{"source-ref": "<S3 image URI>", "animal" : "dog"}
{"source-ref": "<S3 image URI>", "animal" : "cat"}
```

## Votre fonction Lambda de pré-annotation
<a name="sms-custom-templates-step2-demo1-pre-annotation"></a>

Dans le cadre de la configuration de la tâche, fournissez l'ARN d'une AWS Lambda fonction qui peut être appelée pour traiter les entrées de votre manifeste et les transmettre au moteur de modèles.

**Nommage de votre fonction Lambda**  
La bonne pratique pour nommer votre fonction consiste à utiliser l’une des quatre chaînes dans le cadre du nom de la fonction : `SageMaker`, `Sagemaker`, `sagemaker`, ou `LabelingFunction`. Cela s’applique aux fonctions de pré-annotation et de post-annotation.

Lorsque vous utilisez la console, si des fonctions AWS Lambda sont détenues par votre compte, une liste déroulante des fonctions répondant aux exigences de dénomination sera fournie pour en choisir une.

Dans cet exemple très basique, vous êtes seulement en passant par les informations du manifeste sans avoir à faire un traitement supplémentaire. Cet exemple de fonction de pré-annotation est écrit pour Python 3.7.

```
import json

def lambda_handler(event, context):
    return {
        "taskInput": event['dataObject']
    }
```

L’objet JSON de votre manifeste sera fourni en tant qu’enfant de l’objet `event`. Les propriétés à l’intérieur de l’objet `taskInput` seront disponibles en tant que variables de votre modèle, de sorte que la simple définition de la valeur de `taskInput` pour `event['dataObject']` transmettra toutes les valeurs à partir de votre objet de manifeste vers votre modèle, sans avoir à les copier individuellement. Si vous souhaitez envoyer plusieurs valeurs pour le modèle, vous pouvez les ajouter à l’objet `taskInput`.

## Votre fonction Lambda post-annotation
<a name="sms-custom-templates-step2-demo1-post-annotation"></a>

Dans le cadre de la configuration de la tâche, fournissez l'ARN d'une AWS Lambda fonction qui peut être appelée pour traiter les données du formulaire lorsqu'un collaborateur exécute une tâche. Cela peut être aussi simple ou complexe que vous le souhaitez. Si vous souhaitez procéder à la consolidation des réponses et à la notation au fur et à mesure, vous pouvez appliquer les algorithmes de and/or consolidation des scores de votre choix. Si vous souhaitez stocker les données brutes en vue d’un traitement hors ligne, c’est possible.

**Fournissez des autorisations à votre Lambda post-annotation**  
Les données d’annotation seront stockées dans un fichier désigné par la chaîne `s3Uri` dans l’objet `payload`. Pour traiter les annotations au fur et à mesure qu’elles arrivent, même pour une simple fonction de transmission, vous devez attribuer l’accès `S3ReadOnly` à votre fonction Lambda afin qu’elle puisse lire les fichiers d’annotation.  
Dans la page de la console relative à la création de votre fonction Lambda, faites défiler le panneau **Rôle d’exécution**. Sélectionnez **Create a new role from one or more templates (Créer un rôle à partir d’un ou de plusieurs modèles)**. Nommez le rôle. Dans la liste déroulante **Modèles de stratégie**, choisissez **Autorisations en lecture seule d’un objet Amazon S3**. Enregistrez la fonction Lambda. Le rôle est enregistré et sélectionné.

L’exemple suivant concerne Python 2.7.

```
import json
import boto3
from urlparse import urlparse

def lambda_handler(event, context):
    consolidated_labels = []

    parsed_url = urlparse(event['payload']['s3Uri']);
    s3 = boto3.client('s3')
    textFile = s3.get_object(Bucket = parsed_url.netloc, Key = parsed_url.path[1:])
    filecont = textFile['Body'].read()
    annotations = json.loads(filecont);
    
    for dataset in annotations:
        for annotation in dataset['annotations']:
            new_annotation = json.loads(annotation['annotationData']['content'])
            label = {
                'datasetObjectId': dataset['datasetObjectId'],
                'consolidatedAnnotation' : {
                'content': {
                    event['labelAttributeName']: {
                        'workerId': annotation['workerId'],
                        'boxesInfo': new_annotation,
                        'imageSource': dataset['dataObject']
                        }
                    }
                }
            }
            consolidated_labels.append(label)
    
    return consolidated_labels
```

La fonction de post-traitement Lambda reçoit souvent des lots de résultats de tâches dans l’objet d’événement. Ce lot sera l’objet `payload` sur lequel la fonction Lambda devra itérer. Ce que vous renverrez sera un objet conforme au [contrat d’API](sms-custom-templates-step3.md).

## La sortie de votre tâche d’étiquetage
<a name="sms-custom-templates-step2-demo1-job-output"></a>

Vous trouverez la sortie de la tâche dans un dossier nommé d’après votre tâche d’étiquetage dans le compartiment S3 cible que vous avez spécifié. Elle figurera dans un sous-dossier nommé `manifests`.

Pour une tâche de cadre de délimitation, la sortie que vous trouverez dans le manifeste de sortie ressemblera un peu à la démonstration ci-dessous. L’exemple a été nettoyé pour l’impression. La sortie réelle sera une seule ligne par enregistrement.

**Example Objet JSON dans votre manifeste de sortie**  

```
{
  "source-ref":"<URL>",
  "<label attribute name>":
    {
       "workerId":"<URL>",
       "imageSource":"<image URL>",
       "boxesInfo":"{\"boundingBox\":{\"boundingBoxes\":[{\"height\":878, \"label\":\"bird\", \"left\":208, \"top\":6, \"width\":809}], \"inputImageProperties\":{\"height\":924, \"width\":1280}}}"},
  "<label attribute name>-metadata":
    {
      "type":"groundTruth/custom",
      "job_name":"<Labeling job name>",
      "human-annotated":"yes"
    },
  "animal" : "bird"
}
```
Notez la façon dont l’attribut `animal` supplémentaire de votre manifeste initial est transmis au manifeste de sortie au même niveau que le `source-ref` et les données d’étiquetage. Toutes les propriétés de votre manifeste d’entrée, si elles ont été utilisées dans votre modèle ou non, seront transmises au manifeste de sortie.

# Modèle de démonstration : étiquetage des intentions avec `crowd-classifier`
<a name="sms-custom-templates-step2-demo2"></a>

Si vous choisissez un modèle personnalisé, vous atteignez le **panneau de tâches d’étiquetage personnalisé**. Dans la console, vous pouvez sélectionner à partir de plusieurs modèles de démarrage qui représentent la plupart des tâches courantes. Les modèles fournissent un point de départ à partir duquel créer votre modèle de tâche d’étiquetage personnalisé.

Dans cette démonstration, vous allez utiliser le modèle **Détection des intentions**, qui utilise l’élément `crowd-classifier` et les fonctions AWS Lambda nécessaires au traitement de vos données avant et après la tâche.

**Topics**
+ [Modèle personnalisé de démarrage de détection des intentions](#sms-custom-templates-step2-demo2-base-template)
+ [Votre modèle personnalisé de détection des intentions](#sms-custom-templates-step2-demo2-your-template)
+ [Votre fonction Lambda de pré-annotation](#sms-custom-templates-step2-demo2-pre-lambda)
+ [Votre fonction Lambda post-annotation](#sms-custom-templates-step2-demo2-post-lambda)
+ [Votre sortie de tâche d’étiquetage](#sms-custom-templates-step2-demo2-job-output)

## Modèle personnalisé de démarrage de détection des intentions
<a name="sms-custom-templates-step2-demo2-base-template"></a>

Il s’agit du modèle de détection d’intentions qui est fourni en tant que point de départ.

```
<script src="https://assets.crowd.aws/crowd-html-elements.js"></script>

<crowd-form>
  <crowd-classifier
    name="intent"
    categories="{{ task.input.labels | to_json | escape }}"
    header="Pick the most relevant intention expressed by the below text"
  >
    <classification-target>
      {{ task.input.utterance }}
    </classification-target>
    
    <full-instructions header="Intent Detection Instructions">
        <p>Select the most relevant intention expressed by the text.</p>
        <div>
           <p><strong>Example: </strong>I would like to return a pair of shoes</p>
           <p><strong>Intent: </strong>Return</p>
        </div>
    </full-instructions>

    <short-instructions>
      Pick the most relevant intention expressed by the text
    </short-instructions>
  </crowd-classifier>
</crowd-form>
```

Les modèles personnalisés utilisent le [langage du modèle Liquid](https://shopify.github.io/liquid/) et chacun des éléments entre accolades doubles est une variable. La fonction AWS Lambda de pré-annotation doit fournir un objet `taskInput` nommé et les propriétés de cet objet sont accessibles `{{ task.input.<property name> }}` comme dans votre modèle.

## Votre modèle personnalisé de détection des intentions
<a name="sms-custom-templates-step2-demo2-your-template"></a>

Dans le modèle de départ, il y a deux variables : la propriété `task.input.labels` dans la balise d’ouverture de l’élément `crowd-classifier` et le `task.input.utterance` dans le contenu de la région `classification-target`.

À moins que vous deviez offrir différents ensembles d’étiquettes avec différents énoncés, éviter d’utiliser une variable et utiliser simplement du texte vous permettra de gagner du temps de traitement et de créer moins de possibilités d’erreurs. Le modèle utilisé dans cette démonstration supprimera cette variable, mais les variables et les filtres tels que `to_json` sont décrits plus en détail dans l’article de [démonstration de `crowd-bounding-box`]().

### Personnalisez vos éléments
<a name="sms-custom-templates-step2-demo2-instructions"></a>

Deux parties des éléments personnalisés sont parfois oubliées, il s’agit des régions `<full-instructions>` et `<short-instructions>`. Les bonnes instructions permettent d’obtenir de bons résultats.

Dans les éléments qui incluent ces régions, le `<short-instructions>` apparaît automatiquement dans le volet « Instructions » situé à gauche de l’écran. Les `<full-instructions>` sont rattachées au lien « View full instructions (Affichage des instructions complètes) » situé en haut de ce volet. En cliquant sur le lien, vous ouvrez un volet avec des instructions plus détaillées.

Vous ne pouvez pas uniquement utiliser le HTML ou le CSS. JavaScript Dans ces sections, nous vous encourageons à le faire si vous pensez pouvoir fournir un ensemble solide d'instructions et d'exemples qui aideront les employés à effectuer vos tâches avec plus de rapidité et de précision. 

**Example Testez un échantillon avec JSFiddle**  
[https://jsfiddle.net/MTGT_Fiddle_Manager/bjc0y1vd/35/](https://jsfiddle.net/MTGT_Fiddle_Manager/bjc0y1vd/35/)  
 Effectuez un [test`<crowd-classifier>`](https://jsfiddle.net/MTGT_Fiddle_Manager/bjc0y1vd/35/). L'exemple est rendu par JSFiddle, donc toutes les variables du modèle sont remplacées par des valeurs codées en dur. Cliquez sur le lien « View full instructions (Affichage des instructions complètes) » pour consulter plusieurs exemples de styles CSS étendus. Vous pouvez bifurquer le projet pour tester vos propres modifications du CSS, en ajoutant des exemples d'images ou en ajoutant des JavaScript fonctionnalités étendues.

**Example : modèle final personnalisé de détection des intentions**  
Dans ce cas, l’[exemple de tâche `<crowd-classifier>`](https://jsfiddle.net/MTGT_Fiddle_Manager/bjc0y1vd/35/) est utilisé, mais avec une variable pour `<classification-target>`. Si vous essayez de maintenir un style CSS cohérent parmi une série de tâches d’étiquetage différentes, vous pouvez inclure une feuille de style externe à l’aide d’un élément `<link rel...>`, de la même manière que vous le feriez dans n’importe quel autre document HTML.  

```
<script src="https://assets.crowd.aws/crowd-html-elements.js"></script>

<crowd-form>
  <crowd-classifier
    name="intent"
    categories="['buy', 'eat', 'watch', 'browse', 'leave']"
    header="Pick the most relevant intent expressed by the text below"
  >
    <classification-target>
      {{ task.input.source }}
    </classification-target>
    
    <full-instructions header="Emotion Classification Instructions">
      <p>In the statements and questions provided in this exercise, what category of action is the speaker interested in doing?</p>
          <table>
            <tr>
              <th>Example Utterance</th>
              <th>Good Choice</th>
            </tr>
            <tr>
              <td>When is the Seahawks game on?</td>
              <td>
                eat<br>
                <greenbg>watch</greenbg>
                <botchoice>browse</botchoice>
              </td>
            </tr>
            <tr>
              <th>Example Utterance</th>
              <th>Bad Choice</th>
            </tr>
            <tr>
              <td>When is the Seahawks game on?</td>
              <td>
                buy<br>
                <greenbg>eat</greenbg>
                <botchoice>watch</botchoice>
              </td>
            </tr>
          </table>
    </full-instructions>

    <short-instructions>
      What is the speaker expressing they would like to do next?
    </short-instructions>  
  </crowd-classifier>
</crowd-form>
<style>
  greenbg {
    background: #feee23;
    display: block;
  }

  table {
    *border-collapse: collapse; /* IE7 and lower */
    border-spacing: 0; 
  }

  th, tfoot, .fakehead {
    background-color: #8888ee;
    color: #f3f3f3;
    font-weight: 700;
  }

  th, td, tfoot {
      border: 1px solid blue;
  }

  th:first-child {
    border-radius: 6px 0 0 0;
  }

  th:last-child {
    border-radius: 0 6px 0 0;
  }

  th:only-child{
    border-radius: 6px 6px 0 0;
  }

  tfoot:first-child {
    border-radius: 0 0 6px 0;
  }

  tfoot:last-child {
    border-radius: 0 0 0 6px;
  }

  tfoot:only-child{
    border-radius: 6px 6px;
  }

  td {
    padding-left: 15px ;
    padding-right: 15px ;
  }

  botchoice {
    display: block;
    height: 17px;
    width: 490px;
    overflow: hidden;
    position: relative;
    background: #fff;
    padding-bottom: 20px;
  }

  botchoice:after {
    position: absolute;
    bottom: 0;
    left: 0;  
    height: 100%;
    width: 100%;
    content: "";
    background: linear-gradient(to top,
       rgba(255,255,255, 1) 55%, 
       rgba(255,255,255, 0) 100%
    );
    pointer-events: none; /* so the text is still selectable */
  }
</style>
```

**Example Votre fichier manifeste**  
Si vous préparez votre fichier manifeste manuellement pour une tâche de classification de texte de ce type, vous devrez formater vos données de la façon suivante.  

```
{"source": "Roses are red"}
{"source": "Violets are Blue"}
{"source": "Ground Truth is the best"}
{"source": "And so are you"}
```

Il est différent du fichier manifeste utilisé pour la démonstration « [Modèle de démonstration : annotation d’images avec `crowd-bounding-box`](sms-custom-templates-step2-demo1.md) » car le `source-ref` a été utilisé comme nom de propriété et non comme `source`. L'utilisation de `source-ref` désigne S3 URIs pour les images ou autres fichiers devant être convertis en HTTP. Dans le cas contraire, `source` doit être utilisé comme il l’est avec les chaînes de texte ci-dessus.

## Votre fonction Lambda de pré-annotation
<a name="sms-custom-templates-step2-demo2-pre-lambda"></a>

Dans le cadre de la configuration de la tâche, fournissez l'ARN d'un fichier AWS Lambda qui peut être appelé pour traiter les entrées de votre manifeste et transmettez-les au moteur de modèles. 

Cette fonction Lambda est requise pour que l’une des quatre chaînes suivantes fasse partie du nom de la fonction : `SageMaker`, `Sagemaker`, `sagemaker` ou `LabelingFunction`.

Cela s’applique à la fois aux Lambdas pré-annotation et post-annotation.

Lorsque vous utilisez la console, si vous avez des fonctions Lambda qui appartiennent à votre compte, une liste déroulante des fonctions répondant aux exigences d’appellation s’affiche pour vous permettre d’en choisir une.

Dans cet exemple très basique où vous n’avez qu’une seule variable, il s’agit principalement d’une fonction de passerelle. Vous trouverez ci-dessous un exemple de pré-étiquetage Lambda à l’aide de Python 3.7.

```
import json

def lambda_handler(event, context):
    return {
        "taskInput":  event['dataObject']
    }
```

La propriété `dataObject` de l’`event` contient les propriétés d’un objet de données dans votre manifeste.

Dans cette démonstration, qui est une simple transmission d’une variable, vous la transmettez simplement en tant que valeur `taskInput`. Si vous ajoutez des propriétés avec ces valeurs à l’objet `event['dataObject']`, elles seront disponibles pour votre modèle HTML en tant que variables Liquid au format `{{ task.input.<property name> }}`.

## Votre fonction Lambda post-annotation
<a name="sms-custom-templates-step2-demo2-post-lambda"></a>

Dans le cadre de la configuration de la tâche, vous devrez fournir l’ARN d’une fonction Lambda qui peut être appelée pour traiter les données de formulaire lorsqu’un employé effectue une tâche. Cela peut être aussi simple ou complexe que vous le souhaitez. Si vous souhaitez consolider les réponses et les noter au fur et à mesure qu’elles arrivent, vous pouvez appliquer les algorithmes de notation et/ou de consolidation de votre choix. Si vous souhaitez stocker les données brutes en vue d’un traitement hors ligne, c’est possible.

**Définissez les autorisations pour votre fonction Lambda post-annotation**  
Les données d’annotation seront stockées dans un fichier désigné par la chaîne `s3Uri` dans l’objet `payload`. Pour traiter les annotations au fur et à mesure qu’elles arrivent, même pour une simple fonction de transmission, vous devez attribuer l’accès `S3ReadOnly` à votre fonction Lambda afin qu’elle puisse lire les fichiers d’annotation.  
Dans la page de la console relative à la création de votre fonction Lambda, faites défiler le panneau **Rôle d’exécution**. Sélectionnez **Create a new role from one or more templates (Créer un rôle à partir d’un ou de plusieurs modèles)**. Nommez le rôle. Dans la liste déroulante **Modèles de stratégie**, choisissez **Autorisations en lecture seule d’un objet Amazon S3**. Enregistrez la fonction Lambda. Le rôle est enregistré et sélectionné.

L’exemple suivant concerne Python 3.7.

```
import json
import boto3
from urllib.parse import urlparse

def lambda_handler(event, context):
    consolidated_labels = []

    parsed_url = urlparse(event['payload']['s3Uri']);
    s3 = boto3.client('s3')
    textFile = s3.get_object(Bucket = parsed_url.netloc, Key = parsed_url.path[1:])
    filecont = textFile['Body'].read()
    annotations = json.loads(filecont);
    
    for dataset in annotations:
        for annotation in dataset['annotations']:
            new_annotation = json.loads(annotation['annotationData']['content'])
            label = {
                'datasetObjectId': dataset['datasetObjectId'],
                'consolidatedAnnotation' : {
                'content': {
                    event['labelAttributeName']: {
                        'workerId': annotation['workerId'],
                        'result': new_annotation,
                        'labeledContent': dataset['dataObject']
                        }
                    }
                }
            }
            consolidated_labels.append(label)

    return consolidated_labels
```

## Votre sortie de tâche d’étiquetage
<a name="sms-custom-templates-step2-demo2-job-output"></a>

La fonction de post-traitement Lambda reçoit souvent des lots de résultats de tâches dans l’objet d’événement. Ce lot sera l’objet `payload` sur lequel la fonction Lambda devra itérer.

Vous trouverez la sortie de la tâche dans un dossier nommé d’après votre tâche d’étiquetage dans le compartiment S3 cible que vous avez spécifié. Elle figurera dans un sous-dossier nommé `manifests`.

Pour une tâche de détection des intentions, la sortie que vous trouverez dans le manifeste de sortie ressemblera un peu à la démonstration ci-dessous. L’exemple a été ordonné et espacé afin que les humains aient moins de mal à le lire. La sortie réelle sera plus compressée pour la lecture par machine.

**Example Objet JSON dans votre manifeste de sortie**  

```
[
  {
    "datasetObjectId":"<Number representing item's place in the manifest>",
     "consolidatedAnnotation":
     {
       "content":
       {
         "<name of labeling job>":
         {     
           "workerId":"private.us-east-1.XXXXXXXXXXXXXXXXXXXXXX",
           "result":
           {
             "intent":
             {
                 "label":"<label chosen by worker>"
             }
           },
           "labeledContent":
           {
             "content":"<text content that was labeled>"
           }
         }
       }
     }
   },
  "datasetObjectId":"<Number representing item's place in the manifest>",
     "consolidatedAnnotation":
     {
       "content":
       {
         "<name of labeling job>":
         {     
           "workerId":"private.us-east-1.6UDLPKQZHYWJQSCA4MBJBB7FWE",
           "result":
           {
             "intent":
             {
                 "label": "<label chosen by worker>"
             }
           },
           "labeledContent":
           {
             "content": "<text content that was labeled>"
           }
         }
       }
     }
   },
     ...
     ...
     ...
]
```

Cet exemple devrait vous aider à créer et à utiliser votre propre modèle personnalisé.

# Création d’un flux de travail personnalisé à l’aide de l’API
<a name="sms-custom-templates-step4"></a>

Une fois que vous avez créé votre modèle d’interface utilisateur personnalisée (étape 2) et traité les fonctions Lambda (étape 3), vous devez placer le modèle dans un compartiment Amazon S3 avec un format de nom de fichier : `<FileName>.liquid.html`. Utilisez l’action [https://docs.aws.amazon.com/sagemaker/latest/APIReference/API_CreateLabelingJob.html](https://docs.aws.amazon.com/sagemaker/latest/APIReference/API_CreateLabelingJob.html) pour configurer votre tâche. Vous allez utiliser l’emplacement d’un modèle personnalisé ([Création d’un modèle de tâche d’employé personnalisé](sms-custom-templates-step2.md)) stocké dans un fichier `<filename>.liquid.html` sur S3 en tant que valeur du champ `UiTemplateS3Uri` dans l’objet [https://docs.aws.amazon.com/sagemaker/latest/APIReference/API_UiConfig.html](https://docs.aws.amazon.com/sagemaker/latest/APIReference/API_UiConfig.html) au sein de l’objet [https://docs.aws.amazon.com/sagemaker/latest/APIReference/API_HumanTaskConfig.html](https://docs.aws.amazon.com/sagemaker/latest/APIReference/API_HumanTaskConfig.html).

Pour les tâches AWS Lambda décrites dans[Traitement des données dans un flux de travail d'étiquetage personnalisé avec AWS Lambda](sms-custom-templates-step3.md), l'ARN de la tâche post-annotation sera utilisé comme valeur pour le `AnnotationConsolidationLambdaArn` champ, et la tâche de pré-annotation sera utilisée comme valeur pour `PreHumanTaskLambdaArn.` 