注释前和注释后 Lambda 函数要求 - Amazon SageMaker
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

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

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

注释前 Lambda

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

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

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 操作(如 DescribeLabelingJob)时,此 ARN 可用于引用标注作业。

  • dataObject(JSON 对象):该键包含单一 JSON 行,可以来自您的输入清单文件,也可以来自 Amazon SNS。清单中的 JSON 行对象的大小最多可达 100 千字节,并且包含各种数据。对于非常基本的图像注释作业,dataObject JSON 可能只包含一个 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 函数从初始请求访问 dataObject 中的 JSON 对象,并在 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 函数的示例,请参阅 aws-sagemaker-ground-truth-recipe 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 操作(如 DescribeLabelingJob)时,此 ARN 可用于引用标注作业。

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

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

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

  • payload(JSON 对象):包含 s3Uri 键的 JSON,该键标识该数据对象的注释数据在 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://DOC-EXAMPLE-BUCKET/annotations.json" } }
注意

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

下面的代码块包含负载模式。这是由注释后 Lambda 请求 payload JSON 对象中的 s3Uri 参数指示的文件。例如,如果前面的代码块是注释后 Lambda 请求,则下面的注释文件位于 s3://DOC-EXAMPLE-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 键。否则,数据对象的位置(例如,链接或 S3 URI)用 s3Uri 标识。

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

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

    • s3Uri(字符串):包含一个 S3 URI,用于标识注释数据的位置。

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

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://DOC-EXAMPLE-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://DOC-EXAMPLE-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))
提示

对数据运行合并算法时,可以使用 Amazon 数据库服务来存储结果,也可以将处理后的结果传回 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 不会对数据进行进一步处理。