# 이미지 데이터셋 만들기

이미지 데이터셋을 생성하고 공유하는 방법은 두 가지가 있습니다. 이 가이드에서는 다음을 보여 드립니다:

* Create an image dataset from local files in python with [Dataset.push_to_hub()](/docs/datasets/v5.2.0/ko/package_reference/main_classes#datasets.Dataset.push_to_hub). This is an easy way that requires only a few steps in python.

* `ImageFolder`와 일부 메타데이터를 사용하여 이미지 데이터셋을 생성합니다. 이는 수천 장의 이미지로 구성된 이미지 데이터셋을 빠르게 생성하기 위한 노코드 솔루션입니다.

> [!TIP]
> 사용자가 먼저 연락처 정보를 공유하도록 요구하여 데이터셋에 대한 액세스를 제어할 수 있습니다. Hub에서 이 기능을 활성화하는 방법에 대한 자세한 내용은 [Gated datasets](https://huggingface.co/docs/hub/datasets-gated) 가이드를 참고하세요.

## ImageFolder

`ImageFolder`는 수천 장의 이미지로 구성된 이미지 데이터셋을 코드를 작성하지 않고도 빠르게 로드하도록 설계된 데이터셋 빌더입니다.

> [!TIP]
> 💡 `ImageFolder`가 데이터셋 저장소 구조를 기반으로 데이터셋 분할을 생성하는 방법에 대해 자세히 알아보려면 [Split pattern hierarchy](repository_structure#split-pattern-hierarchy)를 확인해 보세요.

`ImageFolder`는 디렉터리 이름을 기반으로 데이터셋의 클래스 라벨을 자동으로 추론합니다. 데이터셋을 다음과 같은 디렉터리 구조로 저장하세요:

```
folder/train/dog/golden_retriever.png
folder/train/dog/german_shepherd.png
folder/train/dog/chihuahua.png

folder/train/cat/maine_coon.png
folder/train/cat/bengal.png
folder/train/cat/birman.png
```

데이터셋이 `ImageFolder` 구조를 따르는 경우, [load_dataset()](/docs/datasets/v5.2.0/ko/package_reference/loading_methods#datasets.load_dataset)를 사용하여 직접 로드할 수 있습니다:

```py
>>> from datasets import load_dataset

>>> dataset = load_dataset("path/to/folder")
```

`imagefolder`를 [load_dataset()](/docs/datasets/v5.2.0/ko/package_reference/loading_methods#datasets.load_dataset)에 수동으로 전달하고 `data_dir`에 디렉터리를 지정하는 것과 동일합니다:

```py
>>> dataset = load_dataset("imagefolder", data_dir="/path/to/folder")
```

`imagefolder`를 사용하여 여러 스플릿을 포함하는 데이터셋을 로드할 수도 있습니다. 이를 위해 데이터셋 디렉토리는 다음 구조를 가져야 합니다:

```
folder/train/dog/golden_retriever.png
folder/train/cat/maine_coon.png
folder/test/dog/german_shepherd.png
folder/test/cat/bengal.png
```

> [!WARNING]
> 모든 이미지 파일이 단일 디렉토리에 포함되어 있거나 동일한 디렉토리 구조 레벨에 있지 않은 경우, `label` 열이 자동으로 추가되지 않습니다. 이 열이 필요한 경우 `drop_labels=False`를 명시적으로 설정하세요.

데이터셋에 텍스트 캡션이나 바운딩 박스처럼 포함하고 싶은 추가 정보가 있다면, 폴더에 `metadata.csv` 파일로 추가하세요. 이를 통해 텍스트 캡션이나 객체 탐지와 같은 다양한 컴퓨터 비전 작업용 데이터셋을 빠르게 만들 수 있습니다. JSONL 파일 `metadata.jsonl` 또는 Parquet 파일 `metadata.parquet`도 사용할 수 있습니다.

```
folder/train/metadata.csv
folder/train/0001.png
folder/train/0002.png
folder/train/0003.png
```

이미지를 zip 파일로 압축하여 사용할 수도 있으며, 이 경우 각 zip 파일에는 이미지와 메타데이터가 모두 포함되어야 합니다

```
folder/train.zip
folder/test.zip
folder/validation.zip
```

`metadata.csv` 파일에는 이미지 파일과 메타데이터를 연결하는 `file_name` 또는 `*_file_name` 필드가 있어야 합니다:

```csv
file_name,additional_feature
0001.png,This is a first value of a text feature you added to your images
0002.png,This is a second value of a text feature you added to your images
0003.png,This is a third value of a text feature you added to your images
```

또는 `metadata.jsonl`을(를) 사용하여:

```jsonl
{"file_name": "0001.png", "additional_feature": "This is a first value of a text feature you added to your images"}
{"file_name": "0002.png", "additional_feature": "This is a second value of a text feature you added to your images"}
{"file_name": "0003.png", "additional_feature": "This is a third value of a text feature you added to your images"}
```

여기서 `file_name`은 메타데이터 파일 옆에 있는 이미지 파일의 이름이어야 합니다. 더 일반적으로, 메타데이터가 포함된 디렉터리에서 이미지 파일까지의 상대 경로여야 합니다.

데이터셋의 각 행에 두 개 이상의 이미지를 지정할 수 있습니다. 예를 들어 입력과 출력 모두 이미지의 경우:

```jsonl
{"input_file_name": "0001.png", "output_file_name": "0001_output.png"}
{"input_file_name": "0002.png", "output_file_name": "0002_output.png"}
{"input_file_name": "0003.png", "output_file_name": "0003_output.png"}
```

이미지 목록을 정의할 수도 있습니다. 이 경우 필드 이름을 `file_names` 또는 `*_file_names`으로 지정해야 합니다. 예시는 다음과 같습니다:

```jsonl
{"frames_file_names": ["0001_t0.png", "0001_t1.png"], label: "moving_up"}
{"frames_file_names": ["0002_t0.png", "0002_t1.png"], label: "moving_down"}
{"frames_file_names": ["0003_t0.png", "0003_t1.png"], label: "moving_right"}
```

### 이미지 캡셔닝

이미지 캡셔닝 데이터셋에는 이미지를 설명하는 텍스트가 포함되어 있습니다. `metadata.csv`의 예시는 다음과 같습니다:

```csv
file_name,text
0001.png,This is a golden retriever playing with a ball
0002.png,A german shepherd
0003.png,One chihuahua
```

`ImageFolder`로 데이터셋을 로드하면 이미지 캡션을 위한 `text` 열이 생성됩니다:

```py
>>> dataset = load_dataset("imagefolder", data_dir="/path/to/folder", split="train")
>>> dataset[0]["text"]
"This is a golden retriever playing with a ball"
```

### 객체 감지

객체 감지 데이터셋에는 이미지 내 객체를 식별하는 바운딩 박스와 범주가 있습니다. `metadata.jsonl`의 예시는 다음과 같습니다:

```jsonl
{"file_name": "0001.png", "objects": {"bbox": [[302.0, 109.0, 73.0, 52.0]], "categories": [0]}}
{"file_name": "0002.png", "objects": {"bbox": [[810.0, 100.0, 57.0, 28.0]], "categories": [1]}}
{"file_name": "0003.png", "objects": {"bbox": [[160.0, 31.0, 248.0, 616.0], [741.0, 68.0, 202.0, 401.0]], "categories": [2, 2]}}
```

`ImageFolder`로 데이터셋을 로드하면, 바운딩 박스와 카테고리를 포함하는 `objects` 열이 생성됩니다:

```py
>>> dataset = load_dataset("imagefolder", data_dir="/path/to/folder", split="train")
>>> dataset[0]["objects"]
{"bbox": [[302.0, 109.0, 73.0, 52.0]], "categories": [0]}
```

### Hub에 데이터셋 업로드

데이터셋을 생성한 후에는 [push_to_hub()](/docs/datasets/v5.2.0/ko/package_reference/main_classes#datasets.DatasetDict.push_to_hub) 메서드를 사용하여 Hub에 공유할 수 있습니다. [huggingface_hub](https://huggingface.co/docs/huggingface_hub/index) 라이브러리가 설치되어 있고 Hugging Face 계정에 로그인되어 있는지 확인하세요(자세한 내용은 [Python으로 업로드하기 튜토리얼](upload_dataset#upload-with-python)을 참조하세요).

[push_to_hub()](/docs/datasets/v5.2.0/ko/package_reference/main_classes#datasets.DatasetDict.push_to_hub)로 데이터셋을 업로드하세요:

```py
>>> from datasets import load_dataset

>>> dataset = load_dataset("imagefolder", data_dir="/path/to/folder", split="train")
>>> dataset.push_to_hub("stevhliu/my-image-captioning-dataset")
```

## WebDataset

[WebDataset](https://github.com/webdataset/webdataset) 형식은 TAR 아카이브를 기반으로 하며 대규모 이미지 데이터셋에 적합합니다. 실제로 이미지를 TAR 아카이브(예: TAR 아카이브당 1GB의 이미지)로 묶고 수천 개의 TAR 아카이브를 사용할 수 있습니다:

```
folder/train/00000.tar
folder/train/00001.tar
folder/train/00002.tar
...
```

아카이브에서 각 예제는 동일한 접두사를 공유하는 파일들로 구성됩니다:

```
e39871fd9fd74f55.jpg
e39871fd9fd74f55.json
f18b91585c4d3f3e.jpg
f18b91585c4d3f3e.json
ede6e66b2fb59aab.jpg
ede6e66b2fb59aab.json
ed600d57fcee4f94.jpg
ed600d57fcee4f94.json
...
```

이미지 라벨/캡션/바운딩 박스를 JSON 또는 텍스트 파일에 담아 사용할 수 있습니다.

WebDataset를 로드하면 파일 확장자(여기서는 "jpg"와 "json")별로 컬럼이 하나씩 생성됩니다:

```python
>>> from datasets import load_dataset

>>> dataset = load_dataset("webdataset", data_dir="/path/to/folder", split="train")
>>> dataset[0]["json"]
{"bbox": [[302.0, 109.0, 73.0, 52.0]], "categories": [0]}
```

이처럼 각 예시당 여러 이미지를 가질 수도 있습니다:

```
e39871fd9fd74f55.input.jpg
e39871fd9fd74f55.output.jpg
e39871fd9fd74f55.json
f18b91585c4d3f3e.input.jpg
f18b91585c4d3f3e.output.jpg
f18b91585c4d3f3e.json
...
```

WebDataset 형식과 python 라이브러리에 대한 자세한 내용은 [WebDataset 문서](https://webdataset.github.io/webdataset)를 참고하세요.

## Lance

[Lance](https://lance.org)는 오픈 멀티모달 레이크하우스 테이블 형식입니다. Lance 테이블은 텍스트와 스칼라 값뿐만 아니라 이미지, 오디오, 비디오와 같은 대형 바이너리 객체(blobs)도 테이블 데이터와 함께 네이티브로 저장할 수 있습니다.

디스크에 있는 이미지 파일과 관련 메타데이터(예: 캡션 및 차원)를 기반으로, 자체적으로 완결된 Lance 데이터셋을 로컬 `*.lance` 디렉토리에 작성할 수 있습니다. 생성된 테이블에는 인코딩된 이미지 바이트를 포함하는 `image` 컬럼과 함께 메타데이터 컬럼을 저장할 수 있습니다.

예를 들어, 다음과 같은 메타데이터로 시작할 수 있습니다:

```text
{'caption': 'Cordelia and Dudley on their wedding  day last year', 'height': 315, 'width': 233}
{'caption': 'Statistics on challenges for automation in 2021', 'height': 299, 'width': 701}
```

메타데이터와 이미지 바이트에 대한 `pyarrow` 스키마를 정의하고, 테이블을 빌드한 후 Lance 데이터셋으로 작성할 수 있습니다:

```python
import lance
import pyarrow as pa

schema = pa.schema(
    [
        pa.field("caption", pa.utf8()),
        pa.field("height", pa.int32()),
        pa.field("width", pa.int32()),
        # ... add any additional metadata columns you want here ...
        pa.field("image", pa.binary()),
    ]
)

# Provide image files alongside metadata
rows = [
    {
        "image_path": "/path/to/images/0001.jpg",
        "caption": "Cordelia and Dudley on their wedding  day last year",
        "height": 315,
        "width": 233,
    },
    {
        "image_path": "/path/to/images/0002.jpg",
        "caption": "Statistics on challenges for automation in 2021",
        "height": 299,
        "width": 701,
    },
]

image_bytes = []
for r in rows:
    with open(r["image_path"], "rb") as f:
        image_bytes.append(f.read())

table = pa.table(
    {
        "caption": [r["caption"] for r in rows],
        "height": [r["height"] for r in rows],
        "width": [r["width"] for r in rows],
        "image": image_bytes,
    },
    schema=schema,
)

ds = lance.write_dataset(
    table,
    "./images.lance",
    schema=schema,
    mode="create",
)
```

이미지를 저장하는 Lance 테이블의 대표적인 예시는 다음과 같습니다(`image` 열에는 인코딩된 바이트가 포함됨):

```text
+-----------------------------------------------+--------+-------+-----+------------------------------+
| caption                                       | height | width | ... | image                        |
+-----------------------------------------------+--------+-------+-----+------------------------------+
| "Cordelia and Dudley on their wedding ..."    | 315    | 233   | ... | b"\\xff\\xd8\\xff...\\xd9"   |
| "Statistics on challenges for automation ..." | 299    | 701   | ... | b"\\xff\\xd8\\xff...\\xd9"   |
+-----------------------------------------------+--------+-------+-----+------------------------------+
```

이 접근 방식을 사용하면 임의로 큰 이미지 데이터셋을 Lance에 저장할 수 있습니다. 생성된 `images.lance/` 디렉터리와 그 안의 `*.lance` 파일은 위의 다른 예시와 마찬가지로 Hugging Face Hub에 업로드할 수 있습니다. Lance 이미지 데이터셋의 예로는 `lance-format/laion-1m` [Hub 데이터셋](https://huggingface.co/datasets/lance-format/laion-1m)을 참고하세요.

Lance 데이터셋을 다루는 방법에 대한 자세한 내용은 [Lance 문서](https://lance.org)를 참고하세요.

