Modèle de démonstration : étiquetage des intentions avec crowd-classifier - Amazon SageMaker

Modèle de démonstration : étiquetage des intentions avec crowd-classifier

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 Intent Detection (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.

Modèle personnalisé de démarrage de détection des intentions

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 et chacun des éléments entre accolades doubles est une variable. La fonction AWS Lambda de pré-annotation doit fournir un objet nommé taskInput et les propriétés de cet objet sont accessibles en tant que {{ task.input.<property name> }} dans votre modèle.

Votre modèle personnalisé de détection des intentions

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 crowd-bounding-boxdémonstration.

Personnalisez vos éléments

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 pouvez utiliser HTML, CSS et JavaScript dans ces rubriques, et nous vous invitons à le faire si vous pensez que vous pouvez fournir un ensemble d'instructions et d'exemples qui aideront le personnel à effectuer vos tâches avec plus de rapidité et de précision.

Exemple Testez du code avec JSFiddle

Effectuez un test<crowd-classifier>. Cet exemple est présenté par JSFiddle. Par conséquent, tous les modèles de variables sont remplacés 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 fourcher le projet pour tester vos propres modifications de CSS, ajouter des modèles d'images, ou ajouter des fonctionnalités JavaScript élargies.

Exemple : modèle final personnalisé de détection des intentions

Dans ce cas, la tâche d'exemple<crowd-classifier> est utilisée, mais avec une variable pour le <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>

Exemple 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 » car le source-ref a été utilisé comme nom de propriété et non comme source. L'utilisation de source-ref désigne les URI S3 pour les images ou d'autres fichiers qui doivent ê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

Dans le cadre de la configuration de la tâche, vous devrez fournir l'ARN d'une AWS Lambda qui peut être appelée pour traiter les entrées du manifeste et les transmettre 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

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 Execution role (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 Policy templates (Modèles de stratégie), choisissez Amazon S3 object read-only permissions (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

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.

Exemple 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é.