

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 將其他資料集格式轉換為清單檔案
<a name="md-converting-to-sm-format"></a>

您可以使用以下資訊，從各種來源資料集格式建立 Amazon SageMaker AI 格式資訊清單檔案。建立清單檔案後，請使用它來建立資料集。如需詳細資訊，請參閱[使用資訊清單檔案匯入映像](md-create-dataset-ground-truth.md)。

**Topics**
+ [將 COCO 資料集轉換為資訊清單檔案格式](md-transform-coco.md)
+ [轉換多標籤 SageMaker AI Ground Truth 資訊清單檔案](md-gt-cl-transform.md)
+ [從 CSV 檔案建立清單檔案。](ex-csv-manifest.md)

# 將 COCO 資料集轉換為資訊清單檔案格式
<a name="md-transform-coco"></a>

[COCO](http://cocodataset.org/#home) 是一種用於指定大規模物件偵測、分割和字幕資料集的格式。此 Python [範例](md-coco-transform-example.md)會說明如何將 COCO 物件偵測格式資料集轉換為 Amazon Rekognition 自訂標籤[週框方塊格式清單檔案](md-create-manifest-file-object-detection.md)。本區段還包括您可用於撰寫自己的程式碼的資訊。

COCO 格式的 JSON 檔案由五個區段組成，提供*整個資料集*的資訊。如需詳細資訊，請參閱[COCO 資料集格式](md-coco-overview.md)。
+ `info` — 有關資料集的一般資訊。
+ `licenses ` — 資料集中影像的授權資訊。
+ [`images`](md-coco-overview.md#md-coco-images) — 資料集中的影像清單。
+ [`annotations`](md-coco-overview.md#md-coco-annotations) — 資料集中所有影像中出現的註釋清單 (包括週框方塊)。
+ [`categories`](md-coco-overview.md#md-coco-categories) — 標籤類別清單。

您需要 `images`、`annotations` 和 `categories` 清單中的資訊，才能建立 Amazon Rekognition 自訂標籤清單檔案。

Amazon Rekognition 自訂標籤清單檔案採用 JSON Lines 格式，其中每行都具有*影像上*一或多個物件的週框方塊和標籤資訊。如需詳細資訊，請參閱[資訊清單檔案中的物件當地語系化](md-create-manifest-file-object-detection.md)。

## 將 COCO 物件對應至自訂標籤 JSON Line
<a name="md-mapping-coco"></a>

若要轉換 COCO 格式資料集，請將 COCO 資料集對應至 Amazon Rekognition 自訂標籤清單檔案，以進行物件本地化。如需詳細資訊，請參閱[資訊清單檔案中的物件當地語系化](md-create-manifest-file-object-detection.md)。若要為每個影像建置 JSON Line，清單檔案需要對應 COCO 資料集 `image`、`annotation` 和 `category` 物件欄位 ID。

以下是 COCO 清單檔案範例。如需詳細資訊，請參閱[COCO 資料集格式](md-coco-overview.md)。

```
{
    "info": {
        "description": "COCO 2017 Dataset","url": "http://cocodataset.org","version": "1.0","year": 2017,"contributor": "COCO Consortium","date_created": "2017/09/01"
    },
    "licenses": [
        {"url": "http://creativecommons.org/licenses/by/2.0/","id": 4,"name": "Attribution License"}
    ],
    "images": [
        {"id": 242287, "license": 4, "coco_url": "http://images.cocodataset.org/val2017/xxxxxxxxxxxx.jpg", "flickr_url": "http://farm3.staticflickr.com/2626/xxxxxxxxxxxx.jpg", "width": 426, "height": 640, "file_name": "xxxxxxxxx.jpg", "date_captured": "2013-11-15 02:41:42"},
        {"id": 245915, "license": 4, "coco_url": "http://images.cocodataset.org/val2017/nnnnnnnnnnnn.jpg", "flickr_url": "http://farm1.staticflickr.com/88/xxxxxxxxxxxx.jpg", "width": 640, "height": 480, "file_name": "nnnnnnnnnn.jpg", "date_captured": "2013-11-18 02:53:27"}
    ],
    "annotations": [
        {"id": 125686, "category_id": 0, "iscrowd": 0, "segmentation": [[164.81, 417.51,......167.55, 410.64]], "image_id": 242287, "area": 42061.80340000001, "bbox": [19.23, 383.18, 314.5, 244.46]},
        {"id": 1409619, "category_id": 0, "iscrowd": 0, "segmentation": [[376.81, 238.8,........382.74, 241.17]], "image_id": 245915, "area": 3556.2197000000015, "bbox": [399, 251, 155, 101]},
        {"id": 1410165, "category_id": 1, "iscrowd": 0, "segmentation": [[486.34, 239.01,..........495.95, 244.39]], "image_id": 245915, "area": 1775.8932499999994, "bbox": [86, 65, 220, 334]}
    ],
    "categories": [
        {"supercategory": "speaker","id": 0,"name": "echo"},
        {"supercategory": "speaker","id": 1,"name": "echo dot"}
    ]
}
```

下圖顯示*資料集*的 COCO 資料集清單如何對應至*影像*的 Amazon Rekognition 自訂標籤 JSON Lines。影像的每個 JSON 行都顯示來源參考、任務和任務中繼資料欄位。相符顏色表示單一影像的資訊。請注意，在資訊清單中，個別影像可能有多個註釋和中繼資料/類別。

![\[圖表顯示 Coco 資訊清單的結構，其中包含影像、註釋和類別。\]](http://docs.aws.amazon.com/zh_tw/rekognition/latest/customlabels-dg/images/coco-transform.png)


**取得單一 JSON Line 的 COCO 物件**

1. 對於影像清單中的每個影像，請從註釋清單中取得註釋，其中註釋欄位 `image_id` 的值會和影像 `id` 欄位相符。

1. 對於步驟 1 中相符的每個註釋，請詳閱 `categories` 清單並取得 `category` 欄位 `id` 的值和 `annotation` 物件 `category_id` 欄位相符的每個 `category`。

1. 使用相符的 `image`、`annotation` 和 `category` 物件為影像建立 JSON Line。若要對應欄位，請參閱 [將 COCO 物件對應至自訂標籤 JSON Line 物件欄位](#md-mapping-fields-coco)。

1. 重複步驟 1 至 3，直到您為 `images` 清單中的每個 `image` 物件建立 JSON Lines 為止。

如需範例程式碼，請參閱 [轉換 COCO 資料集](md-coco-transform-example.md)。

## 將 COCO 物件對應至自訂標籤 JSON Line 物件欄位
<a name="md-mapping-fields-coco"></a>

在您識別 Amazon Rekognition 自訂標籤 JSON Line 的 COCO 物件之後，您需要將 COCO 物件欄位對應至各自的 Amazon Rekognition 自訂標籤 JSON Line 物件欄位。下列 Amazon Rekognition 自訂標籤 JSON Line 範例會將一個影像 (`id`=`000000245915`) 對應至前一個 COCO JSON 範例。記下以下資訊。
+ `source-ref` 是 Amazon S3 儲存貯體中影像的位置。如果您的 COCO 影像未存放在 Amazon S3 儲存貯體中，您需要將它們移至 Amazon S3 儲存貯體。
+ 此 `annotations` 清單包含影像上每個物件的 `annotation` 物件。`annotation` 物件包括週框方塊資訊 (`top`、`left`、`width`、`height`) 和標籤識別碼 (`class_id`)。
+ 標籤識別碼 (`class_id`) 會對應至中繼資料中的 `class-map` 清單。它會列出在影像上使用的標籤。

```
{
	"source-ref": "s3://custom-labels-bucket/images/000000245915.jpg",
	"bounding-box": {
		"image_size": {
			"width": 640,
			"height": 480,
			"depth": 3
		},
		"annotations": [{
			"class_id": 0,
			"top": 251,
			"left": 399,
			"width": 155,
			"height": 101
		}, {
			"class_id": 1,
			"top": 65,
			"left": 86,
			"width": 220,
			"height": 334
		}]
	},
	"bounding-box-metadata": {
		"objects": [{
			"confidence": 1
		}, {
			"confidence": 1
		}],
		"class-map": {
			"0": "Echo",
			"1": "Echo Dot"
		},
		"type": "groundtruth/object-detection",
		"human-annotated": "yes",
		"creation-date": "2018-10-18T22:18:13.527256",
		"job-name": "my job"
	}
}
```

使用下列資訊將 Amazon Rekognition 自訂標籤清單檔案欄位對應至 COCO 資料集 JSON 欄位。

### source-ref
<a name="md-source-ref-coco"></a>

影像位置的 S3 格式 URL。影片必須存放在 S3 儲存貯體中。如需詳細資訊，請參閱[source-ref](md-create-manifest-file-object-detection.md#cd-manifest-source-ref)。如果 `coco_url` COCO 欄位指向 S3 儲存貯體位置，您可以使用 `coco_url` 的值作為 `source-ref` 的值。或者，您可以將 `source-ref` 對應至 `file_name` (COCO) 欄位，並在轉換程式碼中，將必要的 S3 路徑新增至影像的存放位置。

### *bounding-box*
<a name="md-label-attribute-id-coco"></a>

您選擇的標籤屬性名稱。如需詳細資訊，請參閱[*bounding-box*](md-create-manifest-file-object-detection.md#md-manifest-source-bounding-box)。

#### image\$1size
<a name="md-image-size-coco"></a>

影像大小 (以像素為單位)。對應至`image`影像[清單中的 ](md-coco-overview.md#md-coco-images) 物件。
+ `height`-> `image.height`
+ `width`-> `image.width`
+ `depth`-> Amazon Rekognition 自訂標籤目前未使用，但必須一個值。

#### 註釋
<a name="md-annotations-coco"></a>

`annotation` 物件的清單。影像上的每個物件都有一個 `annotation`。

#### 註釋
<a name="md-annotation-coco"></a>

包含影像上某個物件執行個體的週框方塊資訊。
+ `class_id` -> 數字 ID 對應至自訂標籤的 `class-map` 清單。
+ `top` -> `bbox[1]`
+ `left` -> `bbox[0]`
+ `width` -> `bbox[2]`
+ `height` -> `bbox[3]`

### *bounding-box*-metadata
<a name="md-metadata-coco"></a>

標籤屬性的中繼資料。包括標籤和標籤識別碼。如需詳細資訊，請參閱[*bounding-box*-metadata](md-create-manifest-file-object-detection.md#md-manifest-source-bounding-box-metadata)。

#### 物件
<a name="cd-metadata-objects-coco"></a>

影像中的物件陣列。對應至 `annotations` 清單 (依索引)。

##### 物件
<a name="cd-metadata-object-coco"></a>
+ `confidence`->Amazon Rekognition 自訂標籤未使用，但需要值 (1)。

#### class-map
<a name="md-metadata-class-map-coco"></a>

套用至影像中偵測到之物件的標籤 (類別) 的對應。對應至[類別](md-coco-overview.md#md-coco-categories)清單中的類別物件。
+ `id` -> `category.id`
+ `id value` -> `category.name`

#### type
<a name="md-type-coco"></a>

必須為 `groundtruth/object-detection`

#### human-annotated
<a name="md-human-annotated-coco"></a>

可指定為 `yes` 或 `no`。如需詳細資訊，請參閱[*bounding-box*-metadata](md-create-manifest-file-object-detection.md#md-manifest-source-bounding-box-metadata)。

#### creation-date -> [image](md-coco-overview.md#md-coco-images).date\$1captured
<a name="md-creation-date-coco"></a>

影像的建立日期和時間。對應至 COCO 影像清單中影像的 [image](md-coco-overview.md#md-coco-images).date\$1captured 欄位。Amazon Rekognition 自訂標籤預期 `creation-date` 的格式為 *Y-M-DTH:M:S*。

#### job-name
<a name="md-job-name-coco"></a>

您選擇的任務名稱。

# COCO 資料集格式
<a name="md-coco-overview"></a>

COCO 資料集由五個區段的資訊組成，可提供整個資料集的資訊。COCO 物件偵測資料集的格式會以 [COCO 資料格式](http://cocodataset.org/#format-data)記錄。
+ info — 有關資料集的一般資訊。
+ licenses — 資料集中影像的授權資訊。
+ [images](#md-coco-images) — 資料集中的影像清單。
+ [annotations](#md-coco-annotations) — 資料集中所有影像中出現的註釋清單 (包括週框方塊)。
+ [categories](#md-coco-categories) — 標籤類別清單。

若要建立自訂標籤清單檔案，請使用 COCO 清單檔案中的 `images`、`annotations`、和 `categories` 清單。其他區段 (`info`、`licences`) 則非必要。以下是 COCO 清單檔案範例。

```
{
    "info": {
        "description": "COCO 2017 Dataset","url": "http://cocodataset.org","version": "1.0","year": 2017,"contributor": "COCO Consortium","date_created": "2017/09/01"
    },
    "licenses": [
        {"url": "http://creativecommons.org/licenses/by/2.0/","id": 4,"name": "Attribution License"}
    ],
    "images": [
        {"id": 242287, "license": 4, "coco_url": "http://images.cocodataset.org/val2017/xxxxxxxxxxxx.jpg", "flickr_url": "http://farm3.staticflickr.com/2626/xxxxxxxxxxxx.jpg", "width": 426, "height": 640, "file_name": "xxxxxxxxx.jpg", "date_captured": "2013-11-15 02:41:42"},
        {"id": 245915, "license": 4, "coco_url": "http://images.cocodataset.org/val2017/nnnnnnnnnnnn.jpg", "flickr_url": "http://farm1.staticflickr.com/88/xxxxxxxxxxxx.jpg", "width": 640, "height": 480, "file_name": "nnnnnnnnnn.jpg", "date_captured": "2013-11-18 02:53:27"}
    ],
    "annotations": [
        {"id": 125686, "category_id": 0, "iscrowd": 0, "segmentation": [[164.81, 417.51,......167.55, 410.64]], "image_id": 242287, "area": 42061.80340000001, "bbox": [19.23, 383.18, 314.5, 244.46]},
        {"id": 1409619, "category_id": 0, "iscrowd": 0, "segmentation": [[376.81, 238.8,........382.74, 241.17]], "image_id": 245915, "area": 3556.2197000000015, "bbox": [399, 251, 155, 101]},
        {"id": 1410165, "category_id": 1, "iscrowd": 0, "segmentation": [[486.34, 239.01,..........495.95, 244.39]], "image_id": 245915, "area": 1775.8932499999994, "bbox": [86, 65, 220, 334]}
    ],
    "categories": [
        {"supercategory": "speaker","id": 0,"name": "echo"},
        {"supercategory": "speaker","id": 1,"name": "echo dot"}
    ]
}
```

## 影像清單
<a name="md-coco-images"></a>

COCO 資料集所參考的影像會列在影像陣列中。每個影像物件都包含影像的相關資訊，例如影像檔案名稱。在下列影像物件範例中，請注意下列資訊，以及建立 Amazon Rekognition 自訂標籤清單檔案所需的欄位。
+ `id` — (必要) 影像的唯一識別碼。`id` 欄位會對應至註解陣列中的 `id` 欄位 (存放週框方塊資訊的位置)。
+ `license` — (非必要) 對應至授權陣列。
+ `coco_url` — (選用) 影像的位置
+ `flickr_url` — (非必要) 影像在 Flickr 上的位置。
+ `width` — (必要) 影像的寬度。
+ `height` — (必要) 影像的寬度。
+ `file_name` — (必要) 影像檔案名稱。在這個範例中，`file_name` 和 `id` 相符，但這並非 COCO 資料集的需求。
+ `date_captured` — (必要) 擷取影像的日期和時間。

```
{
    "id": 245915,
    "license": 4,
    "coco_url": "http://images.cocodataset.org/val2017/nnnnnnnnnnnn.jpg",
    "flickr_url": "http://farm1.staticflickr.com/88/nnnnnnnnnnnnnnnnnnn.jpg",
    "width": 640,
    "height": 480,
    "file_name": "000000245915.jpg",
    "date_captured": "2013-11-18 02:53:27"
}
```

## 註釋 (週框方塊) 清單
<a name="md-coco-annotations"></a>

所有影像上所有物件的週框方塊資訊會存放在註解清單中。單一註釋物件包含單一物件的週框方塊資訊，以及影像上物件的標籤。影像上物件的每個執行個體都有註釋物件。

在下列範例中，請注意下列資訊，以及建立 Amazon Rekognition 自訂標籤清單檔案所需的欄位。
+ `id` — (非必要) 註釋的識別碼。
+ `image_id` — (必要) 對應於影像陣列中的影像 `id`。
+ `category_id` — (必要) 標籤的識別碼，可識別週框方塊內的物件。它會對應至類別陣列的 `id` 欄位。
+ `iscrowd` — (非必要) 指定影像是否包含一群物件。
+ `segmentation` — (非必要) 影像上物件的分割資訊。Amazon Rekognition 自訂標籤不支援分割。
+ `area` — (非必要) 註釋的區域。
+ `bbox` – (必要) 包含影像上物件周圍週框方塊的座標 (以像素為單位)。

```
{
    "id": 1409619,
    "category_id": 1,
    "iscrowd": 0,
    "segmentation": [
        [86.0, 238.8,..........382.74, 241.17]
    ],
    "image_id": 245915,
    "area": 3556.2197000000015,
    "bbox": [86, 65, 220, 334]
}
```

## 類別清單
<a name="md-coco-categories"></a>

標籤資訊存放在類別陣列中。在下列類別物件範例中，請注意下列資訊，以及建立 Amazon Rekognition 自訂標籤清單檔案所需的欄位。
+ `supercategory` — (非必要) 標籤的父類別。
+ `id` — (必要) 標籤識別碼。`id` 欄位會對應至 `annotation` 物件中的 `category_id` 欄位。在下列範例中，Echo Dot 的識別碼為 2。
+ `name` — (必要) 標籤名稱。

```
        {"supercategory": "speaker","id": 2,"name": "echo dot"}
```

# 轉換 COCO 資料集
<a name="md-coco-transform-example"></a>

使用下列 Python 範例將週框方塊資訊從 COCO 格式資料集轉換為 Amazon Rekognition 自訂標籤清單檔案。程式碼會將建立的清單檔案上傳至 Amazon S3 儲存貯體。此程式碼也會提供 AWS CLI 命令，您可以用來上傳影像。

**轉換 COCO 資料集 (SDK)**

1. 如果您尚未執行：

   1. 請確認您具備 `AmazonS3FullAccess` 權限。如需詳細資訊，請參閱[設定 SDK 權限](su-sdk-permissions.md)。

   1. 安裝和設定 AWS CLI 和 AWS SDKs。如需詳細資訊，請參閱[步驟 4：設定 AWS CLI 和 AWS SDKs](su-awscli-sdk.md)。

1. 使用下列 Python 程式碼來轉換 COCO 資料集。設定下列值。
   + `s3_bucket` — 您要存放影像和 Amazon Rekognition 自訂標籤清單檔案之 S3 儲存貯體的名稱。
   + `s3_key_path_images` — 要在 S3 儲存貯體 (`s3_bucket`) 中放置影像的路徑。
   + `s3_key_path_manifest_file` — 要在 S3 儲存貯體 (`s3_bucket`) 中放置自訂標籤清單檔案的路徑。
   + `local_path` — 範例開啟輸入 COCO 資料集的本機路徑，並儲存新的自訂標籤清單檔案。
   + `local_images_path` — 要用於訓練之影像的本機路徑。
   + `coco_manifest` — 輸入 COCO 資料集檔案名稱。
   + `cl_manifest_file` — 範例所建立之清單檔案的名稱。檔案會儲存在 `local_path` 所指定的位置。按照慣例，該檔案會具有副檔名 `.manifest`，但這不是必要的。
   + `job_name` — 自訂標籤任務的名稱。

   ```
   import json
   import os
   import random
   import shutil
   import datetime
   import botocore
   import boto3
   import PIL.Image as Image
   import io
   
   #S3 location for images
   s3_bucket = 'bucket'
   s3_key_path_manifest_file = 'path to custom labels manifest file/'
   s3_key_path_images = 'path to images/'
   s3_path='s3://' + s3_bucket  + '/' + s3_key_path_images
   s3 = boto3.resource('s3')
   
   #Local file information
   local_path='path to input COCO dataset and output Custom Labels manifest/'
   local_images_path='path to COCO images/'
   coco_manifest = 'COCO dataset JSON file name'
   coco_json_file = local_path + coco_manifest
   job_name='Custom Labels job name'
   cl_manifest_file = 'custom_labels.manifest'
   
   label_attribute ='bounding-box'
   
   open(local_path + cl_manifest_file, 'w').close()
   
   # class representing a Custom Label JSON line for an image
   class cl_json_line:  
       def __init__(self,job, img):  
   
           #Get image info. Annotations are dealt with seperately
           sizes=[]
           image_size={}
           image_size["width"] = img["width"]
           image_size["depth"] = 3
           image_size["height"] = img["height"]
           sizes.append(image_size)
   
           bounding_box={}
           bounding_box["annotations"] = []
           bounding_box["image_size"] = sizes
   
           self.__dict__["source-ref"] = s3_path + img['file_name']
           self.__dict__[job] = bounding_box
   
           #get metadata
           metadata = {}
           metadata['job-name'] = job_name
           metadata['class-map'] = {}
           metadata['human-annotated']='yes'
           metadata['objects'] = [] 
           date_time_obj = datetime.datetime.strptime(img['date_captured'], '%Y-%m-%d %H:%M:%S')
           metadata['creation-date']= date_time_obj.strftime('%Y-%m-%dT%H:%M:%S') 
           metadata['type']='groundtruth/object-detection'
           
           self.__dict__[job + '-metadata'] = metadata
   
   
   print("Getting image, annotations, and categories from COCO file...")
   
   with open(coco_json_file) as f:
   
       #Get custom label compatible info    
       js = json.load(f)
       images = js['images']
       categories = js['categories']
       annotations = js['annotations']
   
       print('Images: ' + str(len(images)))
       print('annotations: ' + str(len(annotations)))
       print('categories: ' + str(len (categories)))
   
   
   print("Creating CL JSON lines...")
       
   images_dict = {image['id']: cl_json_line(label_attribute, image) for image in images}
   
   print('Parsing annotations...')
   for annotation in annotations:
   
       image=images_dict[annotation['image_id']]
   
       cl_annotation = {}
       cl_class_map={}
   
       # get bounding box information
       cl_bounding_box={}
       cl_bounding_box['left'] = annotation['bbox'][0]
       cl_bounding_box['top'] = annotation['bbox'][1]
    
       cl_bounding_box['width'] = annotation['bbox'][2]
       cl_bounding_box['height'] = annotation['bbox'][3]
       cl_bounding_box['class_id'] = annotation['category_id']
   
       getattr(image, label_attribute)['annotations'].append(cl_bounding_box)
   
   
       for category in categories:
            if annotation['category_id'] == category['id']:
               getattr(image, label_attribute + '-metadata')['class-map'][category['id']]=category['name']
           
       
       cl_object={}
       cl_object['confidence'] = int(1)  #not currently used by Custom Labels
       getattr(image, label_attribute + '-metadata')['objects'].append(cl_object)
   
   print('Done parsing annotations')
   
   # Create manifest file.
   print('Writing Custom Labels manifest...')
   
   for im in images_dict.values():
   
       with open(local_path+cl_manifest_file, 'a+') as outfile:
               json.dump(im.__dict__,outfile)
               outfile.write('\n')
               outfile.close()
   
   # Upload manifest file to S3 bucket.
   print ('Uploading Custom Labels manifest file to S3 bucket')
   print('Uploading'  + local_path + cl_manifest_file + ' to ' + s3_key_path_manifest_file)
   print(s3_bucket)
   s3 = boto3.resource('s3')
   s3.Bucket(s3_bucket).upload_file(local_path + cl_manifest_file, s3_key_path_manifest_file + cl_manifest_file)
   
   # Print S3 URL to manifest file,
   print ('S3 URL Path to manifest file. ')
   print('\033[1m s3://' + s3_bucket + '/' + s3_key_path_manifest_file + cl_manifest_file + '\033[0m') 
   
   # Display aws s3 sync command.
   print ('\nAWS CLI s3 sync command to upload your images to S3 bucket. ')
   print ('\033[1m aws s3 sync ' + local_images_path + ' ' + s3_path + '\033[0m')
   ```

1. 執行程式碼。

1. 在程式輸出中，記下磁碟區 `s3 sync` 命令。下一個步驟需要此值。

1. 在命令提示中，執行 `s3 sync` 命令。將影像上傳至 S3 儲存貯體。如果命令在上傳期間失敗，請再次執行，直到本機影像與 S3 儲存貯體同步為止。

1. 在程式輸出中，記下清單檔案的 S3 URL 路徑。下一個步驟需要此值。

1. 請遵循 [使用 SageMaker AI Ground Truth 資訊清單檔案 （主控台） 建立資料集](md-create-dataset-ground-truth.md#md-create-dataset-ground-truth-console) 中的指示，使用上傳的清單檔案建立資料集。對於步驟 8，請在 **.manifest 檔案位置**，輸入您在上一個步驟中記下的 Amazon S3 URL。如果您使用 AWS SDK，請執行 [使用 SageMaker AI Ground Truth 資訊清單檔案 (SDK) 建立資料集](md-create-dataset-ground-truth.md#md-create-dataset-ground-truth-sdk)。

# 轉換多標籤 SageMaker AI Ground Truth 資訊清單檔案
<a name="md-gt-cl-transform"></a>

本主題說明如何將多標籤 Amazon SageMaker AI Ground Truth 資訊清單檔案轉換為 Amazon Rekognition 自訂標籤格式資訊清單檔案。

多標籤任務的 SageMaker AI Ground Truth 資訊清單檔案的格式與 Amazon Rekognition 自訂標籤格式資訊清單檔案不同。多標籤分類指將影像分類為一組類別，但可能同時屬於多個類別。在這種情況下，影像可能有多個標籤 (多標籤)，例如 *football* 和 *ball*。

如需多標籤 SageMaker AI Ground Truth 任務的詳細資訊，請參閱[影像分類 （多標籤）](https://docs.aws.amazon.com/sagemaker/latest/dg/sms-image-classification-multilabel.html)。如需多標籤格式 Amazon Rekognition 自訂標籤清單檔案的相關資訊，請參閱 [對影像新增多個影像層級標籤](md-create-manifest-file-classification.md#md-dataset-purpose-classification-multiple-labels)。

## 取得 SageMaker AI Ground Truth 任務的資訊清單檔案
<a name="md-get-gt-manifest"></a>

下列程序說明如何取得 Amazon SageMaker AI Ground Truth 任務的輸出資訊清單檔案 (`output.manifest`)。將 `output.manifest` 用為下個程序的輸入。

**下載 SageMaker AI Ground Truth 任務清單檔案**

1. 開啟 [https://console.aws.amazon.com/sagemaker/](https://console.aws.amazon.com/sagemaker/)。

1. 在導覽窗格中，選擇 **Ground Truth**，然後選擇**標記任務**。

1. 選擇包含您要使用之清單檔案的標記任務。

1. 在詳細資訊頁面上，選擇**輸出資料集位置**下方的連結。Amazon S3 主控台會在資料集位置開啟。

1. 選擇 `Manifests`、`output`，然後選擇 `output.manifest`。

1. 若要下載清單檔案，請選擇**物件動作**，然後選擇**下載**。

## 轉換多標籤 SageMaker AI 資訊清單檔案
<a name="md-transform-ml-gt"></a>

下列程序會從現有的多標籤格式 SageMaker AI GroundTruth 資訊清單檔案建立多標籤格式的 Amazon Rekognition 自訂標籤資訊清單檔案。

**注意**  
若要執行程式碼，您需要 Python 版本 3 或更高版本。<a name="md-procedure-multi-label-transform"></a>

**轉換多標籤 SageMaker AI 資訊清單檔案**

1. 使用以下 Python 程式碼。提供您在 [取得 SageMaker AI Ground Truth 任務的資訊清單檔案](#md-get-gt-manifest) 中建立的清單檔案名稱作為命令列引數。

   ```
   # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
   # SPDX-License-Identifier:  Apache-2.0
   """
   Purpose
   Shows how to create and Amazon Rekognition Custom Labels format
   manifest file from an Amazon SageMaker Ground Truth Image
   Classification (Multi-label) format manifest file.
   """
   import json
   import logging
   import argparse
   import os.path
   
   logger = logging.getLogger(__name__)
   
   def create_manifest_file(ground_truth_manifest_file):
       """
       Creates an Amazon Rekognition Custom Labels format manifest file from
       an Amazon SageMaker Ground Truth Image Classification (Multi-label) format
       manifest file.
       :param: ground_truth_manifest_file: The name of the Ground Truth manifest file,
       including the relative path.
       :return: The name of the new Custom Labels manifest file.
       """
   
       logger.info('Creating manifest file from %s', ground_truth_manifest_file)
       new_manifest_file = f'custom_labels_{os.path.basename(ground_truth_manifest_file)}'
   
       # Read the SageMaker Ground Truth manifest file into memory.
       with open(ground_truth_manifest_file) as gt_file:
           lines = gt_file.readlines()
   
       #Iterate through the lines one at a time to generate the
       #new lines for the Custom Labels manifest file.
       with open(new_manifest_file, 'w') as the_new_file:
           for line in lines:
               #job_name - The of the Amazon Sagemaker Ground Truth job.
               job_name = ''
               # Load in the old json item from the Ground Truth manifest file
               old_json = json.loads(line)
   
               # Get the job name
               keys = old_json.keys()
               for key in keys:
                   if 'source-ref' not in key and '-metadata' not in key:
                       job_name = key
   
               new_json = {}
               # Set the location of the image
               new_json['source-ref'] = old_json['source-ref']
   
               # Temporarily store the list of labels
               labels = old_json[job_name]
   
               # Iterate through the labels and reformat to Custom Labels format
               for index, label in enumerate(labels):
                   new_json[f'{job_name}{index}'] = index
                   metadata = {}
                   metadata['class-name'] = old_json[f'{job_name}-metadata']['class-map'][str(label)]
                   metadata['confidence'] = old_json[f'{job_name}-metadata']['confidence-map'][str(label)]
                   metadata['type'] = 'groundtruth/image-classification'
                   metadata['job-name'] = old_json[f'{job_name}-metadata']['job-name']
                   metadata['human-annotated'] = old_json[f'{job_name}-metadata']['human-annotated']
                   metadata['creation-date'] = old_json[f'{job_name}-metadata']['creation-date']
                   # Add the metadata to new json line
                   new_json[f'{job_name}{index}-metadata'] = metadata
               # Write the current line to the json file
               the_new_file.write(json.dumps(new_json))
               the_new_file.write('\n')
   
       logger.info('Created %s', new_manifest_file)
       return  new_manifest_file
   
   def add_arguments(parser):
       """
       Adds command line arguments to the parser.
       :param parser: The command line parser.
       """
   
       parser.add_argument(
           "manifest_file", help="The Amazon SageMaker Ground Truth manifest file"
           "that you want to use."
       )
   
   
   def main():
       logging.basicConfig(level=logging.INFO,
                           format="%(levelname)s: %(message)s")
       try:
           # get command line arguments
           parser = argparse.ArgumentParser(usage=argparse.SUPPRESS)
           add_arguments(parser)
           args = parser.parse_args()
           # Create the manifest file
           manifest_file = create_manifest_file(args.manifest_file)
           print(f'Manifest file created: {manifest_file}')
       except FileNotFoundError as err:
           logger.exception('File not found: %s', err)
           print(f'File not found: {err}. Check your manifest file.')
   
   if __name__ == "__main__":
       main()
   ```

1. 記下指令碼顯示的新清單檔案的名稱。在下一個步驟中用得到。

1. [將清單檔案上傳](https://docs.aws.amazon.com/AmazonS3/latest/userguide/upload-objects.html)到您要用於存放清單檔案的 Amazon S3 儲存貯體。
**注意**  
請確保 Amazon Rekognition 自訂標籤可存取清單檔案 JSON Lines 的 `source-ref` 欄位中參考的 Amazon S3 儲存貯體。如需詳細資訊，請參閱[存取外部 Amazon S3 儲存貯體](su-console-policy.md#su-external-buckets)。如果您的 Ground Truth 任務將影像存放在 Amazon Rekognition 自訂標籤主控台儲存貯體中，則不需要新增權限。

1. 請遵循 [使用 SageMaker AI Ground Truth 資訊清單檔案 （主控台） 建立資料集](md-create-dataset-ground-truth.md#md-create-dataset-ground-truth-console) 中的指示，使用上傳的資訊清單檔案建立資料集。對於步驟 8，請在 **.manifest 檔案位置**，輸入清單檔案位置的 Amazon S3 URL。如果您使用 AWS SDK，請執行 [使用 SageMaker AI Ground Truth 資訊清單檔案 (SDK) 建立資料集](md-create-dataset-ground-truth.md#md-create-dataset-ground-truth-sdk)。

# 從 CSV 檔案建立清單檔案。
<a name="ex-csv-manifest"></a>

此 Python 指令碼範例使用逗號分隔值 (CSV) 檔案來標記影像，簡化了清單檔案的建立。建立 CSV 檔案。清單檔案適用於[多標籤影像分類](getting-started.md#gs-multi-label-image-classification-example) 或 [多標籤影像分類](getting-started.md#gs-multi-label-image-classification-example)。如需詳細資訊，請參閱[尋找物件、場景和概念](understanding-custom-labels.md#tm-classification)。

**注意**  
此指令碼不會建立適合尋找[物件位置](understanding-custom-labels.md#tm-object-localization)或尋找[品牌位置](understanding-custom-labels.md#tm-brand-detection-localization)的清單檔案。

清單檔案會描述用於訓練模型的影像。例如，指派給影像的影像位置和標籤。清單檔案由一或多個 JSON Lines 組成。每個 JSON Line 會描述單一影像。如需詳細資訊，請參閱[在資訊清單檔案中匯入影像層級標籤](md-create-manifest-file-classification.md)。

CSV 檔案代表文字檔案中多資料列的表格式資料。資料列中的欄位以逗號分隔。如需詳細資訊，請參閱[逗號分隔值](https://en.wikipedia.org/wiki/Comma-separated_values)。對於此指令碼，CSV 檔案中的每一資料列會代表單一影像，並對應至清單檔案中的 JSON Line。若要為支援[多標籤影像分類](getting-started.md#gs-multi-label-image-classification-example)的清單檔案建立 CSV 檔案，請在每一資料列新增一或多個影像層級標籤。若要建立適合 [Image classification](getting-started.md#gs-image-classification-example) 的清單檔案，請將單一影像層級標籤新增至每一資料列。

例如，下列 CSV 檔案描述 [多標籤影像分類](getting-started.md#gs-multi-label-image-classification-example) (Flowers) *入門*專案中的影像。

```
camellia1.jpg,camellia,with_leaves
camellia2.jpg,camellia,with_leaves
camellia3.jpg,camellia,without_leaves
helleborus1.jpg,helleborus,without_leaves,not_fully_grown
helleborus2.jpg,helleborus,with_leaves,fully_grown
helleborus3.jpg,helleborus,with_leaves,fully_grown
jonquil1.jpg,jonquil,with_leaves
jonquil2.jpg,jonquil,with_leaves
jonquil3.jpg,jonquil,with_leaves
jonquil4.jpg,jonquil,without_leaves
mauve_honey_myrtle1.jpg,mauve_honey_myrtle,without_leaves
mauve_honey_myrtle2.jpg,mauve_honey_myrtle,with_leaves
mauve_honey_myrtle3.jpg,mauve_honey_myrtle,with_leaves
mediterranean_spurge1.jpg,mediterranean_spurge,with_leaves
mediterranean_spurge2.jpg,mediterranean_spurge,without_leaves
```

該指令碼會為每一資料列產生 JSON Lines。例如，以下是第一資料列 (`camellia1.jpg,camellia,with_leaves`) 的 JSON Line。

```
{"source-ref": "s3://bucket/flowers/train/camellia1.jpg","camellia": 1,"camellia-metadata":{"confidence": 1,"job-name": "labeling-job/camellia","class-name": "camellia","human-annotated": "yes","creation-date": "2022-01-21T14:21:05","type": "groundtruth/image-classification"},"with_leaves": 1,"with_leaves-metadata":{"confidence": 1,"job-name": "labeling-job/with_leaves","class-name": "with_leaves","human-annotated": "yes","creation-date": "2022-01-21T14:21:05","type": "groundtruth/image-classification"}}
```

在 CSV 範例中，影像的 Amazon S3 路徑不存在。如果您的 CSV 檔案不包含影像的 Amazon S3 路徑，請使用 `--s3_path` 命令列引數指定影像的 Amazon S3 路徑。

指令碼會在已刪除重複影像的 CSV 檔案中記錄每個影像的第一個項目。已刪除重複影像的 CSV 檔案包含輸入 CSV 檔案中找到的每個影像的單一執行個體。輸入 CSV 檔案中影像的進一步出現次數會記錄在重複影像 CSV 檔案中。如果指令碼尋找重複影像，請檢閱重複影像的 CSV 檔案，並視需要更新已刪除重複影像的 CSV 檔案。使用已刪除重複資料的檔案重新執行指令碼。如果在輸入的 CSV 檔案中找不到重複項目，則指令碼會刪除已刪除重複影像的 CSV 檔案和重複影像的 CSV 檔案，因為它們是空白的。

 在此程序中，您可以建立 CSV 檔案並執行 Python 指令碼來建立清單檔案。

**從 CSV 檔案建立清單檔案**

1. 建立 CSV 檔案，每一資料列中包含以下欄位 (每個影像一個資料列)。請勿將標題資料列新增至 CSV 檔案。    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/rekognition/latest/customlabels-dg/ex-csv-manifest.html)

   例如：`camellia1.jpg,camellia,with_leaves` 或 `s3://my-bucket/flowers/train/camellia1.jpg,camellia,with_leaves` 

1. 儲存 CSV 檔案。

1. 執行下列 Python 指令碼。提供下列引數：
   + `csv_file` — 您在步驟 1 中建立的 CSV 檔案。
   + `manifest_file` — 您要建立的清單檔案的名稱。
   + (選用) `--s3_path s3://path_to_folder/` — 要新增至影像檔案名稱的 Amazon S3 路徑 (欄位 1)。如果欄位 1 中的影像尚未包含 S3 路徑，請使用 `--s3_path`。

   ```
   # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
   # SPDX-License-Identifier:  Apache-2.0
   
   from datetime import datetime, timezone
   import argparse
   import logging
   import csv
   import os
   import json
   
   """
   Purpose
   Amazon Rekognition Custom Labels model example used in the service documentation.
   Shows how to create an image-level (classification) manifest file from a CSV file.
   You can specify multiple image level labels per image.
   CSV file format is
   image,label,label,..
   If necessary, use the bucket argument to specify the S3 bucket folder for the images.
   https://docs.aws.amazon.com/rekognition/latest/customlabels-dg/md-gt-cl-transform.html
   """
   
   logger = logging.getLogger(__name__)
   
   
   def check_duplicates(csv_file, deduplicated_file, duplicates_file):
       """
       Checks for duplicate images in a CSV file. If duplicate images
       are found, deduplicated_file is the deduplicated CSV file - only the first
       occurence of a duplicate is recorded. Other duplicates are recorded in duplicates_file.
       :param csv_file: The source CSV file.
       :param deduplicated_file: The deduplicated CSV file to create. If no duplicates are found
       this file is removed.
       :param duplicates_file: The duplicate images CSV file to create. If no duplicates are found
       this file is removed.
       :return: True if duplicates are found, otherwise false.
       """
   
       logger.info("Deduplicating %s", csv_file)
   
       duplicates_found = False
   
       # Find duplicates.
       with open(csv_file, 'r', newline='', encoding="UTF-8") as f,\
               open(deduplicated_file, 'w', encoding="UTF-8") as dedup,\
               open(duplicates_file, 'w', encoding="UTF-8") as duplicates:
   
           reader = csv.reader(f, delimiter=',')
           dedup_writer = csv.writer(dedup)
           duplicates_writer = csv.writer(duplicates)
   
           entries = set()
           for row in reader:
               # Skip empty lines.
               if not ''.join(row).strip():
                   continue
   
               key = row[0]
               if key not in entries:
                   dedup_writer.writerow(row)
                   entries.add(key)
               else:
                   duplicates_writer.writerow(row)
                   duplicates_found = True
   
       if duplicates_found:
           logger.info("Duplicates found check %s", duplicates_file)
   
       else:
           os.remove(duplicates_file)
           os.remove(deduplicated_file)
   
       return duplicates_found
   
   
   def create_manifest_file(csv_file, manifest_file, s3_path):
       """
       Reads a CSV file and creates a Custom Labels classification manifest file.
       :param csv_file: The source CSV file.
       :param manifest_file: The name of the manifest file to create.
       :param s3_path: The S3 path to the folder that contains the images.
       """
       logger.info("Processing CSV file %s", csv_file)
   
       image_count = 0
       label_count = 0
   
       with open(csv_file, newline='', encoding="UTF-8") as csvfile,\
               open(manifest_file, "w", encoding="UTF-8") as output_file:
   
           image_classifications = csv.reader(
               csvfile, delimiter=',', quotechar='|')
   
           # Process each row (image) in CSV file.
           for row in image_classifications:
               source_ref = str(s3_path)+row[0]
   
               image_count += 1
   
               # Create JSON for image source ref.
               json_line = {}
               json_line['source-ref'] = source_ref
   
               # Process each image level label.
               for index in range(1, len(row)):
                   image_level_label = row[index]
   
                   # Skip empty columns.
                   if image_level_label == '':
                       continue
                   label_count += 1
   
                  # Create the JSON line metadata.
                   json_line[image_level_label] = 1
                   metadata = {}
                   metadata['confidence'] = 1
                   metadata['job-name'] = 'labeling-job/' + image_level_label
                   metadata['class-name'] = image_level_label
                   metadata['human-annotated'] = "yes"
                   metadata['creation-date'] = \
                       datetime.now(timezone.utc).strftime('%Y-%m-%dT%H:%M:%S.%f')
                   metadata['type'] = "groundtruth/image-classification"
   
                   json_line[f'{image_level_label}-metadata'] = metadata
   
                   # Write the image JSON Line.
               output_file.write(json.dumps(json_line))
               output_file.write('\n')
   
       output_file.close()
       logger.info("Finished creating manifest file %s\nImages: %s\nLabels: %s",
                   manifest_file, image_count, label_count)
   
       return image_count, label_count
   
   
   def add_arguments(parser):
       """
       Adds command line arguments to the parser.
       :param parser: The command line parser.
       """
   
       parser.add_argument(
           "csv_file", help="The CSV file that you want to process."
       )
   
       parser.add_argument(
           "--s3_path", help="The S3 bucket and folder path for the images."
           " If not supplied, column 1 is assumed to include the S3 path.", required=False
       )
   
   
   def main():
   
       logging.basicConfig(level=logging.INFO,
                           format="%(levelname)s: %(message)s")
   
       try:
   
           # Get command line arguments
           parser = argparse.ArgumentParser(usage=argparse.SUPPRESS)
           add_arguments(parser)
           args = parser.parse_args()
   
           s3_path = args.s3_path
           if s3_path is None:
               s3_path = ''
   
           # Create file names.
           csv_file = args.csv_file
           file_name = os.path.splitext(csv_file)[0]
           manifest_file = f'{file_name}.manifest'
           duplicates_file = f'{file_name}-duplicates.csv'
           deduplicated_file = f'{file_name}-deduplicated.csv'
   
           # Create manifest file, if there are no duplicate images.
           if check_duplicates(csv_file, deduplicated_file, duplicates_file):
               print(f"Duplicates found. Use {duplicates_file} to view duplicates "
                     f"and then update {deduplicated_file}. ")
               print(f"{deduplicated_file} contains the first occurence of a duplicate. "
                     "Update as necessary with the correct label information.")
               print(f"Re-run the script with {deduplicated_file}")
           else:
               print("No duplicates found. Creating manifest file.")
   
               image_count, label_count = create_manifest_file(csv_file,
                                                               manifest_file,
                                                               s3_path)
   
               print(f"Finished creating manifest file: {manifest_file} \n"
                     f"Images: {image_count}\nLabels: {label_count}")
   
       except FileNotFoundError as err:
           logger.exception("File not found: %s", err)
           print(f"File not found: {err}. Check your input CSV file.")
   
   
   if __name__ == "__main__":
       main()
   ```

1. 如果您打算使用測試資料集，請重複步驟 1 至 3，為測試資料集建立清單檔案。

1. 如有必要，請將影像複製到您在 CSV 檔案的資料欄 1 中指定的 Amazon S3 儲存貯體路徑 (或在 `--s3_path` 命令列中指定)。您可以使用下列 AWS S3 命令。

   ```
   aws s3 cp --recursive your-local-folder s3://your-target-S3-location
   ```

1. [將清單檔案上傳](https://docs.aws.amazon.com/AmazonS3/latest/userguide/upload-objects.html)到您要用於存放清單檔案的 Amazon S3 儲存貯體。
**注意**  
請確保 Amazon Rekognition 自訂標籤可存取清單檔案 JSON Lines 的 `source-ref` 欄位中參考的 Amazon S3 儲存貯體。如需詳細資訊，請參閱[存取外部 Amazon S3 儲存貯體](su-console-policy.md#su-external-buckets)。如果您的 Ground Truth 任務將影像存放在 Amazon Rekognition 自訂標籤主控台儲存貯體中，則不需要新增權限。

1. 請遵循 [使用 SageMaker AI Ground Truth 資訊清單檔案 （主控台） 建立資料集](md-create-dataset-ground-truth.md#md-create-dataset-ground-truth-console) 中的指示，使用上傳的資訊清單檔案建立資料集。對於步驟 8，請在 **.manifest 檔案位置**，輸入清單檔案位置的 Amazon S3 URL。如果您使用 AWS SDK，請執行 [使用 SageMaker AI Ground Truth 資訊清單檔案 (SDK) 建立資料集](md-create-dataset-ground-truth.md#md-create-dataset-ground-truth-sdk)。