<jupyter_start><jupyter_text>Sagemaker Ground Truth TutorialAWS Sagemaker Ground Truth 를 이용하여 개와 고양이 이미지에 대한 라벨링 잡을 만들어 본다.  Step 0: 설정<jupyter_code># Built-in
import os
import json
from glob import glob
from pprint import pprint
from matplotlib import pyplot as plt

# External Dependencies
import boto3
import sagemaker
from gluoncv.utils import viz
session = boto3.session.Session()
region = session.region_name
BUCKET_NAME = sagemaker.Session().default_bucket()
s3 = session.resource('s3')
bucket = s3.Bucket(BUCKET_NAME)
bucket.name<jupyter_output><empty_output><jupyter_text>Step 1: 이미지 S3에 업로드하기이미지는 images 폴더 아래에 8장이 준비되어 있다. 개, 고양이 그리고 개도 고양이도 아닌 동물 사진이 포함되어 있다.그라운드 트루스 라벨링 잡을 만들기 위해서 준비된 이미지를 S3 에 업로드해야한다.위에 표시된 bucket의 *images/* 아래에 이미지들을 업로드한다.<jupyter_code>filenames = []
for filepath in glob('./images/*.jpg'):
    filename = filepath.rsplit('/', 1)[1]
    print(f'upload file: {filename}')
    bucket.upload_file(filepath, f'images/{filename}')
    filenames.append(filename)<jupyter_output>upload file: 8.jpg
upload file: 4.jpg
upload file: 5.jpg
upload file: 7.jpg
upload file: 6.jpg
upload file: 2.jpg
upload file: 3.jpg
upload file: 1.jpg<jupyter_text>Step 2: catdog.manifest 생성하기이미지 주소들을 가지고 학습에 사용할 *catdot.manifest* 를 생성한다.세이지메이커에서 다양한 학습작업들을 생성하기 위해서는 이 manifest 가 필수적이다. manifest 파일은 *source-ref* 키만을 가진 아주 단순한 구조이다.해당 파일을 만들고 위에 표시된 bucket 의 *manifests/catdog.manifest* 로 업로드한다.<jupyter_code>os.makedirs(f'manifests', exist_ok=True)
manifest_loc = f'manifests/catdog.manifest'

with open(manifest_loc, 'w') as fp:
    for filename in filenames:
        source_ref = f's3://{bucket.name}/images/{filename}'
        fp.write(json.dumps({'source-ref': source_ref})+'\n')

bucket.upload_file(manifest_loc, manifest_loc)<jupyter_output><empty_output><jupyter_text>Step 3: Ground Truth 작업 생성> GT 는 한번에 데이터 1000개까지만 지원된다. 1000개 이상의 데이터를 라벨링 하기 원한다면 여러개의 작업으로 나눠서 진행해야한다.GT 는 라벨이 없는 원본 이미지에 라벨링을 쉽게 해줄 수 있는 툴이다. 우리는 디텍션 작업을 위해 이미지에 바운딩박스를 라벨링 해줘야 한다.GT 에서 라벨링 할 수 있는 작업자는 3종류가 있는데 우리는 이 중 *Private Workforce* 를 이용한다. Private Workforce 를 이용하면 팀원들이나 동료들에게 쉽게 라벨링 작업을 할당할 수 있다. Step 3-1. Private Workforce 만드는 법1. AWS Console 의 Services 에서 Sagemaker 를 선택하고,2. 좌측 사이드바에서 Ground Truth > Labeling workforces 를 선택한다.3. 우측 탭메뉴에서 Private 을 선택하고 원하는 작업자를 포함한 Workforce 를 생성한다.Workforce 를 만들면 작업자들에게 메일이 발송된다. 해당 메일에는 임시 비밀번호가 포함되어 있으며, 작업자들이 처음 작업용 URL 에 접근하면 반드시 비밀번호를 초기화하고 사용하게 되어 있다.<jupyter_code>input_data_location = f's3://{bucket.name}/{manifest_loc}'
output_data_location = f's3://{bucket.name}/annotations'

print(f'intput_dataset_location: {input_data_location}')
print(f'output_dataset_location: {output_data_location}')<jupyter_output>intput_dataset_location: s3://sagemaker-ap-northeast-2-929831892372/manifests/catdog.manifest
output_dataset_location: s3://sagemaker-ap-northeast-2-929831892372/annotations<jupyter_text>Step 3-2: GT 라벨링 작업 생성하기**Create labeling job** 버튼을 클릭해서 작업을 생성할 수 있다.* **Job name:** 적절한 작업이름을 적어준다. e.g. `catdog-label-0`* **Label name (The override checkbox):** `labels` 로 오버라이딩(override) 해준다. 기본은 `my-annotations` 이다.* **Input data location:** `catdog.manifest` 의 위치이다. 위에 표시된 `input_dataset_location` 값을 입력해준다.* **Output data location:** 라벨링 결과가 저장될 위치이다. 위에 표시된 `output_dataset_location` 을 입력해준다. 해당 위치에 위의 작업이름 아래로 저장되기 때문에 부모위치로 표시해주면 된다.* **IAM role:** 적절한 롤이 없다면 자동으로 생성해준다.* **Task type:** Image > Bounding box 를 선택한다.나머지는 다 기본값으로 두고 진행한다.마지막 라벨링툴 설정에서는 클래스에 **Cat** 과 **Dog** 를 각각 추가해주고 적절한 작업지시사항을 입력하면 끝이다. 원격으로 일하는 작업자들이 많을 경우, 작업지시사항이 자세할 수록 작업의 정확도가 크게 향상된다.  Step 4: 라벨링 하기*Ground Truth > Labeling Workforces* 에 표시된 주소로 이동하면 로그인을 하라고 나올 것이다.위에서 등록된 워크포스 참여자는 등록된 이메일과 비밀번호로 로그인을 하면 아래와 같이 자신에게 할당된 작업 목록을 확인할 수 있다.*Start Working* 을 눌러서 작업을 진행하면 된다.위와 같이 2개가 있으면 각각의 라벨을 클릭하고 라벨링을 하고, 위와 같이 라벨링 할 내용이 없으면(즉, 개 나 고양이가 없으면) 라벨없음에 체크하고 그냥 *Submit* 하면 된다.  Step 5: 라벨확인하기라벨링 작업이 완료되고 나면 처음 라벨링 잡을 만들때 지정했던 output_data_location 아래에 *output.manifest* 가 생긴다.여기에는 라벨링에 사용되었던 이미지의 정보와 우리가 원하던 바운딩박스정보가 함께 들어있다.이 output.manifest 를 이용하여 온프레미스 또는 Sagemaker 에서 Object Detection 모델 학습을 진행하면 된다.<jupyter_code>output_manifest_path = f'annotations/catdog-lablel-0/manifests/output/output.manifest'
output_manifest_obj = bucket.Object(output_manifest_path)
for el in map(json.loads, output_manifest_obj.get()['Body'].read().decode('utf-8').split('\n')):
    pprint(el)
    break<jupyter_output>{'labels': {'annotations': [{'class_id': 1,
                             'height': 386,
                             'left': 98,
                             'top': 89,
                             'width': 339}],
            'image_size': [{'depth': 3, 'height': 512, 'width': 512}]},
 'labels-metadata': {'class-map': {'1': 'Dog'},
                     'creation-date': '2020-04-29T16:38:58.542746',
                     'human-annotated': 'yes',
                     'job-name': 'labeling-job/catdog-lablel-0',
                     'objects': [{'confidence': 0.09}],
                     'type': 'groundtruth/object-detection'},
 'source-ref': 's3://sagemaker-ap-northeast-2-929831892372/images/8.jpg'}
{'fraction_non_alphanumeric': 0.11344704482348275, 'fraction_numerical': 0.026378421261404203, 'mean_word_length': 3.8490384615384614, 'pattern_counts': {'":': 0, '<': 18, '<?xml version=': 0, '>': 22, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '5', 'dir': 'jupyter-structured-clean-dedup', 'id': '465388', 'license': 'MIT', 'n_tokens_mistral': 2773, 'n_tokens_neox': 3317, 'n_words': 572, 'path': 'Sagemaker Ground Truth.ipynb', 'repo_name': 'haandol/sagemaker-groundtruth-tutorial', 'size': '5042'}