注释前和注释后 Lambda 函数要求 - Amazon SageMaker

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

注释前和注释后 Lambda 函数要求

使用本节可以了解发送到注释前和注释后 Lambda 函数的请求的语法,以及 Ground Truth 运行自定义标注工作流所需的响应语法。

注释前 Lambda

在将标注任务发送给工作人员之前,会调用注释前 Lambda 函数。

JSONGround Truth 向您的 Lambda 函数发送一个格式化的请求,以提供有关标签任务和数据对象的详细信息。下表包含注释前请求模式。每个参数的说明如下。

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> } }
  • version(字符串):这是 Ground Truth 内部使用的版本号。

  • labelingJobArn(字符串):这是您的贴标任务的 Amazon 资源名称或ARN。在使用 Ground Truth API 操作时,这ARN可用于引用标注作业,例如DescribeLabelingJob

  • dataObject(JSON对象):密钥包含一JSON行,要么来自您的输入清单文件,要么从亚马逊发送SNS。清单中的JSON行对象的大小可达 100 千字节,并且包含各种数据。对于非常基本的图像注释作业,dataObjectJSON可能只包含一个用于标识要注释的图像的source-ref密钥。如果数据对象(例如,一行文本)直接包含在输入清单文件中,则用 source 标识数据对象。如果您创建验证或调整作业,则此行可能包含来自前一个标注作业的标签数据和元数据。

下表包括注释前请求的代码块示例。这些示例请求中的每个参数都在选项卡式表下面进行了说明。

Data object identified with "source-ref"
{ "version": "2018-10-16", "labelingJobArn": "arn:aws:sagemaker:<aws_region>:<aws_account_number>: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>:<aws_account_number>:labeling-job/<labeling_job_name>" "dataObject" : { "source": "Sue purchased 10 shares of the stock on April 10th, 2020" } }

作为返回对象,Ground Truth 需要如下格式的响应:

例 预期的返回数据
{ "taskInput": <json object>, "isHumanAnnotationRequired": <boolean> # Optional }

在前面的示例中,<json object> 需要包含自定义工作人员任务模板所需的所有数据。如果您正在执行指令始终保持不变的边界框任务,则可能只是图像文件的 HTTP (S) 或 Amazon S3 资源。如果执行的是情绪分析任务,并且不同的对象可能有不同的选择,那么是作为字符串的对象引用和作为字符串数组的选项。

isHumanAnnotationRequired 的含义

该值是可选的,因为它默认为 true。显式设置该值的主要使用案例是当您想要将此数据对象从人工标注范围中排除时。

如果清单中的对象多种多样,有些需要人工注释,有些则不需要,那么可以在每个数据对象中包含 isHumanAnnotationRequired 值。您可以在注释前 Lambda 中添加逻辑,以动态确定对象是否需要注释,并相应地设置该布尔值。

注释前 Lambda 函数的示例

以下基本预注解 Lambda 函数访问初始请求JSONdataObject中的对象,并在参数中返回该对象。taskInput

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

假设输入清单文件使用 "source-ref" 来标识数据对象,那么在与此注释前 Lambda 相同的标注作业中使用的工作人员任务模板必须包含类似下面的 Liquid 元素,以摄取 dataObject

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

如果输入清单文件使用 source 来标识数据对象,那么工作任务模板可以通过以下方式摄取 dataObject

{{ task.input.source }}

下面的注释前 Lambda 示例包含一个逻辑,用于识别 dataObject 中使用的键,并在 Lambda 的返回语句中使用 taskObject 指向该数据对象。

import json def lambda_handler(event, context): # Event received print("Received event: " + json.dumps(event, indent=2)) # Get source if specified source = event['dataObject']['source'] if "source" in event['dataObject'] else None # Get source-ref if specified source_ref = event['dataObject']['source-ref'] if "source-ref" in event['dataObject'] else None # if source field present, take that otherwise take source-ref task_object = source if source is not None else source_ref # Build response object output = { "taskInput": { "taskObject": task_object }, "humanAnnotationRequired": "true" } print(output) # If neither source nor source-ref specified, mark the annotation failed if task_object is None: print(" Failed to pre-process {} !".format(event["labelingJobArn"])) output["humanAnnotationRequired"] = "false" return output

注释后 Lambda

当所有工作人员都注释了数据对象或达到 TaskAvailabilityLifetimeInSeconds(以先到者为准)时,Ground Truth 将这些注释发送到您的注释后 Lambda。此 Lambda 通常用于注释合并

提示

要查看合并后 Lambda 函数的示例,请参阅-recipe 存储aws-sagemaker-ground-truth中的 GitHub annotation_consolidation_lambda.py。

以下代码块包含注释后请求模式。下面的项目符号列表中描述了每个参数。

{ "version": "2018-10-16", "labelingJobArn": <string>, "labelCategories": [<string>], "labelAttributeName": <string>, "roleArn" : <string>, "payload": { "s3Uri": <string> } }
  • version(字符串):Ground Truth 内部使用的版本号。

  • labelingJobArn(字符串):您的贴标任务的 Amazon 资源名称或ARN。在使用 Ground Truth API 操作时,这ARN可用于引用标注作业,例如DescribeLabelingJob

  • labelCategories(字符串列表):包括在控制台中指定或包含在标签类别配置文件中的标签类别和其他属性。

  • labelAttributeName(字符串):标注作业的名称或创建标注作业时指定的标签属性名称。

  • roleArn(字符串):您在创建标签任务时指定的IAM执行角色的 Amazon 资源名称 (ARN)。

  • payload(JSON对象):JSON包含s3Uri密钥的,用于标识该数据对象的注释数据在 Amazon S3 中的位置。下面的第二个代码块显示了此注释文件的示例。

以下代码块包含注释后请求的示例。此示例请求中的每个参数都在代码块下面进行了说明。

例 注释后 Lambda 请求
{ "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" } }
注意

如果没有工作人员处理数据对象并且已经达到 TaskAvailabilityLifetimeInSeconds,则数据对象被标记为失败,并且不包括在注释后 Lambda 调用中。

下面的代码块包含负载模式。此文件由注释后 Lambda payload JSON 请求对象中的s3Uri参数指示。例如,如果前面的代码块是注释后 Lambda 请求,则下面的注释文件位于 s3://amzn-s3-demo-bucket/annotations.json

下面的项目符号列表中描述了每个参数。

例 注释文件
[ { "datasetObjectId": <string>, "dataObject": { "s3Uri": <string>, "content": <string> }, "annotations": [{ "workerId": <string>, "annotationData": { "content": <string>, "s3Uri": <string> } }] } ]
  • datasetObjectId(字符串):标识 Ground Truth 为发送到标注作业的每个数据对象分配的唯一 ID。

  • dataObject(JSON对象):被标记的数据对象。如果数据对象包含在输入清单文件中并使用 source 键(例如,字符串)进行标识,则 dataObject 包括一个用于标识数据对象的 content 键。否则,将使用标识数据对象(例如,链接或 S3URI)的位置s3Uri

  • annotations(JSON对象列表):此列表包含工作人员为此提交的每个注释的单个JSON对象dataObject。单个JSON对象包含一个唯一对象workerId,可用于识别提交该注释的工作人员。annotationData 键包含下列值之一:

    • content(字符串):包含注释数据。

    • s3Uri(字符串):URI包含标识注解数据位置的 S3。

下表包含了您可以在不同类型注释的负载中找到的内容示例。

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

注释后 Lambda 函数可能包含类似下面的逻辑,以循环访问请求中包含的所有注释。有关完整示例,请参阅 aws-sagemaker-ground-truth- recipe GitHub 存储库中的 annotation_consolidation_lambda.py。在此 GitHub示例中,您必须添加自己的注释合并逻辑。

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))
提示

对数据运行合并算法时,可以使用 AWS 数据库服务来存储结果,也可以将处理后的结果传回 Ground Truth。您返回给 Ground Truth 的数据会以合并注释清单的形式存储在 S3 存储桶中,该存储桶是在标注作业配置过程中指定用于输出的。

作为返回对象,Ground Truth 需要如下格式的响应:

例 预期的返回数据
[ { "datasetObjectId": <string>, "consolidatedAnnotation": { "content": { "<labelattributename>": { # ... label content } } } }, { "datasetObjectId": <string>, "consolidatedAnnotation": { "content": { "<labelattributename>": { # ... label content } } } } . . . ]

此时,除了 datasetObjectId 之外,您发送到 S3 存储桶的所有数据都在 content 对象中。

content 中返回注释时,会在作业的输出清单中生成一个条目,如下所示:

例 输出清单中的标签格式
{ "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 } }

由于自定义模板及其所收集数据的潜在复杂性,Ground Truth 不会对数据进行进一步处理。