

Las traducciones son generadas a través de traducción automática. En caso de conflicto entre la traducción y la version original de inglés, prevalecerá la version en inglés.

# Flujos de trabajo de etiquetado personalizados
<a name="sms-custom-templates"></a>

Estos temas le ayudan a configurar un trabajo de etiquetado de Ground Truth que utilice una plantilla de etiquetado personalizada. Una plantilla de etiquetado personalizada le permite crear una interfaz de usuario personalizada para el portal de trabajadores que estos utilizarán para etiquetar los datos. La plantilla se puede crear utilizando HTML, CSS JavaScript, [lenguaje de plantillas Liquid](https://shopify.github.io/liquid/) y [Crowd HTML Elements](https://docs.aws.amazon.com/sagemaker/latest/dg/sms-ui-template-reference.html).

## Descripción general de
<a name="sms-custom-templates-overview"></a>

Si es la primera vez que crea un flujo de trabajo de etiquetado personalizado en Ground Truth, la siguiente lista es un resumen general de los pasos necesarios.

1. *Configuración del personal*: para crear un flujo de trabajo de etiquetado personalizado, necesita personal. En este tema se enseña cómo configurar personal.

1. *Creación de una plantilla personalizada*: para crear una plantilla personalizada, debe asignar correctamente los datos del archivo de manifiesto de entrada a las variables de la plantilla.

1. *Uso de funciones de Lambda de procesamiento opcionales*: para controlar cómo se añaden los datos del manifiesto de entrada a la plantilla de trabajador y cómo se registran las anotaciones de los trabajadores en el archivo de salida del trabajo.

Este tema también incluye tres end-to-end demostraciones para ayudarlo a comprender mejor cómo usar plantillas de etiquetado personalizadas.

**nota**  
Todos los ejemplos de los enlaces siguientes incluyen funciones de Lambda previas y posteriores a la anotación. Estas funciones de Lambda son opcionales.
+ [Plantilla de demostración: anotación de imágenes con `crowd-bounding-box`](sms-custom-templates-step2-demo1.md)
+ [Plantilla de demostración: intenciones de etiquetado con `crowd-classifier`](sms-custom-templates-step2-demo2.md)
+ [Cree un flujo de trabajo de etiquetado de datos personalizado con Amazon SageMaker Ground Truth](https://aws.amazon.com/blogs/machine-learning/build-a-custom-data-labeling-workflow-with-amazon-sagemaker-ground-truth/)

**Topics**
+ [Descripción general de](#sms-custom-templates-overview)
+ [Configuración del personal](sms-custom-templates-step1.md)
+ [Creación de una plantilla personalizada de tareas de trabajador](sms-custom-templates-step2.md)
+ [Adición de automatización con Liquid](sms-custom-templates-step2-automate.md)
+ [Procesar datos en un flujo de trabajo de etiquetado personalizado con AWS Lambda](sms-custom-templates-step3.md)
+ [Plantilla de demostración: anotación de imágenes con `crowd-bounding-box`](sms-custom-templates-step2-demo1.md)
+ [Plantilla de demostración: intenciones de etiquetado con `crowd-classifier`](sms-custom-templates-step2-demo2.md)
+ [Creación de un flujo de trabajo personalizado mediante la API](sms-custom-templates-step4.md)

# Configuración del personal
<a name="sms-custom-templates-step1"></a>

En este paso, utiliza la consola para establecer qué tipo de trabajador va a utilizar y para realizar las subselecciones necesarias para el tipo de trabajador. Se entiende que ya ha completado los pasos que se detallan hasta este punto en la sección [Introducción: creación de un trabajo de etiquetado mediante cuadros delimitadores con Ground Truth](sms-getting-started.md) y que ha elegido **Custom labeling task (Tarea de etiquetado personalizada)** como **Task type (Tipo de tarea)**.

**Para configurar el personal.**

1. En primer lugar, elija una opción entre los **Tipos de trabajadores**. Actualmente existen tres tipos:
   + **Public (Público)** utiliza personal bajo demanda de contratistas independientes, con tecnología Amazon Mechanical Turk. Se les paga por tarea.
   + **Privado** utiliza sus trabajadores o contratistas para gestionar los datos que deben permanecer en la organización.
   + **El proveedor** utiliza proveedores externos que se especializan en la prestación de servicios de etiquetado de datos, disponibles a través del AWS Marketplace.

1. Si elige la opción **Público**, se le pedirá establecer el **Número de trabajadores por objeto de conjunto de datos**. Disponer de más de un trabajador para realizar la misma tarea en el mismo objeto puede ayudarle a aumentar la precisión de sus resultados. El valor predeterminado es tres. Puede subir o bajar dicho valor en función de la precisión que necesite.

   También se le pedirá que establezca un **Price per task (Precio por tarea)**mediante un menú desplegable. El menú recomienda precios en función de cuánto tiempo tardará en completarse la tarea.

   Para determinar este valor se recomienda ejecutar primero una breve prueba de su tarea con personal **Private (Privado)**. La prueba permite obtener una estimación realista del tiempo que tardará la tarea en completarse. A continuación, puede seleccionar el intervalo en el que entra su estimación, en el menú **Price per task (Precio por tarea)**. Si su tiempo medio supera los 5 minutos, considere desglosar su tarea en unidades de menor tamaño.

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

[Creación de una plantilla personalizada de tareas de trabajador](sms-custom-templates-step2.md)

# Creación de una plantilla personalizada de tareas de trabajador
<a name="sms-custom-templates-step2"></a>

Para crear un trabajo de etiquetado personalizado, debe actualizar la plantilla de tareas de trabajador, asignar los datos de entrada del archivo de manifiesto a las variables utilizadas en la plantilla y asignar los datos de salida a Amazon S3. Para obtener más información sobre las características avanzadas que utilizan la automatización de Liquid, consulte [Adición de automatización con Liquid](sms-custom-templates-step2-automate.md).

En las siguientes secciones se describen cada uno de los pasos necesarios.

## Plantilla de tareas de trabajador
<a name="sms-custom-templates-step2-template"></a>

Una *plantilla de tarea de trabajador* es un archivo que utiliza Ground Truth para personalizar la interfaz de usuario (IU) del trabajador. Puede crear una plantilla de tareas de trabajo utilizando HTML, CSS JavaScript, el [lenguaje de plantillas Liquid](https://shopify.github.io/liquid/) y [Crowd HTML Elements](https://docs.aws.amazon.com/sagemaker/latest/dg/sms-ui-template-reference.html). Se utiliza Liquid para automatizar la plantilla. Crowd HTML Elements se utiliza para incluir herramientas comunes de anotaciones y proporcionar la lógica necesaria para enviarla a Ground Truth.

Use los siguientes temas para aprender a crear una plantilla de tareas de trabajadores. Puedes ver un repositorio de ejemplos de plantillas de tareas para trabajadores de Ground Truth en [GitHub](https://github.com/aws-samples/amazon-sagemaker-ground-truth-task-uis).

### Uso de la plantilla de tareas base para trabajadores de la consola de SageMaker IA
<a name="sms-custom-templates-step2-base"></a>

Puede usar un editor de plantillas en la consola de Ground Truth para empezar a crear una plantilla. Este editor incluye una serie de plantillas base prediseñadas. Es compatible con el relleno automático de códigos HTML y Crowd HTML Elements.

**Para acceder al editor de plantillas personalizadas de Ground Truth:**

1. Siga las instrucciones que se indican en [Crear un trabajo de etiquetado (consola)](sms-create-labeling-job-console.md).

1. A continuación, seleccione **Personalizado** para **Tipo de tarea** del trabajo de etiquetado.

1. Al seleccionar **Siguiente**, podrá acceder al editor de plantillas y las plantillas base en la sección **Configuración de tareas de etiquetado personalizado**. 

1. (Opcional) Seleccione una plantilla base en el menú desplegable de **Plantillas**. Si prefiere crear una plantilla desde cero, seleccione **Personalizar** en el menú desplegable para obtener un esquema de plantilla mínimo.

Consulte la siguiente sección para aprender a visualizar una plantilla desarrollada en la consola de forma local.

#### Visualización de las plantillas de tareas de trabajador de forma local
<a name="sms-custom-template-step2-UI-local"></a>

Debe usar la consola para probar cómo la plantilla procesa los datos entrantes. Para probar el aspecto de los elementos personalizados y de HTML de la plantilla, puede usar el navegador.

**nota**  
Las variables no se analizarán. Es posible que tenga que sustituirlas por contenido de muestra mientras visualiza el contenido de forma local.

El siguiente fragmento de código de ejemplo carga el código necesario para representar los elementos de HTML personalizados. Úselo si quiere desarrollar el aspecto de la plantilla en su editor preferido en lugar de hacerlo en la consola.

**Example**  

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

### Creación de un ejemplo sencillo de tareas mediante HTML
<a name="sms-custom-templates-step2-sample"></a>

Ahora que tiene la plantilla base de tareas de trabajador, puede consultar este tema para crear una plantilla sencilla de tareas basada en HTML.

A continuación se muestra un ejemplo de una entrada de un archivo de manifiesto de entrada.

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

En la plantilla de tareas HTML, debemos asignar las variables del archivo de manifiesto de entrada a la plantilla. Se asignaría la variable del manifiesto de entrada de ejemplo mediante la siguiente sintaxis **task.input.source**, **task.input.labels** y **task.input.header**.

A continuación se muestra un ejemplo de una plantilla sencilla de tareas de trabajador basada en HTML para el análisis de tuits. Todas las tareas comienzan y terminan con los elementos `<crowd-form> </crowd-form>`. Al igual que los elementos `<form>` HTML estándar, todo el código de formulario debería ir entre ellos. Ground Truth genera las tareas de los trabajadores directamente desde el contexto especificado en la plantilla, a menos que se implemente una función de Lambda previa a la anotación. El objeto `taskInput` devuelto por Ground Truth o [Lambda de preanotación](sms-custom-templates-step3-lambda-requirements.md#sms-custom-templates-step3-prelambda) es el objeto `task.input` de las plantillas.

Para una sencilla tarea de análisis de tweet, utilice el elemento `<crowd-classifier>`. Requiere los atributos siguientes:
+ *nombre*: nombre de la variable de salida. Las anotaciones del trabajador se guardan con el nombre de esta variable en el manifiesto de salida.
+ *categories*: matriz con formato JSON de las posibles respuestas.
+ *header*: título para la herramienta de anotaciones

El elemento `<crowd-classifier>` requiere al menos los tres elementos secundarios siguientes.
+ *<classification-target>*: texto que el trabajador clasificará en función de las opciones especificadas en el atributo `categories` anterior.
+ *<full-instructions>*: instrucciones que están disponibles en el enlace Ver instrucciones completas en la herramienta. Puede dejarse en blanco, pero se recomienda que dé buenas instrucciones para obtener mejores resultados.
+ *<short-instructions>*: descripción más breve de la tarea que aparece en la barra lateral de la herramienta. Puede dejarse en blanco, pero se recomienda que dé buenas instrucciones para obtener mejores resultados.

Una versión sencilla de esta herramienta tendría el aspecto siguiente. La variable **\$1\$1 task.input.source \$1\$1** es lo que especifica los datos de origen del archivo de manifiesto de entrada. **\$1\$1 task.input.labels \$1 to\$1json \$1\$1** es un ejemplo de un filtro de variable para convertir la matriz en una representación de JSON. El atributo `categories` debe ser JSON.

**Example de cómo utilizar `crowd-classifier` con el json de manifiesto de entrada de muestra**  

```
<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>
```

Puedes copiar y pegar el código en el editor del flujo de trabajo de creación de empleo de etiquetado de Ground Truth para obtener una vista previa de la herramienta, o bien puedes probar una [demostración de este código CodePen.](https://codepen.io/MTGT/full/OqBvJw)

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

## Datos de entrada, activos externos y la plantilla de tareas
<a name="sms-custom-templates-step2-template-input"></a>

En las siguientes secciones se describen el uso de activos externos, los requisitos de formato de los datos de entrada y cuándo plantearse el uso de funciones de Lambda previas a la anotación.

### Requisitos de formato de datos de entrada
<a name="sms-custom-template-input-manifest"></a>

Al crear un archivo de manifiesto de entrada para usarlo en el trabajo de etiquetado personalizado de Ground Truth, debe almacenar los datos en Amazon S3. Los archivos de manifiesto de entrada también deben guardarse en el mismo lugar Región de AWS en el que se va a ejecutar su trabajo de etiquetado personalizado de Ground Truth. Además, se puede almacenar en cualquier bucket de Amazon S3 al que pueda acceder el rol de servicio de IAM que utilice para ejecutar el trabajo de etiquetado personalizado en Ground Truth.

Los archivos de manifiesto de entrada deben usar el formato de líneas JSON o JSON delimitado por saltos de línea. Cada línea se delimita con un salto de línea estándar, **\$1n** o **\$1r\$1n**. Cada línea también debe ser un objeto JSON válido. 

Además, cada objeto JSON del archivo de manifiesto debe incluir una de las siguientes claves: `source-ref` o `source`. El valor de las claves se interpreta como se indica a continuación:
+ `source-ref`: el origen del objeto es el objeto de Amazon S3 especificado en el valor. Utilice este valor cuando el objeto sea un objeto binario, como una imagen.
+ `source`: el origen del objeto es el valor. Utilice este valor cuando el objeto sea un valor de texto.

Para obtener más información sobre el formato de los archivos de manifiesto de entrada, consulte [Archivos de manifiesto de entrada](sms-input-data-input-manifest.md).

### Función de Lambda previa a la anotación
<a name="sms-custom-template-input-lambda"></a>

Si lo desea, puede especificar una función de *Lambda previa a la anotación* para administrar la forma en que se tratan los datos del archivo de manifiesto de entrada antes del etiquetado. Si ha especificado el par clave-valor `isHumanAnnotationRequired`, debe utilizar una función de Lambda previa a la anotación. Cuando Ground Truth envía a la función de Lambda previa a la anotación una solicitud con formato JSON, utiliza los siguientes esquemas.

**Example objeto de datos identificado con el par clave-valor `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 objeto de datos identificado con el par clave-valor `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
      }
    }
```

A continuación se muestra la respuesta prevista de la función de Lambda cuando se utiliza `isHumanAnnotationRequired`.

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

### Uso de activos externos
<a name="sms-custom-template-step2-UI-external"></a>

Las plantillas personalizadas de Amazon SageMaker Ground Truth permiten incrustar scripts y hojas de estilo externos. Por ejemplo, el siguiente bloque de código muestra cómo añadir una hoja de estilos situada en `https://www.example.com/my-enhancement-styles.css` a la plantilla.

**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 se produce cualquier error, asegúrese de que su servidor de origen envía el tipo MIME correcto y los encabezados de codificación con los activos.

Por ejemplo, los tipos MIME y de codificación de scripts remotos son: `application/javascript;CHARSET=UTF-8`.

El tipo MIME y de codificación para hojas de estilo remotas es: `text/css;CHARSET=UTF-8`.

## Datos de salida y la plantilla de tareas
<a name="sms-custom-templates-step2-template-output"></a>

En las siguientes secciones se describen los datos de salida de un trabajo de etiquetado personalizado y cuándo se debe considerar el uso de una función de Lambda posterior a la anotación.

### Datos de salida
<a name="sms-custom-templates-data"></a>

Una vez finalizado el trabajo de etiquetado personalizado, los datos se guardan en el bucket de Amazon S3 que se haya especificado al crear el trabajo de etiquetado. Los datos se guardan en un archivo `output.manifest`.

**nota**  
*labelAttributeName*es una variable de marcador de posición. En la salida es el nombre del trabajo de etiquetado o el nombre del atributo de etiqueta que ha especificado al crear el trabajo de etiquetado.
+ `source` o `source-ref`: la cadena o un URI de S3 que se les ha pedido a los trabajadores que etiquetaran. 
+ `labelAttributeName`: un diccionario que incluye el contenido de etiquetas consolidado de la [función de Lambda posterior a la anotación](sms-custom-templates-step3-lambda-requirements.md#sms-custom-templates-step3-postlambda). Si no se especifica una función de Lambda posterior a la anotación, este diccionario estará vacío.
+ `labelAttributeName-metadata`: metadatos del trabajo de etiquetado personalizado añadidos por Ground Truth. 
+ `worker-response-ref`: el URI de S3 del bucket en el que se guardan los datos. Si se especifica una función de Lambda posterior a la anotación, este par clave-valor no estará presente.

En este ejemplo, se da formato al objeto JSON para facilitar su lectura. En el archivo de salida real el objeto JSON está en una única línea.

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

### Uso de una función de Lambda posterior a la anotación para consolidar los resultados de los trabajadores
<a name="sms-custom-templates-consolidation"></a>

De forma predeterminada, Ground Truth guarda las respuestas del trabajador sin procesar en Amazon S3. Para tener un control más pormenorizado sobre la forma en que se administran las respuestas, puede especificar una *función de Lambda posterior a la anotación*. Por ejemplo, una función de Lambda posterior a la anotación podría utilizarse para consolidar anotaciones si varios trabajadores han etiquetado el mismo objeto de datos. Para obtener más información sobre la creación de funciones de Lambda posteriores a la anotación, consulte [La función Lambda de postanotación](sms-custom-templates-step3-lambda-requirements.md#sms-custom-templates-step3-postlambda).

Si desea utilizar una función de Lambda posterior a la anotación, debe especificarse como parte de la [https://docs.aws.amazon.com//sagemaker/latest/APIReference/API_AnnotationConsolidationConfig.html](https://docs.aws.amazon.com//sagemaker/latest/APIReference/API_AnnotationConsolidationConfig.html) en una solicitud `CreateLabelingJob`.

Para obtener más información sobre cómo funciona la consolidación de anotaciones, consulte [Consolidación de anotaciones](sms-annotation-consolidation.md).

# Adición de automatización con Liquid
<a name="sms-custom-templates-step2-automate"></a>

Nuestro sistema de plantillas personalizado utiliza [Liquid](https://shopify.github.io/liquid/) para la automatización. Se trata de un lenguaje de marcado en línea de código abierto. En Liquid, el texto entre llaves y símbolos de porcentaje es una instrucción o *etiqueta* que lleva a cabo una operación, como un flujo de control o una iteración. El texto que está entre llaves dobles es una variable u *objeto* que genera su valor.

El uso más frecuente de Liquid consistirá en analizar los datos procedentes del archivo de manifiesto de entrada y extraer las variables pertinentes para crear la tarea. Ground Truth genera automáticamente las tareas a menos que se especifique una función de Lambda previa a la anotación. El objeto `taskInput` devuelto por Ground Truth o [Lambda de preanotación](sms-custom-templates-step3-lambda-requirements.md#sms-custom-templates-step3-prelambda) es el objeto `task.input` de las plantillas.

Las propiedades del manifiesto de entrada se transfieren a la plantilla como `event.dataObject`.

**Example objeto de datos de manifiesto**  

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

**Example HTML de ejemplo que usa variables**  

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

Tenga en cuenta la incorporación de ` | to_json` a la propiedad `labels` anterior. Es un filtro que convierte la matriz de manifiesto de entrada en una representación JSON de esta. Los filtros de variables se explican en la siguiente sección.

La siguiente lista incluye dos tipos de etiquetas de Liquid que podrían ser útiles para automatizar el procesamiento de los datos de entrada de las plantillas. Si selecciona uno de los siguientes tipos de etiquetas, se le redirigirá a la documentación de Liquid.
+ [Flujo de control](https://shopify.github.io/liquid/tags/control-flow/): incluye operadores lógicos de programación, como `if/else`, `unless` y `case/when`.
+ [Iteración](https://shopify.github.io/liquid/tags/iteration/): permite ejecutar bloques de código repetidamente con instrucciones como los bucles for. 

  Para ver un ejemplo de una plantilla HTML que utiliza elementos de Liquid para crear un bucle for, consulte [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) en. GitHub 

Para obtener más información y documentación, visite la [página de inicio de Liquid](https://shopify.github.io/liquid/).

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

Además de los [filtros](https://shopify.github.io/liquid/filters/abs/) y acciones estándar de Liquid, Ground Truth ofrece varios filtros adicionales. Los filtros se aplican colocando una barra vertical (`|`) después del nombre de la variable y luego especificando un nombre de filtro. Los filtros se pueden encadenar en forma de:

**Example**  

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

### Autoescape y escape explícito
<a name="sms-custom-templates-step2-automate-filters-autoescape"></a>

De forma predeterminada, las entradas tendrán un escape de HTML para evitar que haya confusión entre el texto de la variable y HTML. Puede añadir de forma explícita el filtro `escape` para que sea más evidente para la persona que esté leyendo la fuente de la plantilla que se esta realizando un escape.

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

`escape_once` garantiza que si ya ha escapado el código, no se vuelva a realizar un escape encima de este. Por ejemplo, garantiza que &amp; no se convierta en &amp;amp;.

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

`skip_autoescape` es útil cuando se prevé utilizar el contenido como HTML. Por ejemplo, puede que tenga unos cuantos párrafos de texto y algunas imágenes en las instrucciones completas de un cuadro delimitador.

**Utilice `skip_autoescape` con moderación**  
La práctica recomendada en el caso de las plantillas es evitar trasferir código funcional o de marcado con `skip_autoescape`, a menos que esté absolutamente seguro de que tiene un control estricto sobre lo que se transfiere. Si está pasando entradas de usuario, podría estar dejando a sus trabajadores desprotegidos ante un ataque de scripts de sitios.

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

`to_json`codificará lo que introduzcas en JSON (Object Notation)JavaScript . Si introduce un objeto, lo serializará.

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

`grant_read_access` toma un URI de S3 y lo codifica en una URL de HTTPS con un token de acceso de duración limitada para dicho recurso. Esto permite mostrar a los trabajadores objetos de foto, audio o vídeo almacenados en buckets de S3 a los que, de lo contrario, no se podrían acceder públicamente.

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

 El filtro `s3_presign` funciona de la misma forma que el filtro `grant_read_access`. `s3_presign` toma un URI de Amazon S3 y lo codifica en una URL de HTTPS con un token de acceso de duración limitada para dicho recurso. Esto permite mostrar a los trabajadores objetos de foto, audio o vídeo almacenados en buckets de S3 a los que, de lo contrario, no se podría obtener acceso públicamente.

**Example de los filtros 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 de una plantilla de clasificación automatizada.**  
Para automatizar el ejemplo de clasificación de texto sencillo, sustituya el texto del tweet por una variable.  
La plantilla de clasificación de texto siguiente tiene automatización añadida. changes/additions Están resaltados en negrita.  

```
<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>
```
Ahora el texto del tuit del ejemplo anterior se ha sustituido por un objeto. El objeto `entry.taskInput` utiliza `source` (u otro nombre que especifique en la función de Lambda previa a la anotación) como nombre de la propiedad para el texto y se inserta directamente en el HTML por estar entre llaves dobles.

# Procesar datos en un flujo de trabajo de etiquetado personalizado con AWS Lambda
<a name="sms-custom-templates-step3"></a>

En este tema puede aprender a implementar funciones de [AWS Lambda](https://aws.amazon.com/lambda/) opcionales al crear un flujo de trabajo de etiquetado personalizado. Puede especificar dos tipos de funciones de Lambda para utilizarlas con el flujo de trabajo de etiquetado personalizado.
+ *Función de Lambda previa a la anotación*: esta función procesa previamente cada objeto de datos que se envía al trabajo de etiquetado antes de enviarlo a los trabajadores.
+ *Lambda postanotación*: esta función procesa los resultados una vez que los trabajadores envían una tarea. Si especifica varios trabajadores por objeto de datos, esta función puede incluir una lógica para consolidar las anotaciones.

Si es un usuario nuevo de Lambda y Ground Truth, le recomendamos que utilice las páginas de esta sección de la siguiente manera:

1. En primer lugar, revise [Uso de las funciones de Lambda previas y posteriores a la anotaciónUso de las funciones de Lambda](sms-custom-templates-step3-lambda-requirements.md).

1. A continuación, utilice la página [Agregue los permisos necesarios para usarlos AWS Lambda con Ground Truth](sms-custom-templates-step3-lambda-permissions.md) para obtener información sobre los requisitos de seguridad y permisos para utilizar las funciones de Lambda preanotación y postanotación en un trabajo de etiquetado personalizado de Ground Truth.

1. A continuación, debe visitar la consola de Lambda o utilizar la de Lambda APIs para crear sus funciones. Utilice la sección [Creación de funciones de Lambda mediante las plantillas de Ground Truth](sms-custom-templates-step3-lambda-create.md) para obtener información sobre cómo crear funciones de Lambda.

1. Para saber cómo actualizar su función de Lambda, consulte [Prueba de las funciones de Lambda previas y posteriores a la anotación](sms-custom-templates-step3-lambda-test.md).

1. Tras crear las funciones de Lambda de preprocesamiento y postprocesamiento, selecciónelas en la sección **Funciones de Lambda** que aparece después del editor de código para su HTML personalizado en la consola de Ground Truth. Para saber cómo utilizar estas funciones en una solicitud de API `CreateLabelingJob`, consulte [Crear un trabajo de etiquetado (API)](sms-create-labeling-job-api.md).

Para ver un tutorial sobre el flujo de trabajo de etiquetado personalizado que incluya ejemplos de funciones de Lambda previas y posteriores a la anotación, consulte [Plantilla de demostración: anotación de imágenes con `crowd-bounding-box`](sms-custom-templates-step2-demo1.md).

**Topics**
+ [Uso de las funciones de Lambda previas y posteriores a la anotación](sms-custom-templates-step3-lambda-requirements.md)
+ [Agregue los permisos necesarios para usarlos AWS Lambda con Ground Truth](sms-custom-templates-step3-lambda-permissions.md)
+ [Creación de funciones de Lambda mediante las plantillas de Ground Truth](sms-custom-templates-step3-lambda-create.md)
+ [Prueba de las funciones de Lambda previas y posteriores a la anotación](sms-custom-templates-step3-lambda-test.md)

# Uso de las funciones de Lambda previas y posteriores a la anotación
<a name="sms-custom-templates-step3-lambda-requirements"></a>

Consulte estos temas para obtener más información sobre la sintaxis de las solicitudes enviadas a las funciones de Lambda previas y posteriores a la anotación, y la sintaxis de respuesta necesaria que Ground Truth utiliza en flujos de trabajo de etiquetado personalizado.

**Topics**
+ [Lambda de preanotación](#sms-custom-templates-step3-prelambda)
+ [La función Lambda de postanotación](#sms-custom-templates-step3-postlambda)

## Lambda de preanotación
<a name="sms-custom-templates-step3-prelambda"></a>

Antes de enviar una tarea de etiquetado al trabajador, se puede invocar un función de Lambda previa a la anotación opcional.

Ground Truth envía a la función de Lambda una solicitud con formato JSON para proporcionar detalles sobre el trabajo de etiquetado y el objeto de datos.

A continuación se muestran dos solicitudes con formato JSON de ejemplo.

------
#### [ 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>
    }
}
```

------

 En la siguiente lista se incluyen los esquemas de la solicitud previa a la anotación. A continuación, se describe cada parámetro.
+ `version` (cadena): es un número de versión que utiliza internamente Ground Truth.
+ `labelingJobArn` (cadena): es el nombre del recurso de Amazon, o ARN, de su trabajo de etiquetado. Este ARN se puede usar para hacer referencia al trabajo de etiquetado cuando se utilizan operaciones de la API de Ground Truth, como `DescribeLabelingJob`.
+ El `dataObject` (objeto JSON): la clave contiene una sola línea JSON, ya sea desde el archivo de manifiesto de entrada o enviada desde Amazon SNS. Los objetos de línea JSON de su manifiesto pueden tener un tamaño de 100 kilobytes como máximo y contener una gran variedad de datos. Para un trabajo de anotación de imágenes muy básico, es posible que el JSON `dataObject` solo contenga una clave `source-ref` que identifique la imagen que se va a anotar. Si el objeto de datos (por ejemplo, una línea de texto) se incluye directamente en el archivo de manifiesto de entrada, el objeto de datos se identifica con `source`. Si crea un trabajo de verificación o ajuste, esta línea puede contener datos de etiqueta y metadatos del trabajo de etiquetado anterior.

A continuación se muestran ejemplos en pestañas de una solicitud previa a la anotación. Cada parámetro de estas solicitudes de ejemplo se explica debajo de la tabla con pestañas.

------
#### [ 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"
    }
}
```

------

A cambio, Ground Truth requiere una respuesta con el siguiente formato:

**Example de datos devueltos previstos**  

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

En el ejemplo anterior, `<json object>` debe contener *todos* los datos que necesita su plantilla de tarea de trabajador personalizado. Si está llevando a cabo una tarea de cuadro delimitador donde las instrucciones no cambien en ningún momento, podría simplemente ser el recurso de HTTP(S) o Amazon S3 para su archivo de imagen. Si se trata de una tarea de análisis de opinión y diferentes objetos pueden tener diferentes opciones, es la referencia de objeto como una cadena y las opciones como una matriz de cadenas.

**Implicaciones de `isHumanAnnotationRequired`**  
Este valor es opcional, ya que su valor predeterminado será `true`. El principal caso de uso para establecerlo de forma explícita es cuando se desea excluir este objeto de datos de su etiquetado por parte de trabajadores humanos. 

Si tiene una combinación de objetos en el manifiesto, con algunos objetos que requieren anotaciones humanas y otros que no los necesitan, puede incluir un valor `isHumanAnnotationRequired` en cada objeto de datos. Puede añadir lógica a su Lambda preanotación para determinar dinámicamente si un objeto requiere una anotación y establecer este valor booleano en consecuencia.

### Ejemplos de funciones de Lambda previa a la anotación.
<a name="sms-custom-templates-step3-prelambda-example"></a>

La siguiente función de Lambda previa a la anotación básica accede al objeto JSON en `dataObject` desde la solicitud inicial y lo devuelve en el parámetro `taskInput`.

```
import json

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

Suponiendo que el archivo de manifiesto de entrada utiliza `"source-ref"` para identificar objetos de datos, la plantilla de tareas de trabajador que se utiliza en el mismo trabajo de etiquetado que esta función de Lambda preanotación debe incluir un elemento Liquid como el siguiente para su ingerir `dataObject`.

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

Si el archivo de manifiesto de entrada utilizó `source` para identificar el objeto de datos, la plantilla de tareas de trabajador puede ingerir `dataObject` con lo siguiente:

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

El siguiente ejemplo de Lambda preanotación incluye lógica para identificar la clave utilizada en `dataObject` y apuntar a ese objeto de datos mediante `taskObject` en la instrucción de devolución 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
```

## La función Lambda de postanotación
<a name="sms-custom-templates-step3-postlambda"></a>

Cuando todos los trabajadores hayan anotado el objeto de datos o cuando se haya alcanzado [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), lo que ocurra primero, Ground Truth envía esas anotaciones a su Lambda postanotación. Esta función Lambda se suele utilizar para [Consolidación de anotaciones](sms-annotation-consolidation.md).

**nota**  
Para ver un ejemplo de una función Lambda posterior a la consolidación, [consulte](https://github.com/aws-samples/aws-sagemaker-ground-truth-recipe/blob/master/aws_sagemaker_ground_truth_sample_lambda/annotation_consolidation_lambda.py) annotation\$1consolidation\$1lambda.py en [aws-sagemaker-ground-truthel](https://github.com/aws-samples/aws-sagemaker-ground-truth-recipe) GitHub repositorio -recipe.

La siguiente tabla contiene los esquemas de la solicitud postanotación. En la siguiente lista con viñetas se describe cada uno de los parámetros.

```
{
    "version": "2018-10-16",
    "labelingJobArn": <string>,
    "labelCategories": [<string>],
    "labelAttributeName": <string>,
    "roleArn" : <string>,
    "payload": {
        "s3Uri": <string>
    }
 }
```
+ `version` (cadena): un número de versión que utiliza internamente Ground Truth.
+ `labelingJobArn` (cadena): el nombre del recurso de Amazon, o ARN, de su trabajo de etiquetado. Este ARN se puede usar para hacer referencia al trabajo de etiquetado cuando se utilizan operaciones de la API de Ground Truth, como `DescribeLabelingJob`.
+ `labelCategories` (lista de cadenas): incluye las categorías de etiquetas y otros atributos que especificó en la consola o que incluyó en el archivo de configuración de categorías de etiquetas.
+ `labelAttributeName` (cadena): el nombre del trabajo de etiquetado o el nombre del atributo de etiqueta que especificó al crear el trabajo de etiquetado.
+ `roleArn` (cadena): el nombre de recurso de Amazon (ARN) del rol de ejecución de IAM que se especifica al crear el trabajo de etiquetado. 
+ `payload` (objeto JSON): un JSON que incluye una clave `s3Uri` que identifica la ubicación de los datos de anotación de ese objeto de datos en Amazon S3. El segundo bloque de código que aparece a continuación muestra un ejemplo de este archivo de anotaciones.

En el siguiente bloque de código se incluye un ejemplo de una solicitud postanotación. Cada parámetro de esta solicitud de ejemplo se explica debajo del bloque de código.

**Example de una solicitud Lambda postanotación**  

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

**nota**  
Si ningún trabajador trabaja en el objeto de datos y se ha alcanzado `TaskAvailabilityLifetimeInSeconds`, el objeto de datos se marca como erróneo y no se incluirá como parte de la invocación de Lambda postanotación.

El siguiente bloque de código contiene el esquema de carga. Este es el archivo que indica el parámetro `s3Uri` en el objeto JSON de la solicitud Lambda postanotación `payload`. Por ejemplo, si el bloque de código anterior es la solicitud Lambda postanotación, el siguiente archivo de anotaciones se encuentra en `s3://amzn-s3-demo-bucket/annotations.json`.

En la siguiente lista con viñetas se describe cada uno de los parámetros.

**Example de un archivo de anotaciones**  

```
[
    {
        "datasetObjectId": <string>,
        "dataObject": {
            "s3Uri": <string>,
            "content": <string>
        },
        "annotations": [{
            "workerId": <string>,
            "annotationData": {
                "content": <string>,
                "s3Uri": <string>
            }
       }]
    }
]
```
+ `datasetObjectId` (cadena): identifica un identificador único que Ground Truth asigna a cada objeto de datos que envíe al trabajo de etiquetado.
+ `dataObject` (objeto JSON): el objeto de datos que se etiquetó. Si el objeto de datos está incluido en el archivo de manifiesto de entrada y se identifica mediante la clave `source` (por ejemplo, una cadena), `dataObject` incluye una clave `content` que identifica el objeto de datos. De lo contrario, ubicación del objeto de datos (por ejemplo, un enlace o un URI de S3) se identifica con `s3Uri`.
+ `annotations` (lista de objetos JSON): esta lista contiene un único objeto JSON por cada anotación enviada por los trabajadores para ese `dataObject`. Un único objeto JSON contiene un `workerId` único que se puede utilizar para identificar al trabajador que envió esa anotación. La clave `annotationData` contiene uno de los siguientes valores:
  + `content` (cadena): contiene los datos de la anotación. 
  + `s3Uri` (cadena): contiene un URI de S3 que identifica la ubicación de los datos de anotación.

La siguiente tabla contiene ejemplos del contenido que puede encontrar en la carga para distintos tipos de anotaciones.

------
#### [ 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}}}"
          }
        }
      ]
    }
 ]
```

------

La función de Lambda postanotación puede contener una lógica similar a la siguiente para recorrer y acceder a todas las anotaciones contenidas en la solicitud. [Para ver un ejemplo completo, consulte [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) en el aws-sagemaker-ground-truth repositorio -recipe.](https://github.com/aws-samples/aws-sagemaker-ground-truth-recipe) GitHub En este GitHub ejemplo, debe añadir su propia lógica de consolidación de anotaciones. 

```
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))
```

**sugerencia**  
Al ejecutar algoritmos de consolidación en los datos, puede utilizar un servicio de base de datos AWS para almacenar los resultados o puede devolver los resultados procesados a Ground Truth. Los datos que devuelva a Ground Truth se almacenan en manifiestos de anotaciones consolidados en el bucket de S3 especificado para la salida durante la configuración del trabajo de etiquetado.

A cambio, Ground Truth requiere una respuesta con el siguiente formato:

**Example de datos devueltos previstos**  

```
[
   {        
        "datasetObjectId": <string>,
        "consolidatedAnnotation": {
            "content": {
                "<labelattributename>": {
                    # ... label content
                }
            }
        }
    },
   {        
        "datasetObjectId": <string>,
        "consolidatedAnnotation": {
            "content": {
                "<labelattributename>": {
                    # ... label content
                }
            }
        }
    }
    .
    .
    .
]
```
En este punto, todos los datos que envíe a su bucket de S3 que no sean `datasetObjectId` están en el objeto `content`.

Cuando devuelve anotaciones en `content`, se obtiene una entrada en el manifiesto de salida de su trabajo como la siguiente:

**Example de formato de etiqueta en manifiesto de salida**  

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

Debido a la naturaleza potencialmente compleja de una plantilla personalizada y de los datos que recopila, Ground Truth no ofrece un procesamiento más amplio de los datos.

# Agregue los permisos necesarios para usarlos AWS Lambda con Ground Truth
<a name="sms-custom-templates-step3-lambda-permissions"></a>

Es posible que tenga que configurar algunos o todos los siguientes elementos para crear y usar AWS Lambda con Ground Truth. 
+ Debe conceder un permiso a un rol o usuario de IAM (en conjunto, una entidad de IAM) para crear las funciones Lambda previas y posteriores a la anotación mediante y elegirlas al crear el AWS Lambda trabajo de etiquetado. 
+ La función de ejecución de IAM especificada al configurar el trabajo de etiquetado necesita permiso para invocar las funciones de Lambda preanotación y postanotación. 
+ Es posible que las funciones de Lambda postanotación necesiten permiso para acceder a Amazon S3.

Utilice las siguientes secciones para obtener información sobre cómo crear las entidades de IAM y conceder los permisos descritos más arriba.

**Topics**
+ [Otorgue permiso para crear y seleccionar una función AWS Lambda](#sms-custom-templates-step3-postlambda-create-perms)
+ [Conceda permiso al rol de ejecución de IAM para invocar funciones AWS Lambda](#sms-custom-templates-step3-postlambda-execution-role-perms)
+ [Otorgue permisos de Lambda postanotación para acceder a la anotación](#sms-custom-templates-step3-postlambda-perms)

## Otorgue permiso para crear y seleccionar una función AWS Lambda
<a name="sms-custom-templates-step3-postlambda-create-perms"></a>

Si no necesita permisos detallados para desarrollar funciones Lambda previas y posteriores a la anotación, puede adjuntar AWS la `AWSLambda_FullAccess` política gestionada a un usuario o rol. Esta política otorga amplios permisos para usar todas las funciones de Lambda, así como permisos para realizar acciones en otros AWS servicios con los que Lambda interactúa.

Para crear una política más detallada para los casos de uso sensibles a la seguridad, consulte la documentación [Políticas de IAM basadas en la identidad para Lambda en la Guía para](https://docs.aws.amazon.com/lambda/latest/dg/access-control-identity-based.html) desarrolladores para obtener información sobre cómo crear una política de IAM que se adapte a su caso de uso. AWS Lambda 

**Políticas de uso de la consola de Lambda**

Si desea conceder permiso a una entidad de IAM para usar la consola Lambda, [consulte Uso de la consola Lambda en la](https://docs.aws.amazon.com/lambda/latest/dg/security_iam_id-based-policy-examples.html#security_iam_id-based-policy-examples-console) Guía para desarrolladores. AWS Lambda 

Además, si desea que el usuario pueda acceder e implementar las funciones iniciales de anotación previa y posterior a la anotación de Ground Truth mediante AWS Serverless Application Repository la consola de Lambda, debe especificar el *`<aws-region>`* lugar en el que desea implementar las funciones (debe ser la misma AWS región que se utilizó para crear el trabajo de etiquetado) y añadir la siguiente política a la función de 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": "*"
        }
    ]
}
```

------

**Políticas para ver las funciones de Lambda en la consola de Ground Truth**

Para conceder a una entidad de IAM permiso para ver las funciones de Lambda en la consola de Ground Truth cuando el usuario crea un trabajo de etiquetado personalizado, la entidad debe tener los permisos que se describen [Conceda permiso a IAM para usar la consola Amazon SageMaker Ground Truth](sms-security-permission-console-access.md), incluidos los permisos descritos en la sección [Permisos del flujo de trabajo de etiquetado personalizado](sms-security-permission-console-access.md#sms-security-permissions-custom-workflow).

## Conceda permiso al rol de ejecución de IAM para invocar funciones AWS Lambda
<a name="sms-custom-templates-step3-postlambda-execution-role-perms"></a>

Si añade la política gestionada de IAM [AmazonSageMakerGroundTruthExecution](https://console.aws.amazon.com/iam/home?#/policies/arn:aws:iam::aws:policy/AmazonSageMakerGroundTruthExecution)a la función de ejecución de IAM utilizada para crear el trabajo de etiquetado, esta función tiene permiso para enumerar e invocar funciones de Lambda con una de las siguientes cadenas en el nombre de la función`GtRecipe`:`SageMaker`,,, `Sagemaker` o. `sagemaker` `LabelingFunction` 

Si los nombres de las funciones de Lambda preanotación y postanotación no incluyen uno de los términos del párrafo anterior, o si necesita un permiso más detallado que los de la política administrada `AmazonSageMakerGroundTruthExecution`, puede añadir una política similar a la siguiente para dar permiso al rol de ejecución para invocar las funciones preanotación y postanotación.

------
#### [ 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>"
            ]
        }
    ]
}
```

------

## Otorgue permisos de Lambda postanotación para acceder a la anotación
<a name="sms-custom-templates-step3-postlambda-perms"></a>

Como se describe en [La función Lambda de postanotación](sms-custom-templates-step3-lambda-requirements.md#sms-custom-templates-step3-postlambda), la solicitud de Lambda postanotación incluye la ubicación de los datos de la anotación en Amazon S3. Esta ubicación se identifica mediante la cadena `s3Uri` del objeto `payload`. Para procesar las anotaciones a medida que van llegando, incluso para una función de transferencia simple, debe asignar los permisos necesarios al [rol de ejecución de Lambda](https://docs.aws.amazon.com/lambda/latest/dg/lambda-intro-execution-role.html) postanotación para leer archivos de Amazon S3.

Hay muchas maneras de configurar su Lambda para obtener acceso a los datos de anotaciones en Amazon S3. Las dos formas más comunes son:
+ Permita que la función de ejecución de Lambda asuma la función de ejecución de SageMaker IA identificada `roleArn` en la solicitud de Lambda posterior a la anotación. Esta función de ejecución de SageMaker IA es la que se utiliza para crear el trabajo de etiquetado y tiene acceso al depósito de salida de Amazon S3 donde se almacenan los datos de anotación.
+ Conceda permiso al rol de ejecución de Lambda para obtener acceso directo al bucket de salida de Amazon S3.

Utilice las siguientes secciones para aprender a configurar estas opciones. 

**Otorgue permiso a Lambda para asumir la función de ejecución de SageMaker IA**

Para permitir que una función de Lambda asuma una función de ejecución de SageMaker IA, debe adjuntar una política a la función de ejecución de la función de Lambda y modificar la relación de confianza de la función de ejecución de SageMaker IA para permitir que Lambda la asuma.

1. [Adjunte la siguiente política de IAM](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_manage-attach-detach.html) a la función de ejecución de su función Lambda para asumir SageMaker la función de ejecución de IA identificada en. `Resource` Reemplace `222222222222` por el [identificador de la cuenta de AWS](https://docs.aws.amazon.com/general/latest/gr/acct-identifiers.html). Reemplace `sm-execution-role` por el nombre del rol asumido.

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

****  

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

------

1. [Modifique la política de confianza](https://docs.aws.amazon.com/IAM/latest/UserGuide/roles-managingrole-editing-console.html#roles-managingrole_edit-trust-policy) de la función de ejecución de la SageMaker IA para incluir lo siguiente. `Statement` Reemplace `222222222222` por el [identificador de la cuenta de AWS](https://docs.aws.amazon.com/general/latest/gr/acct-identifiers.html). Reemplace `my-lambda-execution-role` por el nombre del rol asumido.

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

****  

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

------

**Conceda permiso al rol de ejecución de Lambda para acceder a S3**

Puede añadir una política similar a la siguiente al rol de ejecución de la función de Lambda postanotación para concederle permisos de lectura de S3. *amzn-s3-demo-bucket*Sustitúyalo por el nombre del depósito de salida que especifique al crear un trabajo de etiquetado.

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

****  

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

------

Para añadir permisos de lectura de S3 a un rol de ejecución de Lambda en la consola de Lambda, utilice el siguiente procedimiento. 

**Añada permisos de lectura de S3 a la función de Lambda postanotación:**

1. Abra la página **Funciones** en la consola de Lambda.

1. Elija el nombre de la función postanotación.

1. Elija **Configuración** y, a continuación, seleccione **Permisos**.

1. Seleccione el **Nombre del rol** y la página de resumen de ese rol se abrirá en la consola de IAM en una pestaña nueva. 

1. Seleccione **Asociar políticas**.

1. Realice una de las siguientes acciones:
   + Busque y seleccione **`AmazonS3ReadOnlyAccess`** para dar permiso a la función para leer todos los buckets y objetos de la cuenta. 
   + Si necesita permisos más detallados, seleccione **Crear política** y utilice el ejemplo de política de la sección anterior para crear una política. Tenga en cuenta que debe volver a la página de resumen del rol de ejecución después de crear la política.

1. Si utilizó la política administrada `AmazonS3ReadOnlyAccess`, seleccione **Asociar política**. 

   Si creó una política nueva, vuelva a la página de resumen del rol de ejecución de Lambda y asocie la política que acaba de crear.

# Creación de funciones de Lambda mediante las plantillas de Ground Truth
<a name="sms-custom-templates-step3-lambda-create"></a>

Puede crear una función Lambda mediante la consola de Lambda AWS CLI, el o un AWS SDK en el lenguaje de programación compatible que elija. Utilice la Guía para AWS Lambda desarrolladores para obtener más información sobre cada una de estas opciones:
+ Para saber cómo crear una función de Lambda con la consola, consulte [Cree una función de Lambda con la consola](https://docs.aws.amazon.com/lambda/latest/dg/getting-started-create-function.html).
+ Para obtener información sobre cómo crear una función Lambda mediante AWS CLI, consulte Uso de [AWS Lambda con la AWS](https://docs.aws.amazon.com/lambda/latest/dg/gettingstarted-awscli.html) interfaz de línea de comandos.
+ Seleccione la sección correspondiente de la tabla de contenido para obtener más información sobre cómo trabajar con Lambda en el lenguaje que prefiera. Por ejemplo, seleccione [Compilación con Python](https://docs.aws.amazon.com/lambda/latest/dg/lambda-python.html) para obtener más información sobre el uso de Lambda con AWS SDK para Python (Boto3).

*Ground Truth proporciona plantillas de anotación previa y posterior a través de una receta AWS Serverless Application Repository (SAR).* Utilice el siguiente procedimiento para seleccionar la receta de Ground Truth en la consola de Lambda.

**Utilice la receta SAR de Ground Truth para crear funciones de Lambda preanotación y postanotación:**

1. Abra la página [https://console.aws.amazon.com/lambda/home#/functions](https://console.aws.amazon.com/lambda/home#/functions) en la consola de Lambda.

1. Seleccione **Crear función**.

1. Seleccione **Examinar el repositorio de aplicaciones sin servidor**.

1. En el cuadro de texto de búsqueda, escribe **aws-sagemaker-ground-truth-recipe** y selecciona esa aplicación.

1. Seleccione **Implementar**. La implementación de la aplicación puede tardar un par de minutos. 

   Una vez implementada la aplicación, aparecen dos funciones en la sección **Funciones** de la consola de Lambda: `serverlessrepo-aws-sagema-GtRecipePreHumanTaskFunc-<id>` y `serverlessrepo-aws-sagema-GtRecipeAnnotationConsol-<id>`. 

1. Seleccione una de estas funciones y añada su lógica personalizada en la sección **Código**.

1. Cuando haya terminado con los cambios, seleccione **Implementar** para implementarlas.

# Prueba de las funciones de Lambda previas y posteriores a la anotación
<a name="sms-custom-templates-step3-lambda-test"></a>

Puede probar las funciones de Lambda preanotación y postanotación en la consola de Lambda. Si es un usuario nuevo de Lambda, puede aprender a probar, o *invocar*, sus funciones de Lambda en la consola mediante el tutorial [Crear una función de Lambda](https://docs.aws.amazon.com/lambda/latest/dg/getting-started-create-function.html#gettingstarted-zip-function) con la consola en la Guía para desarrolladores de AWS Lambda . Puedes usar las secciones de esta página para aprender a probar las plantillas de anotación previa y posterior a la anotación de Ground Truth que se proporcionan a través de un AWS Serverless Application Repository (SAR). 

**Topics**
+ [Requisitos previos](#sms-custom-templates-step3-lambda-test-pre)
+ [Pruebe la función de Lambda preanotación](#sms-custom-templates-step3-lambda-test-pre-annotation)
+ [Pruebe la función de Lambda postanotación](#sms-custom-templates-step3-lambda-test-post-annotation)

## Requisitos previos
<a name="sms-custom-templates-step3-lambda-test-pre"></a>

Debe hacer lo siguiente para utilizar las pruebas que se describen en esta página.
+ Necesita acceso a la consola de Lambda y permiso para crear e invocar funciones de Lambda. Para saber cómo configurar estos permisos, consulte [Otorgue permiso para crear y seleccionar una función AWS Lambda](sms-custom-templates-step3-lambda-permissions.md#sms-custom-templates-step3-postlambda-create-perms)
+ Si no ha implementado la receta de SAR de Ground Truth, utilice el procedimiento [Creación de funciones de Lambda mediante las plantillas de Ground Truth](sms-custom-templates-step3-lambda-create.md) para hacerlo.
+ Para probar la función de Lambda postanotación, debe tener un archivo de datos en Amazon S3 con ejemplos de datos de anotación. Para realizar una prueba sencilla, puede copiar y pegar el siguiente código en un archivo, guardarlo como `sample-annotations.json` y [subirlo a Amazon S3](https://docs.aws.amazon.com/AmazonS3/latest/userguide/upload-objects.html). Anote el URI de S3 de este archivo; necesita esta información para configurar la prueba de Lambda postanotación.

  ```
  [{"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}]}}"}}]}]
  ```
+ Debe seguir las instrucciones para dar permiso [Otorgue permisos de Lambda postanotación para acceder a la anotación](sms-custom-templates-step3-lambda-permissions.md#sms-custom-templates-step3-postlambda-perms) a la función de ejecución de la función Lambda posterior a la anotación para que asuma la función de ejecución de SageMaker IA que utiliza para crear el trabajo de etiquetado. La función Lambda posterior a la anotación utiliza la función de ejecución de SageMaker IA para acceder al archivo de datos de la anotación, en S3. `sample-annotations.json`



## Pruebe la función de Lambda preanotación
<a name="sms-custom-templates-step3-lambda-test-pre-annotation"></a>

Utilice el siguiente procedimiento para probar la función Lambda previa a la anotación creada al implementar la receta Ground Truth AWS Serverless Application Repository (SAR). 

**Pruebe la función de Lambda preanotación de la receta de SAR de Ground Truth**

1. Abra la página [https://console.aws.amazon.com/lambda/home#/functions](https://console.aws.amazon.com/lambda/home#/functions) en la consola de Lambda.

1. Seleccione la función preanotación que se implementó a partir de la receta de SAR de Ground Truth. El nombre de esta función es similar a `serverlessrepo-aws-sagema-GtRecipePreHumanTaskFunc-<id>`.

1. En la sección **Código fuente**, selecciona la flecha situada junto a **Probar**.

1. Seleccione **Configurar un evento de prueba**.

1. Mantenga seleccionada la opción **Crear un evento de prueba nuevo**.

1. En **Plantilla de evento**, selecciona **SageMakerGround Truth PreHumanTask**. 

1. Asigne un **Nombre de evento** a su prueba.

1. Seleccione **Crear**.

1. Seleccione la flecha situada junto a **Probar** otra vez y verá que está seleccionada la prueba que ha creado, que se indica con un punto junto al nombre del evento. Si no está seleccionada, selecciónela. 

1. Seleccione **Probar** para ejecutar la prueba. 

Después de ejecutar la prueba, podrá ver los **Resultados de la ejecución**. En **Registros de la función**, debería ver una respuesta similar a la siguiente:

```
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
```

En esta respuesta, podemos ver que el resultado de la función de Lambda coincide con la sintaxis de respuesta preanotación requerida:

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

## Pruebe la función de Lambda postanotación
<a name="sms-custom-templates-step3-lambda-test-post-annotation"></a>

Utilice el siguiente procedimiento para probar la función Lambda posterior a la anotación creada al implementar la receta Ground Truth AWS Serverless Application Repository (SAR). 

**Pruebe la función de Lambda postanotación de la receta de SAR de Ground Truth**

1. Abra la página [https://console.aws.amazon.com/lambda/home#/functions](https://console.aws.amazon.com/lambda/home#/functions) en la consola de Lambda.

1. Seleccione la función postanotación que se implementó a partir de la receta de SAR de Ground Truth. El nombre de esta función es similar a `serverlessrepo-aws-sagema-GtRecipeAnnotationConsol-<id>`.

1. En la sección **Código fuente**, selecciona la flecha situada junto a **Probar**.

1. Seleccione **Configurar un evento de prueba**.

1. Mantenga seleccionada la opción **Crear un evento de prueba nuevo**.

1. En **Plantilla de evento**, selecciona **SageMakerGround Truth AnnotationConsolidation**.

1. Asigne un **Nombre de evento** a su prueba.

1. Modifique el código de la plantilla de la siguiente manera:
   + Sustituya el nombre del recurso de Amazon (ARN) por el `roleArn` ARN de la función de ejecución de SageMaker IA que utilizó para crear el trabajo de etiquetado.
   + Sustituya el URI de S3 en `s3Uri` por el URI del archivo `sample-annotations.json` que ha añadido a Amazon S3.

   Después de realizar estas modificaciones, la prueba debería tener un aspecto similar al siguiente:

   ```
   {
     "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. Seleccione **Crear**.

1. Seleccione la flecha situada junto a **Probar** otra vez y verá que está seleccionada la prueba que ha creado, que se indica con un punto junto al nombre del evento. Si no está seleccionada, selecciónela. 

1. Seleccione **Probar** para ejecutar la prueba. 

Tras ejecutar la prueba, debería ver una sección `-- Consolidated Output --` en los **Registros de las funciones**, que contiene una lista de todas las anotaciones incluidas en `sample-annotations.json`.

# Plantilla de demostración: anotación de imágenes con `crowd-bounding-box`
<a name="sms-custom-templates-step2-demo1"></a>

Si eliges usar una plantilla personalizada como tipo de tarea en la consola Amazon SageMaker Ground Truth, accedes al **panel de tareas de etiquetado personalizado**. Ahí puede elegir entre varias plantillas básicas. Las plantillas representan algunas de las tareas más frecuentes y proporcionan una muestra a partir de la cual trabajar cuando se crea la plantilla de la tarea de etiquetado personalizada. Si no utilizas la consola o como recurso adicional, consulta [Amazon SageMaker AI Ground Truth Sample Task UIs ](https://github.com/aws-samples/amazon-sagemaker-ground-truth-task-uis) para ver un repositorio de plantillas de demostración para distintos tipos de tareas de etiquetado.

Esta demostración funciona con la **BoundingBox**plantilla. La demostración también funciona con las AWS Lambda funciones necesarias para procesar los datos antes y después de la tarea. En el repositorio de Github anterior, para encontrar plantillas que funcionen con AWS Lambda funciones, busca `{{ task.input.<property name> }}` en la plantilla.

**Topics**
+ [Plantilla personalizada de cuadro delimitador de inicio](#sms-custom-templates-step2-demo1-base-template)
+ [Su propia plantilla personalizada de cuadro delimitador de inicio](#sms-custom-templates-step2-demo1-your-own-template)
+ [El archivo de manifiesto](#sms-custom-templates-step2-demo1-manifest)
+ [La función Lambda preanotación](#sms-custom-templates-step2-demo1-pre-annotation)
+ [La función Lambda de postanotación](#sms-custom-templates-step2-demo1-post-annotation)
+ [La salida del trabajo de etiquetado](#sms-custom-templates-step2-demo1-job-output)

## Plantilla personalizada de cuadro delimitador de inicio
<a name="sms-custom-templates-step2-demo1-base-template"></a>

Esta es la plantilla de cuadro delimitador de inicio que se proporciona.

```
<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>
```

La plantillas personalizadas utilizan el [lenguaje de plantillas de Liquid](https://shopify.github.io/liquid/) y todos los elementos que están entre llaves dobles son variables. La AWS Lambda función de anotación previa debe proporcionar un nombre a un objeto `taskInput` y se puede acceder a las propiedades de ese objeto como `{{ task.input.<property name> }}` en tu plantilla.

## Su propia plantilla personalizada de cuadro delimitador de inicio
<a name="sms-custom-templates-step2-demo1-your-own-template"></a>

Por ejemplo, supongamos que tiene una gran colección de fotos de animales en la que sabe el tipo de animal por un trabajo de clasificación de imágenes anterior. Ahora quiere que tengan dibujado a su alrededor un cuadro delimitador.

En el ejemplo de inicio, hay tres variables: `taskObject`, `header` y `labels`.

Cada uno de estos ejemplos estaría representado en diferentes partes del cuadro delimitador.
+ `taskObject` es una URL de HTTPS o URI de S3 para la foto que se va a comentar. El `| grant_read_access` añadido es un filtro que convertirá un URI de S3 en una URL de HTTPS con acceso de duración limitada a ese recurso. Si está utilizando una dirección URL de HTTPS, no es necesario.
+ `header` es el texto que esta encima de la foto que se va a etiquetar; algo así como "Dibujar un cuadro en torno al pájaro de la foto".
+ `labels` es una matriz, representada como `['item1', 'item2', ...]`. Se trata de etiquetas que el trabajador puede asignar a los diferentes cuadros que dibuja. Puede tener uno o varios.

Cada uno de los nombres de variables proceden del objeto JSON de la respuesta de su Lambda de preanotación. Los nombres que están encima son simples sugerencias. Use los nombres de variables que tengan sentido para usted y facilitará la legibilidad del código entre su equipo.

**Use variables solo cuando sea necesario**  
Si un campo no va a cambiar, puede quitar esa variable de la plantilla y reemplazarla con ese texto, de lo contrario tendrá que repetir dicho texto como valor en cada uno de los objetos de su manifiesto o codificarlo en la función de Lambda preanotación.

**Example : plantilla de cuadro delimitador personalizada final**  
Para mantener las cosas simples, esta plantilla tendrá una variable, una etiqueta e instrucciones básicas. Suponiendo que el manifiesto tiene una propiedad "animal" en cada objeto de datos, dicho valor se puede volver a utilizar en dos partes de la plantilla.  

```
<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>
```
Observe la reutilización de `{{ task.input.animal }}` en toda la plantilla. Si el manifiesto tenía todos los nombres de animales escritos con una letra mayúscula al principio, podría utilizar `{{ task.input.animal | downcase }}`, que incorpora uno de los filtros integrados de Liquid en frases en las que sea necesario que la presentación sea en minúsculas.

## El archivo de manifiesto
<a name="sms-custom-templates-step2-demo1-manifest"></a>

El archivo de manifiesto debe proporcionar los valores de las variables que esté utilizando en la plantilla. Puede realizar algunas transformaciones en los datos del manifiesto de su Lambda preanotación, pero si no es necesario, tendrá un menor riesgo de errores y su Lambda se ejecutará con mayor rapidez. A continuación le mostramos un archivo de manifiesto de ejemplo para la plantilla.

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

## La función Lambda preanotación
<a name="sms-custom-templates-step2-demo1-pre-annotation"></a>

Como parte de la configuración del trabajo, proporciona el ARN de AWS Lambda una función a la que se pueda llamar para procesar las entradas del manifiesto y pasarlas al motor de plantillas.

**Asignación del nombre de la función de Lambda**  
La práctica recomendada para dar un nombre a su función es utilizar una de las cuatro cadenas siguientes como parte del nombre de función: `SageMaker`, `Sagemaker`, `sagemaker` o `LabelingFunction`. Esto se aplica tanto a las funciones de preanotación como de postanotación.

Cuando utilice la consola, si tiene funciones de AWS Lambda que son propiedad de su cuenta, se mostrará una lista desplegable de las funciones que cumplen los requisitos de denominación para elegir una.

En este ejemplo muy básico, solo transfiere la información del manifiesto sin necesidad de realizar ningún procesamiento adicional en él. Esta función de preanotación de muestra está escrita para Python 3.7.

```
import json

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

El objeto JSON del manifiesto se proporcionará como elemento secundario del objeto `event`. Las propiedades del interior del objeto `taskInput` estarán disponibles como variables para la plantilla, por lo que con solo establecer el valor de `taskInput` en `event['dataObject']` se pasarán todos los valores de su objeto de manifiesto a la plantilla sin tener que copiarlos individualmente. Si desea enviar más valores a la plantilla, puede añadirlos al objeto `taskInput`.

## La función Lambda de postanotación
<a name="sms-custom-templates-step2-demo1-post-annotation"></a>

Como parte de la configuración del trabajo, proporcione el ARN de AWS Lambda una función a la que se pueda llamar para procesar los datos del formulario cuando un trabajador complete una tarea. Esto puede ser tan sencillo o complejo como desee. Si desea consolidar y puntuar las respuestas a medida que se presentan, puede aplicar los algoritmos de and/or consolidación de puntuaciones que prefiera. Si desea almacenar los datos sin procesar para el procesamiento sin conexión, esto es una opción.

**Proporcione permisos a su Lambda de postanotación**  
Los datos de anotaciones estarán en un archivo designado por la cadena `s3Uri` en el objeto `payload`. Para procesar las anotaciones a medida que están disponibles, incluso para una sencilla función de acceso directo, tiene que asignar el acceso `S3ReadOnly` a su Lambda para que pueda los archivos de anotaciones.  
En la página Console (Consola) de creación de su Lambda, desplácese hasta el panel **Execution role (Rol de ejecución)**. Seleccione **Create a new role from one or more templates (Crear un rol nuevo a partir de una o varias plantillas)**. Ponga un nombre al rol. Desde el menú desplegable **Policy templates (Plantillas de políticas)**, elija **Amazon S3 object read-only permissions (Permisos de solo lectura de objetos Amazon S3)**. Guarde la función de Lambda y el rol se guardará y seleccionará.

El siguiente ejemplo se encuentra en 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 función Lambda de postanotación recibirá a menudo lotes de resultados de tareas en el objeto de evento. Este lote será el objeto `payload` que Lambda deberá iterar. Lo que se devolverá será un objeto que cumple el [contrato de API](sms-custom-templates-step3.md).

## La salida del trabajo de etiquetado
<a name="sms-custom-templates-step2-demo1-job-output"></a>

Encontrará la salida del trabajo en una carpeta llamada como el trabajo de etiquetado del bucket de S3 que ha especificado. Estará en una subcarpeta denominada `manifests`.

Para una tarea de cuadro delimitador, el resultado que encuentre en el manifiesto de salida tendrá un aspecto similar al de la demostración siguiente. El ejemplo se ha limpiado para su impresión. El resultado real será una sola línea por registro.

**Example : JSON en su manifiesto de salida**  

```
{
  "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"
}
```
Observe cómo se pasa el atributo `animal` adicional de su manifiesto original al manifiesto de salida en el mismo nivel que `source-ref` y los datos de etiquetado. Cualquier propiedad de su manifiesto de entrada, independientemente de si se ha utilizado en la plantilla o no, se transferirá al manifiesto de salida.

# Plantilla de demostración: intenciones de etiquetado con `crowd-classifier`
<a name="sms-custom-templates-step2-demo2"></a>

Si elige una plantilla personalizada, irá a **Custom labeling task panel (Panel de tareas de etiquetado personalizadas)**. Ahí puede elegir entre varias plantillas para principiantes que representan algunas de las tareas más frecuentes. Las plantillas proporcionan un punto de partida para trabajar en la creación de la plantilla de la tarea de etiquetado personalizada.

En esta demostración, trabajará con la plantilla **Intent Detection (Detección de intentos)**, que utiliza el elemento `crowd-classifier` y las funciones AWS Lambda necesarias para procesar los datos antes y después de la tarea.

**Topics**
+ [Plantilla personalizada de detección de intentos para principiantes](#sms-custom-templates-step2-demo2-base-template)
+ [La plantilla personalizada de detección de intentos](#sms-custom-templates-step2-demo2-your-template)
+ [La función Lambda de preanotación](#sms-custom-templates-step2-demo2-pre-lambda)
+ [La función Lambda de postanotación](#sms-custom-templates-step2-demo2-post-lambda)
+ [Su salida de trabajo de etiquetado](#sms-custom-templates-step2-demo2-job-output)

## Plantilla personalizada de detección de intentos para principiantes
<a name="sms-custom-templates-step2-demo2-base-template"></a>

Esta es la plantilla de detección de intentos que se proporciona como punto de partida.

```
<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>
```

La plantillas personalizadas utilizan el [lenguaje de plantillas de Liquid](https://shopify.github.io/liquid/) y todos los elementos que están entre llaves dobles son variables. La función AWS Lambda previa a la anotación debe proporcionar un nombre de objeto `taskInput` y se puede acceder a las propiedades de ese objeto como `{{ task.input.<property name> }}` en la plantilla.

## La plantilla personalizada de detección de intentos
<a name="sms-custom-templates-step2-demo2-your-template"></a>

En la plantilla inicial, existen dos variables: la propiedad `task.input.labels` en la etiqueta de apertura del elemento `crowd-classifier` y la propiedad `task.input.utterance` en el contenido de la región `classification-target`.

A menos que necesite ofrecer diferentes conjuntos de etiquetas con distintos enunciados, evite el uso de una variable y utilice simplemente texto, ya que así ahorrará tiempo de procesamiento y existirá un menor riesgo de errores. La plantilla que se utiliza en esta demostración eliminará esa variable, pero las variables y los filtros como `to_json` se explican con más detalle en el artículo de [demostración de `crowd-bounding-box`]().

### Estilo de los elementos
<a name="sms-custom-templates-step2-demo2-instructions"></a>

Dos partes de estos elementos personalizados que a veces se pasan por alto son las regiones `<full-instructions>` y `<short-instructions>`. Unas buenas instrucciones generan buenos resultados.

En los elementos que incluyen estas regiones, las `<short-instructions>` aparecen automáticamente en el panel de instrucciones situado a la izquierda de la pantalla del proceso de trabajo. Se puede obtener acceso a las `<full-instructions>` desde el enlace "View full instructions" (Ver instrucciones completas) situado cerca de la parte superior de ese panel. Al hacer clic en el enlace, se abre un panel modal con instrucciones más detalladas.

No solo puede utilizar HTML y CSS, sino que JavaScript en estas secciones le recomendamos que lo haga si cree que puede proporcionar un conjunto sólido de instrucciones y ejemplos que ayudarán a los trabajadores a completar sus tareas con mayor rapidez y precisión. 

**Example Pruebe una muestra con JSFiddle**  
[https://jsfiddle.net/MTGT_Fiddle_Manager/bjc0y1vd/35/](https://jsfiddle.net/MTGT_Fiddle_Manager/bjc0y1vd/35/)  
 Pruebe una [tarea de `<crowd-classifier>` de ejemplo](https://jsfiddle.net/MTGT_Fiddle_Manager/bjc0y1vd/35/). El ejemplo se representa mediante JSFiddle, por lo tanto, todas las variables de la plantilla se sustituyen por valores codificados de forma rígida. Haga clic en el enlace "View full instructions (Ver instrucciones completas)" para ver un conjunto de ejemplos con estilo CSS extendido. Puedes bifurcar el proyecto para experimentar con tus propios cambios en el CSS, añadir imágenes de ejemplo o añadir JavaScript funciones ampliadas.

**Example : plantilla de detección de intentos personalizada final**  
Aquí se utiliza la [tarea de `<crowd-classifier>` de ejemplo](https://jsfiddle.net/MTGT_Fiddle_Manager/bjc0y1vd/35/), pero con una variable para `<classification-target>`. Si está intentando mantener un diseño CSS consistente entre una serie de trabajos de etiquetado distintos, puede incluir una hoja de estilo externa mediante un elemento `<link rel...>` de la misma forma que haría en cualquier otro documento 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 : su archivo de manifiesto**  
Si está preparando manualmente el archivo de manifiesto para una tarea de clasificación de texto de este tipo, dé un formato a los datos de la siguiente manera:  

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

Esto difiere del archivo de manifiesto utilizado para la demostración "[Plantilla de demostración: anotación de imágenes con `crowd-bounding-box`](sms-custom-templates-step2-demo1.md)" en que `source-ref` se utilizó como el nombre de la propiedad en lugar de `source`. El uso de `source-ref` designa S3 URIs para imágenes u otros archivos que deben convertirse a HTTP. De lo contrario, debe utilizarse `source` tal cual con las cadenas de texto anteriores.

## La función Lambda de preanotación
<a name="sms-custom-templates-step2-demo2-pre-lambda"></a>

Como parte de la configuración del trabajo, proporciona el ARN de AWS Lambda una persona a la que se pueda llamar para procesar las entradas del manifiesto y pásalas al motor de plantillas. 

Esta función de Lambda debe tener una de las cuatro cadenas siguientes como parte del nombre de la función: `SageMaker`, `Sagemaker`, `sagemaker` o `LabelingFunction`.

Esto se aplica tanto a las Lambdas de preanotación como de postanotación.

Cuando utiliza la consola, si tiene Lambda que son propiedad de su cuenta, se proporcionará una lista desplegable de funciones que cumplen los requisitos de nomenclatura para que elija una.

En este ejemplo muy básico donde solo tiene una variable, se trata básicamente de una función de paso a través. A continuación, le mostramos una función de Lambda de etiquetado previo de ejemplo que utiliza Python 3.7.

```
import json

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

La propiedad `dataObject` de `event` contiene las propiedades de un objeto de datos del manifiesto.

En esta demostración, que es un simple acceso directo, solo pasa esto directamente como el valor `taskInput`. Si añade propiedades con esos valores al objeto `event['dataObject']`, estas estarán disponibles para la plantilla HTML como variables Liquid con el formato `{{ task.input.<property name> }}`.

## La función Lambda de postanotación
<a name="sms-custom-templates-step2-demo2-post-lambda"></a>

Como parte de la configuración del trabajo, tendrá que proporcionar el ARN de una función de Lambda a la que se puede llamar para procesar los datos de formulario cuando un trabajador completa una tarea. Esto puede ser tan sencillo o complejo como desee. Si desea realizar la consolidación y puntuación de respuestas a medida que entran los datos, puede aplicar los algoritmos de puntuación o consolidación que desee. Si desea almacenar los datos sin procesar para el procesamiento sin conexión, esto es una opción.

**Establecimiento de permisos a su función lambda de postanotación**  
Los datos de anotaciones estarán en un archivo designado por la cadena `s3Uri` en el objeto `payload`. Para procesar las anotaciones a medida que están disponibles, incluso para una sencilla función de acceso directo, tiene que asignar el acceso `S3ReadOnly` a su Lambda para que pueda los archivos de anotaciones.  
En la página Console (Consola) de creación de su Lambda, desplácese hasta el panel **Execution role (Rol de ejecución)**. Seleccione **Create a new role from one or more templates (Crear un rol nuevo a partir de una o varias plantillas)**. Ponga un nombre al rol. Desde el menú desplegable **Policy templates (Plantillas de políticas)**, elija **Amazon S3 object read-only permissions (Permisos de solo lectura de objetos Amazon S3)**. Guarde la función de Lambda y el rol se guardará y seleccionará.

El siguiente ejemplo es para 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
```

## Su salida de trabajo de etiquetado
<a name="sms-custom-templates-step2-demo2-job-output"></a>

La función Lambda de postanotación recibirá a menudo lotes de resultados de tareas en el objeto de evento. Este lote será el objeto `payload` que Lambda deberá iterar.

Encontrará la salida del trabajo en una carpeta llamada como el trabajo de etiquetado del bucket de S3 que ha especificado. Estará en una subcarpeta denominada `manifests`.

Para una tarea de detección de intentos, el resultado del manifiesto de salida tendrá un aspecto similar al de la demostración siguiente. Hemos limpiado e incluido espacios en el ejemplo para facilitar su comprensión. La salida real estará más comprimida para la lectura automática.

**Example : JSON en su manifiesto de salida**  

```
[
  {
    "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>"
           }
         }
       }
     }
   },
     ...
     ...
     ...
]
```

Esto puede serle útil para crear y utilizar su propia plantilla personalizada.

# Creación de un flujo de trabajo personalizado mediante la API
<a name="sms-custom-templates-step4"></a>

Cuando haya creado su plantilla de interfaz de usuario personalizada (paso 2) y las funciones de Lambda de procesamiento (paso 3), debe colocar la plantilla en un bucket de Amazon S3 con un formato de nombre de archivo como el siguiente: `<FileName>.liquid.html`. Utilice la acción [https://docs.aws.amazon.com/sagemaker/latest/APIReference/API_CreateLabelingJob.html](https://docs.aws.amazon.com/sagemaker/latest/APIReference/API_CreateLabelingJob.html) para configurar su tarea. Utilizará la ubicación de una plantilla personalizada ([Creación de una plantilla personalizada de tareas de trabajador](sms-custom-templates-step2.md)) almacenada en un archivo `<filename>.liquid.html` en S3 como el valor del campo `UiTemplateS3Uri` en el objeto [https://docs.aws.amazon.com/sagemaker/latest/APIReference/API_UiConfig.html](https://docs.aws.amazon.com/sagemaker/latest/APIReference/API_UiConfig.html) dentro del objeto[https://docs.aws.amazon.com/sagemaker/latest/APIReference/API_HumanTaskConfig.html](https://docs.aws.amazon.com/sagemaker/latest/APIReference/API_HumanTaskConfig.html).

Para las tareas de AWS Lambda descritas en[Procesar datos en un flujo de trabajo de etiquetado personalizado con AWS Lambda](sms-custom-templates-step3.md), el ARN de la tarea posterior a la anotación se utilizará como valor del `AnnotationConsolidationLambdaArn` campo y la tarea de anotación previa se utilizará como valor para `PreHumanTaskLambdaArn.` 