Plantilla de demostración: anotación de imágenes con crowd-bounding-box - Amazon SageMaker

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.

Plantilla de demostración: anotación de imágenes con crowd-bounding-box

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 las interfaces de usuario de Amazon SageMaker Ground Truth, donde encontrarás un repositorio de plantillas de demostración para distintos tipos de tareas de etiquetado.

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

Plantilla personalizada de cuadro delimitador de inicio

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 y todos los elementos que están entre llaves dobles son variables. La función de AWS Lambda de preanotación debe proporcionar un objeto denominado taskInput y se puede obtener acceso a las propiedades de dicho objeto como {{ task.input.<property name> }} en la plantilla.

Su propia plantilla personalizada de cuadro delimitador de inicio

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.

ejemplo : 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

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

Como parte de la configuración del trabajo, proporcione el ARN de una función AWS Lambda que se puede llamar para procesar las entradas de manifiesto y transferirlas al motor de la plantilla.

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 utiliza la consola, si tiene funciones de Lambda de AWS 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, 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

Como parte de la configuración del trabajo, tiene que proporcionar el ARN de una función AWS Lambda que se pueda llamar para procesar los datos de formulario cuando un trabajador complete una tarea. Esto puede ser tan sencillo o complejo como desee. Si desea realizar la consolidación y puntuación de respuestas tal y como viene, puede aplicar los algoritmos de puntuación o consolidación de su elección. 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.

La salida del trabajo de etiquetado

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 llamada 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.

ejemplo : 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.