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

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

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

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

注释前 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。此 ARN 可用于在使用 Ground Truth API 操作(如DescribeLabelingJob

  • 这些区域有:dataObject(JSON 对象):密钥包含一个 JSON 行,可以从您的输入清单文件或从 Amazon 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 函数访问dataObject,并将其返回到taskInput参数。

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

假设输入清单文件使用"source-ref"来标识数据对象,则与此预注释 Lambda 在同一标签作业中使用的工作任务模板必须包含类似以下内容的 Fulid 元素才能引入dataObject

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

如果输入清单文件使用source来标识数据对象,则工作任务模板可以引入dataObject改用如下权限:

{{ task.input.source }}

以下预注释 Lambda 示例包含用于标识dataObject,并指向该数据对象使用taskObject在 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

注释后 Lambda

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

提示

要查看合并后 Lambda 函数的示例,请参阅annotation_consolidation_lambda.py中的AWS 萨格制造商-地面-真理配方GitHub 存储库。

以下代码块包含注释后请求模式。每个参数会在后文中予以说明。

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

  • labelingJobArn(字符串):贴标任务的亚马逊资源名称或 ARN。此 ARN 可用于在使用 Ground Truth API 操作(如DescribeLabelingJob

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

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

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

  • payload(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://DOC-EXAMPLE-BUCKET/annotations.json" } }
注意

如果没有工作人员在数据对象上工作,并且TaskAvailabilityLifetimeInSeconds,则数据对象将被标记为失败,并且不包含在注释后 Lambda 调用中。

以下代码块包含有效负载模式。这是由s3Uri注释后 Lambda 请求中的参数payloadJSON 对象。例如,如果前面的代码块是注释后 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 函数可能包含类似于以下内容的逻辑,用于循环和访问请求中包含的所有注释。有关完整示例,请参阅annotation_consolidation_lambda.py中的AWS 萨格制造商-地面-真理配方GitHub 存储库。在此 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 } } } } . . . ]

此时,您发送到 S3 存储桶的所有数据,而不是datasetObjectId,位于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 理不提供对数据的进一步处理。