# 画像データセットを作成する

画像データセットを作成して共有するには、2つの方法があります。このガイドでは、次の方法について説明します。

* Create an image dataset from local files in python with [Dataset.push_to_hub()](/docs/datasets/v5.2.0/ja/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/ja/package_reference/loading_methods#datasets.load_dataset)で直接読み込むことができます:

```py
>>> from datasets import load_dataset

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

これは、[load_dataset()](/docs/datasets/v5.2.0/ja/package_reference/loading_methods#datasets.load_dataset) で `imagefolder` を手動で渡し、`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/ja/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/ja/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アーカイブにグループ化（例：1つの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を読み込むと、ファイルの拡張子ごとに1列ずつ作成されます（ここでは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]}
```

1つの例に対して複数の画像を持つことも可能です。その場合、以下のようにします。

```
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テーブルでは、テキストやスカラー値だけでなく、画像、音声、動画などの大きなバイナリオブジェクト（blob）も、タブラーデータと並んでネイティブに保存できます。

ディスク上の画像ファイルと関連するメタデータ（キャプションや寸法など）を起点として、ローカルの`*.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)を参照してください。

