{"id":318,"date":"2020-09-30T21:37:42","date_gmt":"2020-09-30T21:37:42","guid":{"rendered":"https:\/\/machine-learning.webcloning.com\/2020\/09\/30\/using-amazon-rekognition-custom-labels-and-amazon-a2i-for-detecting-pizza-slices-and-augmenting-predictions\/"},"modified":"2020-09-30T21:37:42","modified_gmt":"2020-09-30T21:37:42","slug":"using-amazon-rekognition-custom-labels-and-amazon-a2i-for-detecting-pizza-slices-and-augmenting-predictions","status":"publish","type":"post","link":"https:\/\/salarydistribution.com\/machine-learning\/2020\/09\/30\/using-amazon-rekognition-custom-labels-and-amazon-a2i-for-detecting-pizza-slices-and-augmenting-predictions\/","title":{"rendered":"Using Amazon Rekognition Custom Labels and\u00a0Amazon A2I for detecting pizza slices and augmenting predictions"},"content":{"rendered":"<div id=\"\">\n<p>Customers need machine learning (ML) models to detect objects that are interesting for their business. In most cases doing so is hard as these models needs thousands of labelled images and deep learning expertise. \u00a0Generating this data can take months to gather, and can require large teams of labelers to prepare it for use. In addition, setting up a workflow for auditing or reviewing model predictions to validate adherence to your requirements can further add to the overall complexity.<\/p>\n<p>With <a href=\"https:\/\/aws.amazon.com\/rekognition\/custom-labels-features\/\" target=\"_blank\" rel=\"noopener noreferrer\">Amazon Rekognition Custom Labels<\/a>, which is built on the existing capabilities of <a href=\"https:\/\/aws.amazon.com\/rekognition\/\" target=\"_blank\" rel=\"noopener noreferrer\">Amazon Rekognition<\/a>, you can identify the objects and scenes in images that are specific to your business needs. For example, you can find your logo in social media posts, identify your products on store shelves, classify machine parts in an assembly line, distinguish healthy and infected plants, or detect animated characters in videos.<\/p>\n<p>But what if the custom label model you trained can\u2019t recognize images with a high level of confidence, or you need your team of experts to validate the results from your model during the testing phase or review the results in production? You can easily send predictions from Amazon Rekognition Custom Labels to <a href=\"https:\/\/aws.amazon.com\/augmented-ai\/\" target=\"_blank\" rel=\"noopener noreferrer\">Amazon Augmented AI<\/a> (Amazon A2I). Amazon A2I makes it easy to integrate a human review into your ML workflow. This allows you to automatically have humans step into your ML pipeline to review results below a confidence threshold, set up review and auditing workflows, and augment the prediction results to improve model accuracy.<\/p>\n<p>In this post, we show you to how to build a custom object detection model trained to detect pepperoni slices in a pizza using Amazon Rekognition Custom Labels with a dataset labeled using <a href=\"https:\/\/aws.amazon.com\/sagemaker\/groundtruth\/\" target=\"_blank\" rel=\"noopener noreferrer\">Amazon SageMaker Ground Truth<\/a>. We then show how to create your own private workforce and set up an Amazon A2I workflow definition to conditionally trigger human loops for review and augmenting tasks. You can use the annotations created by Amazon A2I for model retraining.<\/p>\n<p>We walk you through the following steps using the accompanying <a href=\"https:\/\/github.com\/aws-samples\/amazon-a2i-sample-jupyter-notebooks\/blob\/master\/Amazon-A2I-Rekognition-Custom-Label-notebook.ipynb\" target=\"_blank\" rel=\"noopener noreferrer\">Amazon SageMaker Jupyter Notebook<\/a>:<\/p>\n<ol>\n<li>Complete prerequisites.<\/li>\n<li>Create an Amazon Rekognition custom model.<\/li>\n<li>Set up an Amazon A2I workflow and send predictions to an Amazon A2I human loop.<\/li>\n<li>Evaluate results and retrain the model.<\/li>\n<\/ol>\n<h2>Prerequisites<\/h2>\n<p>Before getting started, set up your Amazon SageMaker notebook. Follow the steps in the accompanying <a href=\"https:\/\/github.com\/aws-samples\/amazon-a2i-sample-jupyter-notebooks\/blob\/master\/Amazon-A2I-Rekognition-Custom-Label-notebook.ipynb\" target=\"_blank\" rel=\"noopener noreferrer\">Amazon SageMaker Jupyter Notebook<\/a> to create your human workforce and download the datasets.<\/p>\n<ol>\n<li>\n<a href=\"https:\/\/docs.aws.amazon.com\/sagemaker\/latest\/dg\/howitworks-create-ws.html\" target=\"_blank\" rel=\"noopener noreferrer\">Create a notebook instance<\/a> in <a href=\"https:\/\/aws.amazon.com\/sagemaker\/\" target=\"_blank\" rel=\"noopener noreferrer\">Amazon SageMaker<\/a>.<\/li>\n<\/ol>\n<p>Make sure your Amazon SageMaker notebook has the necessary <a href=\"http:\/\/aws.amazon.com\/iam\" target=\"_blank\" rel=\"noopener noreferrer\">AWS Identity and Access Management<\/a> (IAM) roles and permissions mentioned in the prerequisite section of the <a href=\"https:\/\/github.com\/aws-samples\/amazon-a2i-sample-jupyter-notebooks\/blob\/master\/Amazon-A2I-Rekognition-Custom-Label-notebook.ipynb\" target=\"_blank\" rel=\"noopener noreferrer\">notebook<\/a>.<\/p>\n<ol start=\"2\">\n<li>When the notebook is active, choose <strong>Open Jupyter<\/strong>.<\/li>\n<li>On the Jupyter dashboard, choose <strong>New<\/strong>, and choose <strong>Terminal<\/strong>.<\/li>\n<li>In the terminal, enter the following code:<\/li>\n<\/ol>\n<div class=\"hide-language\">\n<pre class=\"unlimited-height-code\"><code class=\"lang-bash\">cd SageMaker\r\ngit clone https:\/\/github.com\/aws-samples\/amazon-a2i-sample-jupyter-notebooks\r\n<\/code><\/pre>\n<\/div>\n<ol start=\"5\">\n<li>Open the notebook by choosing <strong>Amazon-A2I-Rekognition-Custom-Label.ipynb<\/strong> in the root folder.<\/li>\n<\/ol>\n<p>For this post, you create a private work team and add one user (you) to it.<\/p>\n<ol start=\"6\">\n<li>Create your human workforce by following the appropriate section of the notebook.<\/li>\n<\/ol>\n<p>Alternatively, you can create your private workforce using <a href=\"http:\/\/aws.amazon.com\/cognito\" target=\"_blank\" rel=\"noopener noreferrer\">Amazon Cognito<\/a>. For instructions, see <a href=\"https:\/\/docs.aws.amazon.com\/sagemaker\/latest\/dg\/sms-workforce-create-private-console.html#create-workforce-sm-console\" target=\"_blank\" rel=\"noopener noreferrer\">Create an Amazon Cognito Workforce Using the Labeling Workforces Page<\/a>.<\/p>\n<ol start=\"7\">\n<li>After you create the private workforce, <a href=\"https:\/\/docs.aws.amazon.com\/sagemaker\/latest\/dg\/sms-workforce-management-private-api.html\" target=\"_blank\" rel=\"noopener noreferrer\">find the workforce ARN<\/a> and enter the ARN in step 4 of the notebook.<\/li>\n<\/ol>\n<p><strong>\u00a0<\/strong>The dataset is composed of 12 images for training that contain pepperoni pizza in the <code>data\/images<\/code> folder and 3 images for testing in the <code>data\/testimages<\/code> folder. We sourced our images from <a href=\"http:\/\/pexels.com\/\" target=\"_blank\" rel=\"noopener noreferrer\">pexels.com<\/a>. We labeled this dataset for this post using Ground Truth <a href=\"https:\/\/docs.aws.amazon.com\/sagemaker\/latest\/dg\/sms-custom-templates.html\" target=\"_blank\" rel=\"noopener noreferrer\">custom labeling workflows<\/a>. A Ground Truth labeled manifest template is available in <a href=\"https:\/\/github.com\/aws-samples\/amazon-a2i-sample-jupyter-notebooks\/tree\/master\/data\/manifest\" target=\"_blank\" rel=\"noopener noreferrer\">data\/manifest<\/a>.<\/p>\n<ol start=\"8\">\n<li>Download the dataset.<\/li>\n<li>Run the notebook steps <strong>Download the Amazon SageMaker GroundTruth object detection manifest to Amazon S3<\/strong> to process and upload the manifest in your <a href=\"http:\/\/aws.amazon.com\/s3\" target=\"_blank\" rel=\"noopener noreferrer\">Amazon Simple Storage Service<\/a> (Amazon S3) bucket.<\/li>\n<\/ol>\n<h2>Creating an Amazon Rekognition custom model<\/h2>\n<p>To create our custom model, we follow these steps:<\/p>\n<ol>\n<li>Create a project in Amazon Rekognition Custom Labels.<\/li>\n<li>Create a dataset with images containing one or more pizzas and label them by applying bounding boxes.<\/li>\n<\/ol>\n<p>Because we already have a dataset labeled using Ground Truth, we just point to that labeled dataset in this step. Alternatively, you can label the images using the user interface provided by Amazon Rekognition Custom Labels.<\/p>\n<ol start=\"3\">\n<li>Train the model.<\/li>\n<li>Evaluate the model\u2019s performance.<\/li>\n<li>Test the deployed model using a sample image.<\/li>\n<\/ol>\n<h3>Creating a project<\/h3>\n<p>In this step, we create a project to detect peperoni pizza slices. For instructions on creating a project, see <a href=\"https:\/\/docs.aws.amazon.com\/rekognition\/latest\/customlabels-dg\/cp-create-project.html\" target=\"_blank\" rel=\"noopener noreferrer\">Creating an Amazon Rekognition Custom Labels Project<\/a>.<\/p>\n<ol>\n<li>On the Amazon Rekognition console, choose <strong>Custom Labels<\/strong>.<\/li>\n<li>Choose <strong>Get started<\/strong>.<\/li>\n<li>For <strong>Project name<\/strong>, enter <code>a2i-rekog-pepperoni-pizza<\/code>.<\/li>\n<li>Choose <strong>Create project<\/strong>.<\/li>\n<\/ol>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-full wp-image-16517\" src=\"https:\/\/d2908q01vomqb2.cloudfront.net\/f1f836cb4ea6efb2a0b1b99f41ad8b103eff4b59\/2020\/09\/30\/1-Create-Project.jpg\" alt=\"\" width=\"900\" height=\"408\"><\/p>\n<h3>Creating a dataset<\/h3>\n<p>To create your dataset, complete the following steps:<\/p>\n<ol>\n<li>On the Amazon Rekognition Custom Labels console, choose <strong>Datasets<\/strong>.<\/li>\n<li>Choose <strong>Create dataset<\/strong>.<\/li>\n<li>For <strong>Dataset name<\/strong>, enter <code>rekog-a2i-pizza-dataset<\/code>.<\/li>\n<li>Select <strong>Import images labeled by Amazon SageMaker Ground Truth<\/strong>.<\/li>\n<li>For <strong>.manifest file location<\/strong>, enter the S3 bucket location of your .manifest file.<\/li>\n<\/ol>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-full wp-image-16518\" src=\"https:\/\/d2908q01vomqb2.cloudfront.net\/f1f836cb4ea6efb2a0b1b99f41ad8b103eff4b59\/2020\/09\/30\/2-Create-dataset.jpg\" alt=\"\" width=\"900\" height=\"501\"><\/p>\n<ol start=\"6\">\n<li>Choose\u00a0<strong>Submit<\/strong>.<\/li>\n<\/ol>\n<p>You should get a prompt to provide the S3 bucket policy when you provide the S3 path. For more information about these steps, see <a href=\"https:\/\/docs.aws.amazon.com\/rekognition\/latest\/customlabels-dg\/cd-ground-truth.html\" target=\"_blank\" rel=\"noopener noreferrer\">SageMaker Ground Truth<\/a>.<\/p>\n<p>After you create the dataset, you should see the images with the bounding boxes and labels, as in the following screenshot.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-full wp-image-16519\" src=\"https:\/\/d2908q01vomqb2.cloudfront.net\/f1f836cb4ea6efb2a0b1b99f41ad8b103eff4b59\/2020\/09\/30\/3-Custom-labels.jpg\" alt=\"\" width=\"900\" height=\"424\"><\/p>\n<p><strong>Make<\/strong> sure to upload the images for our dataset (that you downloaded in the <strong>Prerequisites<\/strong> section) to the console S3 bucket for Amazon Rekognition Custom Labels.<\/p>\n<h3>Training an Amazon Rekognition custom model<\/h3>\n<p>You\u2019re now ready to train your model.<\/p>\n<ol>\n<li>On the Amazon Rekognition console, choose <strong>Train model<\/strong>.<\/li>\n<li>For <strong>Choose project<\/strong>, choose your newly created project.<\/li>\n<li>For <strong>Choose training dataset<\/strong>, choose your newly created dataset.<\/li>\n<li>Select <strong>Split training dataset<\/strong>.<\/li>\n<li>Choose <strong>Train<\/strong>.<\/li>\n<\/ol>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-full wp-image-16520\" src=\"https:\/\/d2908q01vomqb2.cloudfront.net\/f1f836cb4ea6efb2a0b1b99f41ad8b103eff4b59\/2020\/09\/30\/4-Training-details.jpg\" alt=\"\" width=\"900\" height=\"558\"><\/p>\n<p>The training takes approximately 45 minutes to complete.<\/p>\n<h4>Checking training status<\/h4>\n<p>Run the following notebook cell to get information about the project you created using the <a href=\"https:\/\/docs.aws.amazon.com\/cli\/latest\/reference\/rekognition\/describe-projects.html\" target=\"_blank\" rel=\"noopener noreferrer\">describe-projects<\/a> API:<\/p>\n<div class=\"hide-language\">\n<pre class=\"unlimited-height-code\"><code class=\"lang-python\">!aws rekognition describe-projects<\/code><\/pre>\n<\/div>\n<p>Use the accompanying <a href=\"https:\/\/github.com\/aws-samples\/amazon-a2i-sample-jupyter-notebooks\/blob\/master\/Amazon-A2I-Rekognition-Custom-Label.ipynb\" target=\"_blank\" rel=\"noopener noreferrer\">Amazon SageMaker Jupyter notebook<\/a> to follow the steps in this post.<\/p>\n<p>To get the project ARN using the <a href=\"https:\/\/docs.aws.amazon.com\/cli\/latest\/reference\/rekognition\/describe-project-versions.html\" target=\"_blank\" rel=\"noopener noreferrer\">describe-project versions<\/a> API, run the following cell:<\/p>\n<div class=\"hide-language\">\n<pre class=\"unlimited-height-code\"><code class=\"lang-python\">#Replace the project-arn below with the project-arn of your project from the describe-projects output above\r\n!aws rekognition describe-project-versions \u2014project-arn \"<span>&lt;project-arn&gt;<\/span>\"\r\n<\/code><\/pre>\n<\/div>\n<p>Enter the ARN in <em><span>&lt;project-version-arn-of-your-model&gt;<\/span><\/em> in the following code and run this cell to start running of the version of a model using the <a href=\"https:\/\/docs.aws.amazon.com\/cli\/latest\/reference\/rekognition\/start-project-version.html\" target=\"_blank\" rel=\"noopener noreferrer\">start-project-version<\/a> API:<\/p>\n<div class=\"hide-language\">\n<pre class=\"unlimited-height-code\"><code class=\"lang-python\"># Copy\/paste the ProjectVersionArn for your model from the describe-project-versions cell output above to the --project-version-arn parameter here\r\n!aws rekognition start-project-version \r\n--project-version-arn <span>&lt;project-version-arn-of-your-model&gt;<\/span> \r\n--min-inference-units 1 \r\n--region us-east-1\r\n<\/code><\/pre>\n<\/div>\n<h3>Evaluating performance<\/h3>\n<p>When training is complete, you can evaluate the performance of the model. To help you, Amazon Rekognition Custom Labels provides summary metrics and evaluation metrics for each label. For information about the available metrics, see <a href=\"https:\/\/docs.aws.amazon.com\/rekognition\/latest\/customlabels-dg\/tr-metrics-use.html\" target=\"_blank\" rel=\"noopener noreferrer\">Metrics for Evaluating Your Model<\/a>. To improve your model using metrics, see <a href=\"https:\/\/docs.aws.amazon.com\/rekognition\/latest\/customlabels-dg\/tr-improve-model.html\" target=\"_blank\" rel=\"noopener noreferrer\">Improving an Amazon Rekognition Custom Labels Model<\/a>.<\/p>\n<p>The following screenshot shows our evaluation results and label performance.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-full wp-image-16521\" src=\"https:\/\/d2908q01vomqb2.cloudfront.net\/f1f836cb4ea6efb2a0b1b99f41ad8b103eff4b59\/2020\/09\/30\/5-a2i.jpg\" alt=\"\" width=\"900\" height=\"512\"><\/p>\n<p>Custom Labels determines the assumed threshold for each label based on maximum precision and recall achieved. Your model defaults to returning predictions above that threshold. You can reset this when you start your model. For information about adjusting your assumed threshold (such as looking at predictions either below or above your assumed threshold) and optimizing the model for your use case, see <a href=\"https:\/\/aws.amazon.com\/blogs\/machine-learning\/training-a-custom-single-class-object-detection-model-with-amazon-rekognition-custom-labels\/\" target=\"_blank\" rel=\"noopener noreferrer\">Training a custom single class object detection model with Amazon Rekognition Custom Labels<\/a>.<\/p>\n<p>For a demonstration of the Amazon Rekognition Custom Labels solution, see <a href=\"https:\/\/docs.aws.amazon.com\/rekognition\/latest\/customlabels-dg\/ex-custom-labels-demo.html\" target=\"_blank\" rel=\"noopener noreferrer\">Custom Labels Demonstration<\/a>. The demo shows you how you can analyze an image from your local computer.<\/p>\n<h3>Testing the deployed model<\/h3>\n<p>Run following notebook cell to load the test image. Use the accompanying <a href=\"https:\/\/github.com\/aws-samples\/amazon-a2i-sample-jupyter-notebooks\/blob\/master\/Amazon-A2I-Rekognition-Custom-Label-notebook.ipynb\" target=\"_blank\" rel=\"noopener noreferrer\">Amazon SageMaker Jupyter Notebook<\/a> to follow the steps in this post.<\/p>\n<div class=\"hide-language\">\n<pre class=\"unlimited-height-code\"><code class=\"lang-python\">from PIL import Image, ImageDraw, ExifTags, ImageColor, ImageFont\r\nimage=Image.open('.\/data\/images\/pexels_brett_jordan_825661__1_.jpg')\r\ndisplay(image)\r\n<\/code><\/pre>\n<\/div>\n<p>Enter the project version model ARN from previous notebook step <code>aws rekognition start-project-version<\/code> and run the following cell to analyze the response from the <a href=\"https:\/\/docs.aws.amazon.com\/cli\/latest\/reference\/rekognition\/detect-custom-labels.html\" target=\"_blank\" rel=\"noopener noreferrer\">detect_custom_labels<\/a> API:<\/p>\n<div class=\"hide-language\">\n<pre class=\"unlimited-height-code\"><code class=\"lang-python\">model_arn = '<span>&lt;project-version-arn-of-your-model&gt;<\/span>'\r\nmin_confidence=40\r\n#Call DetectCustomLabels\r\nresponse = client.detect_custom_labels(Image={'S3Object': {'Bucket': BUCKET, 'Name': PREFIX + test_photo}},\r\nMinConfidence=min_confidence,\r\nProjectVersionArn=model_arn)\r\n<\/code><\/pre>\n<\/div>\n<p>Run the next cell in the notebook to display results (see the following screenshot).<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-full wp-image-16522\" src=\"https:\/\/d2908q01vomqb2.cloudfront.net\/f1f836cb4ea6efb2a0b1b99f41ad8b103eff4b59\/2020\/09\/30\/6-pizza.jpg\" alt=\"\" width=\"900\" height=\"695\"><\/p>\n<p>The model detected the pepperoni pizza slices in our test image and drew bounding boxes. We can use Amazon A2I to send the prediction results from our model to a human loop consisting of our private workforce to review and audit the results.<\/p>\n<h2>Setting up an Amazon A2I human loop<\/h2>\n<p>In this section, you set up a human review loop for low-confidence detection in Amazon A2I. It includes the following steps:<\/p>\n<ol>\n<li>Create a human task UI.<\/li>\n<li>Create a worker task template and workflowflow definition.<\/li>\n<li>Send predictions to Amazon A2I human loops.<\/li>\n<li>Check the human loop status.<\/li>\n<\/ol>\n<p>Use the accompanying <a href=\"https:\/\/github.com\/aws-samples\/amazon-a2i-sample-jupyter-notebooks\/blob\/master\/Amazon-A2I-Rekognition-Custom-Label-notebook.ipynb\" target=\"_blank\" rel=\"noopener noreferrer\">Amazon SageMaker Jupyter notebook<\/a> to follow the steps in this post.<\/p>\n<h3>Creating a human task UI<\/h3>\n<p>Create a human task UI resource with a UI template in liquid HTML. This template is used whenever a human loop is required.<\/p>\n<p>For this post, we take an <a href=\"https:\/\/github.com\/aws-samples\/amazon-a2i-sample-task-uis\/blob\/master\/images\/bounding-box.liquid.html\" target=\"_blank\" rel=\"noopener noreferrer\">object detection UI<\/a> and fill in the object categories in the <code>labels<\/code> variable in the template. Run the following template to create the human task AI for object detection:<\/p>\n<div class=\"hide-language\">\n<pre class=\"unlimited-height-code\"><code class=\"lang-python\">def create_task_ui():\r\n    '''\r\n    Creates a Human Task UI resource.\r\n\r\n    Returns:\r\n    struct: HumanTaskUiArn\r\n    '''\r\n    response = sagemaker_client.create_human_task_ui(\r\n        HumanTaskUiName=taskUIName,\r\n        UiTemplate={'Content': template})\r\n    return response\r\n# Create task UI\r\nhumanTaskUiResponse = create_task_ui()\r\nhumanTaskUiArn = humanTaskUiResponse['HumanTaskUiArn']\r\nprint(humanTaskUiArn)\r\n<\/code><\/pre>\n<\/div>\n<p>For over 70 pre-built UIs, see the <a href=\"https:\/\/github.com\/aws-samples\/amazon-a2i-sample-task-uis\" target=\"_blank\" rel=\"noopener noreferrer\">Amazon Augmented AI Sample Task UIs<\/a> GitHub repo.<\/p>\n<h3>Creating a worker task template and workflow definition<\/h3>\n<p>Workflow definitions allow you to specify the following:<\/p>\n<ul>\n<li>The workforce that your tasks are sent to<\/li>\n<li>The instructions that your workforce receives<\/li>\n<\/ul>\n<p>This post uses the following API to create a workflow definition:<\/p>\n<div class=\"hide-language\">\n<pre class=\"unlimited-height-code\"><code class=\"lang-python\">create_workflow_definition_response = sagemaker.create_flow_definition(\r\n        FlowDefinitionName= flowDefinitionName,\r\n        RoleArn= ROLE,\r\n        HumanLoopConfig= {\r\n            \"WorkteamArn\": WORKTEAM_ARN,\r\n            \"HumanTaskUiArn\": humanTaskUiArn,\r\n            \"TaskCount\": 1,\r\n            \"TaskDescription\": \"Identify custom labels in the image\",\r\n            \"TaskTitle\": \"Identify custom image\"\r\n        },\r\n        OutputConfig={\r\n            \"S3OutputPath\" : OUTPUT_PATH\r\n        }\r\n    )\r\nflowDefinitionArn = create_workflow_definition_response['FlowDefinitionArn'] # let's save this ARN for future use\r\n<\/code><\/pre>\n<\/div>\n<p>Optionally, you can create this workflow definition on the <a href=\"https:\/\/console.aws.amazon.com\/a2i\/home?region=us-east-1#\/human-review-workflows\" target=\"_blank\" rel=\"noopener noreferrer\">Amazon A2I console<\/a>. For instructions, see <a href=\"https:\/\/docs.aws.amazon.com\/sagemaker\/latest\/dg\/a2i-create-flow-definition.html\" target=\"_blank\" rel=\"noopener noreferrer\">Create a Human Review Workflow<\/a>.<\/p>\n<h3>Sending predictions to Amazon A2I human loops<\/h3>\n<p>We now loop through our test images and invoke the trained model endpoint to detect the custom label <code>pepperoni pizza slice<\/code> using the <code>detect_custom_labels<\/code> API. If the confidence score is less than 60% for the detected labels in our test dataset, we send that data for human review and start the human review A2I loop with the <a href=\"https:\/\/awscli.amazonaws.com\/v2\/documentation\/api\/latest\/reference\/sagemaker-a2i-runtime\/start-human-loop.html\" target=\"_blank\" rel=\"noopener noreferrer\">start-human-loop<\/a> API. When using Amazon A2I for a custom task, a human loops starts when <code>StartHumanLoop<\/code> is called in your application. Use the accompanying <a href=\"https:\/\/github.com\/aws-samples\/amazon-a2i-sample-jupyter-notebooks\/blob\/master\/Amazon-A2I-Rekognition-Custom-Label-notebook.ipynb\" target=\"_blank\" rel=\"noopener noreferrer\">Amazon SageMaker Jupyter notebook<\/a> to follow the steps in this post.<\/p>\n<p>You can change the value of the <code>SCORE_THRESHOLD<\/code> based on what confidence level you want to trigger the human review. See the following code:<\/p>\n<div class=\"hide-language\">\n<pre class=\"unlimited-height-code\"><code class=\"lang-python\">import uuid\r\n\r\nhuman_loops_started = []\r\nSCORE_THRESHOLD = 60\r\n\r\nfolderpath = r\"data\/testimages\" # make sure to put the 'r' in front and provide the folder where your files are\r\nfilepaths  = [os.path.join(folderpath, name) for name in os.listdir(folderpath) if not name.startswith('.')] # do not select hidden directories\r\nfor path in filepaths:\r\n    # Call custom label endpoint and not display any object detected with probability lower than 0.01\r\n    response = client.detect_custom_labels(Image={'S3Object': {'Bucket': BUCKET, 'Name': PREFIX+'\/'+path}},\r\n        MinConfidence=20,\r\n        ProjectVersionArn=model_arn)    \r\n  \r\n    #Get the custom labels\r\n    labels=response['CustomLabels']\r\n    if labels and labels[0]['Confidence'] &lt; SCORE_THRESHOLD: \r\n        s3_fname='s3:\/\/%s\/%s' % (BUCKET, PREFIX+'\/'+path)\r\n        print(\"Images with labels less than 60% confidence score: \" + s3_fname)\r\n        humanLoopName = str(uuid.uuid4())\r\n        inputContent = {\r\n            \"initialValue\": 'null',\r\n            \"taskObject\": s3_fname\r\n        }\r\n        start_loop_response = a2i.start_human_loop(\r\n            HumanLoopName=humanLoopName,\r\n            FlowDefinitionArn=flowDefinitionArn,\r\n            HumanLoopInput={\r\n                \"InputContent\": json.dumps(inputContent)\r\n            }\r\n        )\r\n        human_loops_started.append(humanLoopName)\r\n        print(f'Starting human loop with name: {humanLoopName}  n')\r\n<\/code><\/pre>\n<\/div>\n<p>The following screenshot shows the output.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-full wp-image-16530\" src=\"https:\/\/d2908q01vomqb2.cloudfront.net\/f1f836cb4ea6efb2a0b1b99f41ad8b103eff4b59\/2020\/09\/30\/12.jpg\" alt=\"\" width=\"900\" height=\"66\"><\/p>\n<h3>Checking the status of human loop<\/h3>\n<p>Run the steps in the notebook to check the status of the human loop. You can use the accompanying <a href=\"https:\/\/github.com\/aws-samples\/amazon-a2i-sample-jupyter-notebooks\/blob\/master\/Amazon-A2I-Rekognition-Custom-Label-notebook.ipynb\" target=\"_blank\" rel=\"noopener noreferrer\">Amazon SageMaker Jupyter notebook<\/a> to follow the steps in this post.<\/p>\n<ol>\n<li>Run the following notebook cell to get a login link to navigate to the private workforce portal:<\/li>\n<\/ol>\n<div class=\"hide-language\">\n<pre class=\"unlimited-height-code\"><code class=\"lang-python\">workteamName = WORKTEAM_ARN[WORKTEAM_ARN.rfind('\/') + 1:]\r\nprint(\"Navigate to the private worker portal and do the tasks. Make sure you've invited yourself to your workteam!\")\r\nprint('https:\/\/' + sagemaker_client.describe_workteam(WorkteamName=workteamName)['Workteam']['SubDomain'])<\/code><\/pre>\n<\/div>\n<ol start=\"2\">\n<li>Choose the login link to the private worker portal.<\/li>\n<\/ol>\n<p>After you log in, you can start working on the task assigned.<\/p>\n<ol start=\"3\">\n<li>Draw bounding boxes with respect to the label as required and choose <strong>Submit<\/strong>.<\/li>\n<\/ol>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-full wp-image-16523\" src=\"https:\/\/d2908q01vomqb2.cloudfront.net\/f1f836cb4ea6efb2a0b1b99f41ad8b103eff4b59\/2020\/09\/30\/7-pizza2.jpg\" alt=\"\" width=\"900\" height=\"469\"><\/p>\n<ol start=\"4\">\n<li>To check if the workers have completed the labeling task, enter the following code:<\/li>\n<\/ol>\n<div class=\"hide-language\">\n<pre class=\"unlimited-height-code\"><code class=\"lang-python\">completed_human_loops = []\r\nfor human_loop_name in human_loops_started:\r\n    resp = a2i.describe_human_loop(HumanLoopName=human_loop_name)\r\n    print(f'HumanLoop Name: {human_loop_name}')\r\n    print(f'HumanLoop Status: {resp[\"HumanLoopStatus\"]}')\r\n    print(f'HumanLoop Output Destination: {resp[\"HumanLoopOutput\"]}')\r\n    print('n')\r\n    \r\n    if resp[\"HumanLoopStatus\"] == \"Completed\":\r\n        completed_human_loops.append(resp)\r\n<\/code><\/pre>\n<\/div>\n<p>The following screenshot shows the output.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-full wp-image-16524\" src=\"https:\/\/d2908q01vomqb2.cloudfront.net\/f1f836cb4ea6efb2a0b1b99f41ad8b103eff4b59\/2020\/09\/30\/8-Screenshot-3.jpg\" alt=\"\" width=\"900\" height=\"77\"><\/p>\n<h2>Evaluating the results and retraining your model<\/h2>\n<p>When the labeling work is complete, your results should be available in the Amazon S3 output path specified in the human review workflow definition. The human answer, label, and bounding box are returned and saved in the JSON file. Run the notebook cell to get the results from Amazon S3. The following screenshot shows the Amazon A2I annotation output JSON file.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-full wp-image-16525\" src=\"https:\/\/d2908q01vomqb2.cloudfront.net\/f1f836cb4ea6efb2a0b1b99f41ad8b103eff4b59\/2020\/09\/30\/9-Screenshot-1.jpg\" alt=\"\" width=\"900\" height=\"174\"><\/p>\n<p>Because we created our training set using Ground Truth, it\u2019s in the form of an output.manifest file in the <code>data\/manifest<\/code> folder. We need to do the following:<\/p>\n<ol>\n<li>Convert the Amazon A2I labeled JSON output to a .manifest file for retraining.<\/li>\n<li>Merge the <code>output.manifest<\/code> file with the existing training dataset .manifest file in data\/manifest.<\/li>\n<li>Train the new model using the augmented file.<\/li>\n<\/ol>\n<h3>Converting the JSON output to an augmented .manifest file<\/h3>\n<p>You can loop through all the Amazon A2I output, convert the JSON file, and concatenate them into a JSON Lines file, in which each line represents the results of one image. Run the following code in the <a href=\"https:\/\/github.com\/aws-samples\/amazon-a2i-sample-jupyter-notebooks\/blob\/master\/Amazon-A2I-Rekognition-Custom-Label-notebook.ipynb\" target=\"_blank\" rel=\"noopener noreferrer\">Amazon SageMaker Jupyter notebook<\/a> to convert the Amazon A2I results into an augmented manifest:<\/p>\n<div class=\"hide-language\">\n<pre class=\"unlimited-height-code\"><code class=\"lang-python\">object_categories = ['pepperoni pizza slice'] # if you have more labels, add them here\r\nobject_categories_dict = {str(i): j for i, j in enumerate(object_categories)}\r\n\r\ndsname = 'pepperoni_pizza'\r\n\r\ndef convert_a2i_to_augmented_manifest(a2i_output):\r\n    annotations = []\r\n    confidence = []\r\n    for i, bbox in enumerate(a2i_output['humanAnswers'][0]['answerContent']['annotatedResult']['boundingBoxes']):\r\n        object_class_key = [key for (key, value) in object_categories_dict.items() if value == bbox['label']][0]\r\n        obj = {'class_id': int(object_class_key), \r\n               'width': bbox['width'],\r\n               'top': bbox['top'],\r\n               'height': bbox['height'],\r\n               'left': bbox['left']}\r\n        annotations.append(obj)\r\n        confidence.append({'confidence': 1})\r\n\r\n    # Change the attribute name to the dataset-name_BB for this dataset. This will later be used in setting the training data\r\n    augmented_manifest={'source-ref': a2i_output['inputContent']['taskObject'],\r\n                        dsname+'_BB': {'annotations': annotations,\r\n                                           'image_size': [{'width': a2i_output['humanAnswers'][0]['answerContent']['annotatedResult']['inputImageProperties']['width'],\r\n                                                           'depth':3,\r\n                                                           'height': a2i_output['humanAnswers'][0]['answerContent']['annotatedResult']['inputImageProperties']['height']}]},\r\n                        dsname+'_BB-metadata': {'job-name': 'a2i\/%s' % a2i_output['humanLoopName'],\r\n                                                    'class-map': object_categories_dict,\r\n                                                    'human-annotated':'yes',\r\n                                                    'objects': confidence,\r\n                                                    'creation-date': a2i_output['humanAnswers'][0]['submissionTime'],\r\n                                                    'type':'groundtruth\/object-detection'}}\r\n    return augmented_manifest\r\n<\/code><\/pre>\n<\/div>\n<h3>Merging the augmented manifest with the existing training manifest<\/h3>\n<p>You now need to merge the output.manifest file, which consists of the existing training dataset manifest in <code>data\/manifest<\/code>, with the Amazon A2I augmented .manifest file you generated from the JSON output.<\/p>\n<p>Run the following notebook cell in the <a href=\"https:\/\/github.com\/aws-samples\/amazon-a2i-sample-jupyter-notebooks\/blob\/master\/Amazon-A2I-Rekognition-Custom-Label-notebook.ipynb\" target=\"_blank\" rel=\"noopener noreferrer\">Amazon SageMaker Jupyter notebook<\/a> to generate this file for training a new model:<\/p>\n<div class=\"hide-language\">\n<pre class=\"unlimited-height-code\"><code class=\"lang-python\">f4 = open('.\/augmented-temp.manifest', 'r')\r\nwith open('augmented.manifest', 'w') as outfl:\r\n    for lin1 in f4:\r\n        z_json = json.loads(lin1)\r\n        done_json = json.loads(lin1)\r\n        done_json['source-ref'] = 'a'\r\n        f3 = open('.\/data\/manifest\/output.manifest', 'r')\r\n        for lin2 in f3:\r\n            x_json = json.loads(lin2)\r\n            if z_json['source-ref'] == x_json['source-ref']:\r\n                print(\"replacing the annotations\")\r\n                x_json[dsname+'_BB'] = z_json[dsname+'_BB']\r\n                x_json[dsname+'_BB-metadata'] = z_json[dsname+'_BB-metadata']\r\n            elif done_json['source-ref'] != z_json['source-ref']:\r\n                print(\"This is a net new annotation to augmented file\")\r\n                json.dump(z_json, outfl)\r\n                outfl.write('n')\r\n                print(str(z_json))\r\n                done_json = z_json\r\n            json.dump(x_json, outfl)\r\n            outfl.write('n')         \r\n        f3.close()       \r\nf4.close()    \r\n<\/code><\/pre>\n<\/div>\n<h3>Training a new model<\/h3>\n<p>To train a new model with the augmented manifest, enter the following code:<\/p>\n<div class=\"hide-language\">\n<pre class=\"unlimited-height-code\"><code class=\"lang-python\"># upload the manifest file to S3\r\ns3r.meta.client.upload_file('.\/augmented.manifest', BUCKET, PREFIX+'\/'+'data\/manifest\/augmented.manifest')\r\n<\/code><\/pre>\n<\/div>\n<p>We uploaded the augmented .manifest file from Amazon A2I to the S3 bucket. You can train a new model by creating a new dataset by following the <strong>Creating a dataset<\/strong> step in this post using this augmented manifest. The following screenshot shows some of the results from the dataset.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-full wp-image-16526\" src=\"https:\/\/d2908q01vomqb2.cloudfront.net\/f1f836cb4ea6efb2a0b1b99f41ad8b103eff4b59\/2020\/09\/30\/10-Screenshot-1.jpg\" alt=\"\" width=\"900\" height=\"759\"><\/p>\n<p>Follow the instructions provided in the section <strong>Creating an Amazon Rekognition custom label model <\/strong>of this post. After you train a new model using this augmented dataset, you can inspect the model metrics for accuracy improvement.<\/p>\n<p>The following screenshot shows the metrics for the trained model using the Amazon AI labeled dataset.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-full wp-image-16527\" src=\"https:\/\/d2908q01vomqb2.cloudfront.net\/f1f836cb4ea6efb2a0b1b99f41ad8b103eff4b59\/2020\/09\/30\/11-Evaluation-results.jpg\" alt=\"\" width=\"900\" height=\"397\"><\/p>\n<p>We noticed an overall improvement in the metrics after retraining using the augmented dataset. Moreover, we used only 12 images to achieve these performance metrics.<\/p>\n<h2>Cleaning up<\/h2>\n<p>To avoid incurring unnecessary charges, delete the resources used in this walkthrough when not in use. For instructions, see the following:<\/p>\n<h2>Conclusion<\/h2>\n<p>This post demonstrated how you can use Amazon Rekognition Custom Labels and Amazon A2I to train models to detect objects and images unique to your business and define conditions to send the predictions to a human workflow with labelers to review and update the results. You can use the human labeled output to augment the training dataset for retraining, which improves model accuracy, or you can send it to downstream applications for analytics and insights.<\/p>\n<hr>\n<h3>About the Authors<\/h3>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"size-full wp-image-16219 alignleft\" src=\"https:\/\/d2908q01vomqb2.cloudfront.net\/f1f836cb4ea6efb2a0b1b99f41ad8b103eff4b59\/2020\/09\/23\/Mona.jpg\" alt=\"\" width=\"100\" height=\"134\"><strong>Mona Mona<\/strong> is an AI\/ML Specialist Solutions Architect based out of Arlington, VA. She works with the World Wide Public Sector team and helps customers adopt machine learning on a large scale. She is passionate about NLP and ML Explainability areas in AI\/ML.<\/p>\n<p>\u00a0<\/p>\n<p>\u00a0<\/p>\n<p>\u00a0<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"size-full wp-image-16535 alignleft\" src=\"https:\/\/d2908q01vomqb2.cloudfront.net\/f1f836cb4ea6efb2a0b1b99f41ad8b103eff4b59\/2020\/09\/30\/PremRanga-1.jpg\" alt=\"\" width=\"100\" height=\"125\"><strong>Prem Ranga<\/strong> is an Enterprise Solutions Architect based out of Houston, Texas. He is part of the Machine Learning Technical Field Community and loves working with customers on their ML and AI journey. Prem is passionate about robotics, is an autonomous vehicles researcher, and also built the Alexa-controlled Beer Pours in Houston and other locations.<\/p>\n<p>\u00a0<\/p>\n<p>\u00a0<\/p>\n<p>\u00a0<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"size-full wp-image-16534 alignleft\" src=\"https:\/\/d2908q01vomqb2.cloudfront.net\/f1f836cb4ea6efb2a0b1b99f41ad8b103eff4b59\/2020\/09\/30\/NeelSendas.jpg\" alt=\"\" width=\"100\" height=\"115\"><strong>Neel Sendas<\/strong> is a Senior Technical Account Manager at Amazon Web Services. Neel works with enterprise customers to design, deploy, and scale cloud applications to achieve their business goals. He has worked on various ML use cases, ranging from anomaly detection to predictive product quality for manufacturing and logistics optimization. When he is not helping customers, he dabbles in golf and salsa dancing.<\/p>\n<\/p><\/div>\n","protected":false},"excerpt":{"rendered":"<p>https:\/\/aws.amazon.com\/blogs\/machine-learning\/using-amazon-rekognition-custom-labels-and-amazon-a2i-for-detecting-pizza-slices-and-augmenting-predictions\/<\/p>\n","protected":false},"author":0,"featured_media":319,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[3],"tags":[],"_links":{"self":[{"href":"https:\/\/salarydistribution.com\/machine-learning\/wp-json\/wp\/v2\/posts\/318"}],"collection":[{"href":"https:\/\/salarydistribution.com\/machine-learning\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/salarydistribution.com\/machine-learning\/wp-json\/wp\/v2\/types\/post"}],"replies":[{"embeddable":true,"href":"https:\/\/salarydistribution.com\/machine-learning\/wp-json\/wp\/v2\/comments?post=318"}],"version-history":[{"count":0,"href":"https:\/\/salarydistribution.com\/machine-learning\/wp-json\/wp\/v2\/posts\/318\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/salarydistribution.com\/machine-learning\/wp-json\/wp\/v2\/media\/319"}],"wp:attachment":[{"href":"https:\/\/salarydistribution.com\/machine-learning\/wp-json\/wp\/v2\/media?parent=318"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/salarydistribution.com\/machine-learning\/wp-json\/wp\/v2\/categories?post=318"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/salarydistribution.com\/machine-learning\/wp-json\/wp\/v2\/tags?post=318"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}