演示模板:使用 crowd-bounding-box 的图像注释 - Amazon SageMaker

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

演示模板:使用 crowd-bounding-box 的图像注释

当您在 Amazon G SageMaker round Truth 控制台中选择使用自定义模板作为任务类型时,您将进入自定义标签任务面板。在该面板中,您可以从多个基本模板中进行选择。模板表示一些最常见的任务,并在您创建自定义标注任务的模板时提供样本。如果您没有使用控制台,或者作为其他补救措施,请参阅 Amazon G SageMaker round Truth 示例任务 UIs,了解各种标签任务类型的演示模板存储库。

此演示与BoundingBox模板一起使用。该演示还适用于 AWS Lambda 在任务之前和之后处理数据所需的函数。在上面的 Github 存储库中,查找与之配合使用的模板 AWS Lambda 函数,在模板{{ task.input.<property name> }}中查找。

入门边界框自定义模板

这是所提供的入门边界框模板。

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

此自定义模板使用 Liquid 模板语言,双大括号之间的每个项都是一个变量。预注释 AWS Lambda 函数应提供一个名为的对象,taskInput并且可以像在模板{{ task.input.<property name> }}中一样访问该对象的属性。

您自己的边界框自定义模板

举例来说,假设您有大量的动物照片,您可以通过之前的图像分类作业知道图像中的动物种类。现在,您希望在其周围绘制一个边界框。

在入门示例中,有三个变量:taskObjectheaderlabels

其中每个变量都表示在边界框的不同部分中。

  • taskObject是 HTTP (S) URL 或 S3 表示要URI为照片添加批注。添加的过滤| grant_read_access器会将 S3 URI 转换为对该资源HTTPSURL具有短暂访问权限的。如果你使用的是 HTTP (S)URL,则不需要。

  • header 是照片上方要标注的文本,如“在照片中的鸟周围画一个框”。

  • labels 是一个数组,表示为 ['item1', 'item2', ...]。这些标签可以由工作人员分配给他们绘制的不同边界框。您可以有一个或多个标签。

每个变量名称都来自您的预注释 Lambda 的响应中的JSON对象,上面的名称只是建议的,使用任何对您有意义的变量名称,这将提高团队中代码的可读性。

仅在必要时才使用变量

如果某个字段不会改变,可以从模板中删除该变量并用该文本替换,否则就必须在清单中的每个对象中重复该文本作为值,或者将其编码到注释前 Lambda 函数中。

例 :最终的自定义边界框模板

为简单起见,此模板将具有一个变量、一个标签和非常基本的说明。假设您的清单中每个数据对象都有一个“animal”属性,那么这个值就可以在模板的两个部分中重复使用。

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

注意在整个模板中重复使用 {{ task.input.animal }}。如果您的清单中所有动物名称都以大写字母开头,您可以使用 {{ task.input.animal | downcase }},在需要小写的句子中加入 Liquid 的内置筛选器之一。

您的清单文件

您的清单文件应提供您在模板中使用的变量值。您可以在注释前 Lambda 中对清单数据进行一些转换,但如果您不需要这样做,就可以保持较低的出错风险,而且 Lambda 运行速度也会更快。下面是模板的清单文件示例。

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

注释前 Lambda 函数

作为工作设置的一部分,请ARN提供 AWS Lambda 可以调用该函数来处理您的清单条目并将其传递给模板引擎。

命名 Lambda 函数

命名函数的最佳实践是使用以下四个字符串之一作为函数名称的一部分:SageMakerSagemakersagemakerLabelingFunction。这同时适用于注释前函数和注释后函数。

当你使用主机时,如果你有 AWS 您的账户拥有的 Lambda 函数,将提供符合命名要求的函数的下拉列表供您选择。

在这个非常基本的示例中,您只是传递来自清单的信息,而不对其进行任何额外的处理。这个注释前函数示例是为 Python 3.7 编写的。

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

清单中的JSON对象将作为该event对象的子对象提供。taskInput 对象内部的属性将作为变量提供给模板,因此只需将 taskInput 的值设置为 event['dataObject'] 即可将清单对象中的所有值传递给模板,而无需单独复制它们。如果您希望向模板发送更多的值,可以将这些值添加到 taskInput 对象中。

注释后 Lambda 函数

作为工作设置的一部分,请ARN提供 AWS Lambda 当工作人员完成任务时,可以调用该函数来处理表单数据。这可以很简单,也可以很复杂。如果您想对收到的答案进行合并和评分,您可以应用自己选择的评分和/或合并算法。如果您想要存储原始数据以进行脱机处理,则这是一个选项。

提供对注释后 Lambda 的权限

注释数据将位于一个文件中,该文件由 payload 对象中的 s3Uri 字符串指定。要处理传入的注释,即使是简单的传递函数,也需要为 Lambda 分配 S3ReadOnly 访问权限,以使其能够读取注释文件。

在创建 Lambda 的控制台页面中,滚动到执行角色面板。选择从一个或多个模板中创建新角色。指定角色的名称。从策略模板下拉列表中,选择 Amazon S3 对象只读权限。保存 Lambda,将保存并选择该角色。

下面是 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

注释后 Lambda 通常会在事件对象中接收成批的任务结果。该批次将是 Lambda 应该遍历的 payload 对象。你寄回的将是一个符合API合同的对象。

标注作业的输出

您将在指定的目标 S3 存储桶中以标注作业命名的文件夹中找到作业的输出。它将位于名为 manifests 的子文件夹中。

对于边界框任务,您在输出清单找到的输出将有点类似于下面的演示。该示例已清理以供打印。实际输出将是每条记录一行。

例 : JSON 在你的输出清单中
{ "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" }

请注意原始清单中的 animal 附加属性是如何与 source-ref 和标注数据同级传递到输出清单的。输入清单中的任何属性,无论是否在模板中使用,都将传递到输出清单中。