

As traduções são geradas por tradução automática. Em caso de conflito entre o conteúdo da tradução e da versão original em inglês, a versão em inglês prevalecerá.

# Uso de funções do Lambda de pré-anotação e pós-anotação
<a name="sms-custom-templates-step3-lambda-requirements"></a>

Use estes tópicos para aprender sobre a sintaxe das solicitações enviadas para as funções do Lambda de pré-anotação e pós-anotação, e a sintaxe de resposta que o Ground Truth exige para executar um fluxo de trabalho de rotulagem personalizado.

**Topics**
+ [Lambda de pré-anotação](#sms-custom-templates-step3-prelambda)
+ [Lambda de pós-anotação](#sms-custom-templates-step3-postlambda)

## Lambda de pré-anotação
<a name="sms-custom-templates-step3-prelambda"></a>

Antes de uma tarefa de rotulagem ser enviada ao operador, uma função do Lambda de pré-anotação pode ser invocada.

O Ground Truth envia à sua função do Lambda uma solicitação em formato JSON para fornecer detalhes sobre o trabalho de rotulagem e o objeto de dados.

Veja a seguir 2 exemplos de solicitações em formato 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>
    }
}
```

------

 A lista a seguir contém os esquemas de solicitação de pré-anotação. Cada parâmetro é descrito abaixo.
+ `version` (string): esse é um número da versão usado internamente pela Ground Truth.
+ `labelingJobArn` (string): esse é o Nome de recurso da Amazon, ou ARN, do seu trabalho de rotulagem. Esse ARN pode ser usado para referenciar o trabalho de rotulagem ao usar operações de API Ground Truth, como `DescribeLabelingJob`.
+ O `dataObject` (objeto JSON): a chave contém uma única linha JSON, do seu arquivo manifesto de entrada ou enviada do Amazon SNS. Os objetos de linha JSON no seu manifesto podem ter até 100 kilobytes de tamanho e conter uma variedade de dados. Para um trabalho de anotação de imagem muito básico, o `dataObject` JSON pode conter apenas uma chave `source-ref`, identificando a imagem a ser anotada. Se o objeto de dados (por exemplo, uma linha de texto) for incluído diretamente no arquivo manifesto de entrada, o objeto de dados será identificado com `source`. Se você criar uma tarefa de verificação ou ajuste, essa linha poderá conter dados de etiqueta e metadados da trabalho de rotulagem anterior.

Os exemplos de guias a seguir mostram exemplos de uma solicitação de pré-anotação. Cada parâmetro nesses exemplos de solicitações é explicado abaixo da tabela com guias.

------
#### [ 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"
    }
}
```

------

Em troca, o Ground Truth exige uma resposta formatada da seguinte forma:

**Example de dados de retorno esperados**  

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

No exemplo anterior, o `<json object>` precisa conter *todos* os dados de que seu modelo de tarefas de operador personalizado precisará. Se você estiver realizando uma tarefa de caixa delimitadora em que as instruções permanecem as mesmas o tempo todo, pode ser apenas o recurso HTTP(S) ou Amazon S3 para o arquivo de imagem. \$1´Se é uma tarefa de análise de sentimento, e objetos diferentes podem ter opções diferentes, seria a referência do objeto como uma string e as opções como uma matriz de strings.

**Implicações de `isHumanAnnotationRequired`**  
Este valor é opcional, pois será o padrão para `true`. O caso de uso principal para a definição explícita é quando você deseja excluir esse objeto de dados de ser rotulado por operadores humanos. 

Se você tiver uma mistura de objetos em seu manifesto, com alguns exigindo anotação por humano e alguns não precisando, você pode incluir um valor `isHumanAnnotationRequired` em cada objeto de dados. Você pode adicionar lógica à sua pré-anotação Lambda para determinar dinamicamente se um objeto requer anotação e definir esse valor booleano de acordo.

### Exemplos de funções do Lambda de pré-anotação
<a name="sms-custom-templates-step3-prelambda-example"></a>

A seguinte função do Lambda básica de pré-anotação acessa o objeto JSON em `dataObject` a partir da solicitação inicial e o retorna no parâmetro `taskInput`:

```
import json

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

Supondo que o arquivo manifesto de entrada `"source-ref"` seja usado para identificar objetos de dados, o modelo de tarefas de operador usado no mesmo trabalho de rotulagem dessa pré-anotação Lambda deve incluir um elemento Liquid como o seguinte para ser ingerido `dataObject`:

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

Se o arquivo manifesto de entrada for usado `source` para identificar o objeto de dados, o modelo de tarefa de trabalho poderá ser ingerido `dataObject` com o seguinte:

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

O exemplo de pré-anotação do Lambda a seguir inclui lógica para identificar a chave usada no `dataObject` e apontar para esse objeto de dados usando `taskObject` na instrução de retorno do 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 de pós-anotação
<a name="sms-custom-templates-step3-postlambda"></a>

Quando todos os operadores tiverem anotado o objeto de dados ou quando o [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) for atingido, o que ocorrer primeiro, o Ground Truth enviará essas anotações para seu Lambda de pós-anotação. Esse Lambda é geralmente usado para [Consolidação de anotações](sms-annotation-consolidation.md).

**nota**  
[Para ver um exemplo de uma função Lambda pós-consolidação, consulte [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) no repositório -recipe. aws-sagemaker-ground-truth](https://github.com/aws-samples/aws-sagemaker-ground-truth-recipe) GitHub 

O bloco de código a seguir contém o esquema de solicitação pós-anotação. Cada parâmetro é descrito na seguinte lista com marcadores:

```
{
    "version": "2018-10-16",
    "labelingJobArn": <string>,
    "labelCategories": [<string>],
    "labelAttributeName": <string>,
    "roleArn" : <string>,
    "payload": {
        "s3Uri": <string>
    }
 }
```
+ `version` (string): esse é um número da versão usado internamente pela Ground Truth.
+ `labelingJobArn` (string): Esse é o nome de recurso da Amazon, ou ARN, do seu trabalho de rotulagem. Esse ARN pode ser usado para referenciar o trabalho de rotulagem ao usar operações de API Ground Truth, como `DescribeLabelingJob`.
+ `labelCategories` (lista de sequências de caracteres): inclui as categorias de rótulos e outros atributos que você especificou no console ou que você incluiu no arquivo de configuração da categoria de rótulo.
+ `labelAttributeName` (string): o nome do seu trabalho de rotulagem ou o nome de atributo do rótulo que você especifica ao criar o trabalho de rotulagem.
+ `roleArn` (string): o nome do recurso da Amazon (ARN) da função de execução do IAM que você especifica ao criar a tarefa de rotulagem. 
+ `payload` (objeto JSON): um JSON que inclui uma chave `s3Uri`, que identifica a localização dos dados de anotação desse objeto de dados no Amazon S3. O segundo bloco de código abaixo mostra um exemplo desse arquivo de anotação.

O bloco de código a seguir contém um exemplo de uma solicitação pós-anotação. Cada parâmetro nesses exemplos de solicitações é explicado abaixo da tabela com guias.

**Example de uma solicitação Lambda de pós-anotação**  

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

**nota**  
Se nenhum operador trabalhar no objeto de dados e o `TaskAvailabilityLifetimeInSeconds` for atingido, o objeto de dados será marcado como falha e não será incluído como parte da invocação do Lambda de pós-anotação.

O bloco de código a seguir contém o esquema de carga útil. Esse é o arquivo indicado pelo `s3Uri` parâmetro no objeto JSON de solicitação `payload` Lambda de pós-anotação. Por exemplo, se o bloco de código anterior for a solicitação Lambda pós-anotação, o arquivo de anotação a seguir está localizado em `s3://amzn-s3-demo-bucket/annotations.json`.

Cada parâmetro é descrito na seguinte lista com marcadores:

**Example de um arquivo de anotação**  

```
[
    {
        "datasetObjectId": <string>,
        "dataObject": {
            "s3Uri": <string>,
            "content": <string>
        },
        "annotations": [{
            "workerId": <string>,
            "annotationData": {
                "content": <string>,
                "s3Uri": <string>
            }
       }]
    }
]
```
+ `datasetObjectId` (string): identifica uma ID exclusiva que a Ground Truth atribui a cada objeto de dados que você envia para o trabalho de rotulagem.
+ `dataObject` (objeto JSON): o objeto de dados que foi rotulado. Se o objeto de dados estiver incluído no arquivo manifesto de entrada e identificado usando a `source` chave (por exemplo, uma string), `dataObject` inclua uma `content` chave que identifica o objeto de dados. Caso contrário, a localização do objeto de dados (por exemplo, um link ou URI do S3) será identificada com `s3Uri`.
+ `annotations` (lista de objetos JSON): essa lista contém um único objeto JSON para cada anotação enviada pelos operadores para esse `dataObject`. Um único objeto JSON contém um único `workerId` que pode ser usado para identificar o operador que enviou essa anotação. A chave `annotationData` contém um dos seguintes valores:
  + `content` (string): contém os dados de anotação. 
  + `s3Uri` (string): contém um URI do S3 que identifica a localização dos dados de anotação.

A tabela a seguir contém exemplos do conteúdo que você pode encontrar no payload para diferentes tipos de anotação.

------
#### [ 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}}}"
          }
        }
      ]
    }
 ]
```

------

Sua função do Lambda de pós-anotação pode conter uma lógica semelhante à seguinte para percorrer e acessar todas as anotações contidas na solicitação: Para ver um exemplo completo, consulte [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) no GitHub repositório [aws-sagemaker-ground-truth-recipe](https://github.com/aws-samples/aws-sagemaker-ground-truth-recipe). Neste GitHub exemplo, você deve adicionar sua própria lógica de consolidação de anotações. 

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

**dica**  
Ao executar algoritmos de consolidação nos dados, você pode usar um serviço de banco de dados do AWS para armazenar os resultados ou pode passar os resultados processados de volta para a Ground Truth. Os dados que você retorna ao Ground Truth são armazenados em manifestos de anotação consolidados no bucket do S3 especificado para saída durante a configuração do trabalho de rotulagem.

Em troca, o Ground Truth exige uma resposta formatada da seguinte forma:

**Example de dados de retorno esperados**  

```
[
   {        
        "datasetObjectId": <string>,
        "consolidatedAnnotation": {
            "content": {
                "<labelattributename>": {
                    # ... label content
                }
            }
        }
    },
   {        
        "datasetObjectId": <string>,
        "consolidatedAnnotation": {
            "content": {
                "<labelattributename>": {
                    # ... label content
                }
            }
        }
    }
    .
    .
    .
]
```
Neste ponto, todos os dados que você está enviando para seu bucket S3, exceto o `datasetObjectId`, estão no objeto `content`.

Quando você retorna anotações em `content`, isso resulta em uma entrada no manifesto de saída do seu trabalho, como a seguinte:

**Example do formato do rótulo no manifesto de saída**  

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

Por causa da natureza potencialmente complexa de um modelo personalizado e dos dados que ele coleta, o Ground Truth não oferece processamento adicional dos dados ou percepções sobre ele.