

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

# 前注釈と後注釈の Lambda 関数をテストする
<a name="sms-custom-templates-step3-lambda-requirements"></a>

このセクションでは、前注釈と後注釈の Lambda 関数に送信されるリクエストの構文と、Ground Truth でカスタムラベル付けワークフローを実行するために必要な応答構文について学習します。

**Topics**
+ [前注釈 Lambda](#sms-custom-templates-step3-prelambda)
+ [後注釈 Lambda](#sms-custom-templates-step3-postlambda)

## 前注釈 Lambda
<a name="sms-custom-templates-step3-prelambda"></a>

ラベル付けタスクがワーカーに送信される前に、前注釈の Lambda 関数をオプションで呼び出すことができます。

Ground Truth は、Lambda 関数に JSON 形式のリクエストを送信し、ラベル付けジョブとデータオブジェクトに関する詳細を提供します。

JSON 形式のリクエストの例を次に 2 つ示します。

------
#### [ 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 は、`DescribeLabelingJob` のようなGround Truth ス API オペレーションを使用するときにラベル付けジョブを参照するために使用できます。
+ `dataObject` (JSON オブジェクト): キーには、入力マニフェストファイルから、または Amazon SNS から送信された 1 つの JSON 行が含まれます。マニフェストの JSON 行オブジェクトのサイズは最大 100 キロバイトで、さまざまなデータを含むことができます。非常に基本的な画像注釈ジョブでは、`dataObject` JSONには注釈を付けるイメージを指定する `source-ref`キーのみが含まれる場合があります。データオブジェクト (テキスト行など) が入力マニフェストファイルに直接含まれている場合、データオブジェクトは `source` で識別されます。検証ジョブまたは調整ジョブを作成する場合、この行には、前のラベル付けジョブのラベルデータとメタデータが含まれる場合があります。

次の各タブに、前注釈リクエストの例を示します。これらのリクエストの例の各パラメータの説明は、タブ付きテーブルの下にあります。

------
#### [ Data object identified with "source-ref" ]

```
{
    "version": "2018-10-16",
    "labelingJobArn": "arn:aws:sagemaker:us-west-2:111122223333: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>:111122223333:labeling-job/<labeling_job_name>"
    "dataObject" : {
        "source": "Sue purchased 10 shares of the stock on April 10th, 2020"
    }
}
```

------

代わりに、Ground Truth には、次のような形式の応答が必要です。

**Example 想定される戻りデータの**  

```
{
    "taskInput": <json object>,
    "isHumanAnnotationRequired": <boolean> # Optional
}
```

前の例では、`<json object>` には、カスタムワーカーテンプレートに必要な*すべての*データが含まれている必要があります。手順が常に同じである境界ボックスタスクを実行している場合は、単にイメージファイルの HTTP(S) または Amazon S3 リソースであることがあります。これが感情分析タスクであり、さまざまなオブジェクトに各種の選択肢がある場合には、文字列としてのオブジェクト参照、文字列の配列としての選択肢になります。

**`isHumanAnnotationRequired` の意義**  
デフォルト値が `true` に設定されるため、この値は任意です。明示的な設定の主なユースケースは、このデータオブジェクトを人間のワーカーによるラベル付けから除外する場合です。

マニフェストに複数のオブジェクトがあり、それらの中に人間の注釈を必要とするものと必要としないものがある場合は、`isHumanAnnotationRequired` 値を各データオブジェクトに含めることができます。注釈前 Lambda にロジックを追加して、オブジェクトに注釈が必要かどうかを動的に判断し、それに応じてこのブール値を設定できます。

### 前注釈 Lambda 関数の例
<a name="sms-custom-templates-step3-prelambda-example"></a>

次の基本的な前注釈 Lambda 関数は、最初のリクエストから `dataObject` の JSON オブジェクトにアクセスし、`taskInput` パラメータで返します。

```
import json

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

入力マニフェストファイルが `"source-ref"` を使用してデータオブジェクトを識別すると仮定して、この注釈前 Lambda と同じラベル付けジョブで使用されるワーカータスクテンプレートには、`dataObject` を取り込むために以下のような Liquid 要素を含める必要があります。

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

入力マニフェストファイルが `source` を使用してデータオブジェクトを識別する場合は、ワーカータスクテンプレートは、以下を使用して `dataObject` を取り込むことができます。

```
{{ task.input.source }}
```

次の注釈前 Lambda の例には、`dataObject` で使用されたキーを識別するロジックが含まれており、Lambda の return ステートメントで `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
<a name="sms-custom-templates-step3-postlambda"></a>

すべてのワーカーがデータオブジェクトに注釈を付けたとき、または [https://docs.aws.amazon.com/sagemaker/latest/APIReference/API_HumanLoopConfig.html#SageMaker-Type-HumanLoopConfig-TaskAvailabilityLifetimeInSeconds](https://docs.aws.amazon.com/sagemaker/latest/APIReference/API_HumanLoopConfig.html#SageMaker-Type-HumanLoopConfig-TaskAvailabilityLifetimeInSeconds) に達したときのいずれか早い方で、Ground Truth はそれらの注釈を注釈後 Lambda に送信します。この Lambda は一般に、[注釈統合](sms-annotation-consolidation.md) に使用されます。

**注記**  
統合後の Lambda 関数の例については、[aws-sagemaker-ground-truth-recipe](https://github.com/aws-samples/aws-sagemaker-ground-truth-recipe) GitHub リポジトリの [annotation\$1consolidation\$1lambda.py](https://github.com/aws-samples/aws-sagemaker-ground-truth-recipe/blob/master/aws_sagemaker_ground_truth_sample_lambda/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) です。この ARN は、`DescribeLabelingJob` のようなGround Truth ス API オペレーションを使用するときにラベル付けジョブを参照するために使用できます。
+ `labelCategories` (文字列のリスト): コンソールで指定した、またはラベルカテゴリ設定ファイルに含まれるラベルカテゴリとその他の属性が含まれます。
+ `labelAttributeName` (文字列): ラベル付けジョブの名前、またはラベル付けジョブの作成時に指定したラベル属性名のいずれかです。
+ `roleArn` (文字列): ラベル付けジョブの作成時に指定する IAM 実行ロールの Amazon リソースネーム (ARN) です。
+ `payload` (JSON オブジェクト): `s3Uri` を含む JSON キー。Amazon S3 内のそのデータオブジェクトの注釈データの場所を特定します。次の 2 番目のコードブロックは、この注釈ファイルの例です。

次のコードブロックは、注釈後リクエストの例を示しています。このサンプルリクエストの各パラメータの説明は、コードブロックの下にあります。

**Example 注釈後 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` になります。

各パラメータの説明は、下の箇条書きにあります。

**Example 注釈ファイルの**  

```
[
    {
        "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 オブジェクトのリスト): このリストには、その `dataObject` にワーカーから送信された注釈ごとに 1 つの JSON オブジェクトが含まれます。注釈を送信したワーカーを特定するために使用できる一意の `workerId` を含む単一の JSON オブジェクト。`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://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](https://github.com/aws-samples/aws-sagemaker-ground-truth-recipe)GitHub リポジトリの [annotation\$1consolidation\$1lambda.py](https://github.com/aws-samples/aws-sagemaker-ground-truth-recipe/blob/master/aws_sagemaker_ground_truth_sample_lambda/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 には、次のような形式の応答が必要です。

**Example 想定される戻りデータの**  

```
[
   {        
        "datasetObjectId": <string>,
        "consolidatedAnnotation": {
            "content": {
                "<labelattributename>": {
                    # ... label content
                }
            }
        }
    },
   {        
        "datasetObjectId": <string>,
        "consolidatedAnnotation": {
            "content": {
                "<labelattributename>": {
                    # ... label content
                }
            }
        }
    }
    .
    .
    .
]
```
この時点で、S3 バケットに送信している、`datasetObjectId` 以外のすべてのデータが `content` オブジェクトに配置されます。

`content` で注釈を返すとき、これにより、ジョブの出力マニフェストに次のようなエントリが生成されます。

**Example 出力マニフェストでのラベル形式の**  

```
{  "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 ではデータの詳細な処理は行いません。