Hugging Face Hubにdatasetを作る方法


この記事では、自前のデータをどうやってHuggingface上にアップロードする方法を調べる。

<編集中>(;´･ω･)翻訳できてないとこたくさんある...

<動機>
英語に対して耐性がなく、基本的に逃げ癖が付いてしまっているので、ENGLISHで書かれた記事を目にするとどうにも読みたくなくなる。それでも、一から翻訳するとなれば腰を落ち着けて記事が読めるかもしれない。それで、外国語が得意な方から見るとあほらしいかもしれないが、とりあえず適当に一文ずつ訳していくことにした。

具体的には以下の記事を読んでいくが、方法だけ知りたい人は[手順目次](###手順目次)へGO

https://huggingface.co/docs/datasets/share#create-the-repository

https://huggingface.co/docs/hub/datasets-cards

https://huggingface.co/docs/datasets/image_dataset



# Share a dataset using the CLI
> At Hugging Face, we are on a mission to democratize good Machine Learning and we believe in the value of open source. That’s why we designed 🤗 Datasets so that anyone can share a dataset with the greater ML community. There are currently thousands of datasets in over 100 languages in the Hugging Face Hub, and the Hugging Face team always welcomes new contributions!


Huggingfaceでは、よい機械学習を民主化（みんなが使えるように）することを使命とし、オープンソース化することの価値を信じています。それが私たちがHugging Face Datasetsを設計した理由であり、誰もがデータセットをよりよい機械学習コミュニティーに共有することができます。 現在までにHuggingface Hubには100を超える言語で何千ものデータセットが存在し、HuggingFaceチームは常に新しい貢献を歓迎いたします。

> Dataset repositories offer features such as:
> - Free dataset hosting
> - Dataset versioning
> - Commit history and diffs
> - Metadata for discoverability
> - Dataset cards for documentation, licensing, limitations, etc.
> This guide will show you how to share a dataset that can be easily accessed by anyone.

データセットリポジトリは次のような特徴を提供します
- フリーデータセットホスティング
- データセットのバージョン管理
- 履歴と差分表示
- より分かりやすくするための？メタデータ
- 文書化、ライセンス管理、利用制限のためのデータセットカード
このガイドで、どのように（誰でも簡単にアクセスできる）データセットを共有すればよいかを示します。

## Add a dataset
> You can share your dataset with the community with a dataset repository on the Hugging Face Hub. It can also be a private dataset if you want to control who has access to it.
In a dataset repository, you can either host all your data files and configure your dataset to define which file goes to which split. The following formats: CSV, TSV, JSON, JSON lines, text, Parquet, Arrow, SQLite. The script also supports many kinds of compressed file types such as: GZ, BZ2, LZ4, LZMA or ZSTD. For example, your dataset can be made of .json.gz files.

データセットを共有することもできますが、あなたが望めばそれを秘匿することもできます。データセットリポジトリでは、どのファイルをどのように分割するか、自分で設定することもできます。次のフォーマット（CSV, TSV, JSON, JSON lines, text, Parquet, Arrow, SQLite）や、圧縮ファイル（GZ, BZ2, LZ4, LZMA, ZSTD）などのファイル形式もサポートしています。例えば、自分で使うデータセットは.json.gzファイルとして作成することができます。

> On the other hand, if your dataset is not in a supported format or if you want more control over how your dataset is loaded, you can write your own dataset script.
When loading a dataset from the Hub, all the files in the supported formats are loaded, following the repository structure. However if there’s a dataset script, it is downloaded and executed to download and prepare the dataset instead.
For more information on how to load a dataset from the Hub, take a look at the load a dataset from the Hub tutorial.

一方、アップロードしたいデータセットがその形式に従っていない場合、自分でデータセットスクリプトを書く必要があります。
HuggingFace Hubからデータセットがロードされたとき、リポジトリの構成に従ってサポートされた形式のすべてのファイルがロードされます。しかし、そこにデータセットのスクリプトが存在するとき、データセットのスクリプトファイルがダウンロード&データのダウンロードと前処理が実行されます。
HuggingFaceHubからデータをロードする方法の詳細は、HuggingFaceHubのチュートリアル<a href = "https://huggingface.co/docs/datasets/load_hub">"load a dataset from the Hub"</a>を見てね。

### 手順目次
1. Create the repository 
2. Prepare your files
2. Upload your files
2. (Optional) Add the dataset loading script
2. Verify the files have been correctly staged. Then you can commit and push your files
2. Ask for a help and reviews

### Create the repository
> Sharing a community dataset will require you to create an account on hf.co if you don’t have one yet. You can directly create a new dataset repository from your account on the Hugging Face Hub, but this guide will show you how to upload a dataset from the terminal.

もしHuggingface Hubのアカウントを持っていければ、コミュニティーにデータセットを共有(アップロード)する際には必要なので作っておいてください。
Hugging Face Hub上の自分のアカウントを使用して、直接新しいデータセットリポジトリを作ることもできますが、ここではパソコンのターミナルからデータセットをアップロードする方法を見ていきましょう。

> Make sure you are in the virtual environment where you installed Datasets, and run the following command:
``` huggingface-cli login ```
Login using your Hugging Face Hub credentials, and create a new dataset repository:
``` huggingface-cli repo create your_dataset_name --type dataset```

データセットをインストールした仮想環境を起動していることを確認し、次のコマンドを実行して下さい。

```!huggingface-cli login ```

Hugging Face Hubの認証システムを利用してログインし、新しいデータセットリポジトリを作成してください。

``` !huggingface-cli repo create データセット名 --type dataset ```


> Add the -organization flag to create a repository under a specific organization:
``` huggingface-cli repo create データセット名 --type dataset --organization 組織名 ```

特定の組織（グループ？）に紐づけてリポジトリを作成する場合は、```-organization``` のフラグ（引数）を設定して実行して下さい。

### Clone the repository
リポジトリのクローン方法
> Install Git LFS and clone your repository:

<a href="https://git-lfs.com/">Git Large File Storage</a>をインストールしてね。
``` 
# Make sure you have git-lfs installed
# (https://git-lfs.github.com/)
!git lfs install
!git clone https://huggingface.co/datasets/namespace/your_dataset_name
```
> Here the namespace is either your username or your organization name.

namespaceと書かれた場所はあなたのユーザネームか、組織名を入れてね。


#### Prepare your files
> Now is a good time to check your directory to ensure the only files you’re uploading are:
> - The data files of the dataset
> - The dataset card README.md
> - (optional) your_dataset_name.py is your dataset loading script (optional if your data files are already in the supported formats csv/jsonl/json/parquet/txt). To create a dataset script, see the dataset script page.

はじめに、ディレクトリにこれからuploadしようとしている以下のファイルしかないことを確認してください。
- データセットのデータファイル
- データセットカード(README.md)
- （option）your_dataset_name.py 
    ・・・データセットをロードするためのスクリプトファイル。データセットがcsv, jsonl, json, parquet, textなどのHugging Face Hubでサポートされた形式のファイルの場合は必要ない。
スクリプトファイルを作る方法：<a href="https://huggingface.co/docs/datasets/dataset_script">dataset_scripts</a>

#### Upload your files
> You can directly upload your files to your repository on the Hugging Face Hub, but this guide will show you how to upload the files from the terminal.
It is important to add the large data files first with git lfs track or else you will encounter an error later when you push your files:

今からターミナルの操作をしてHuggingface Hubのリポジトリへアップロードしていくよ。ちなみに、Git LFSで大規模データをaddしておかないと、のちのちエラー吐くます。ここテスト出るからね(*'▽')

```
cp /somewhere/data/*.json .
git lfs track *.json
git add .gitattributes
git add *.json
git commit -m "add json files"
```

#### (Optional) Add the dataset loading script:
（必要に応じて、loadingスクリプトもaddする。）
```
cp /somewhere/data/load_script.py .
git add --all
```

#### Verify the files have been correctly staged. Then you can commit and push your files:
正しくステージされたファイルを検証しし、コミット and プッシュ。

```
git status
git commit -m "First version of the your_dataset_name dataset."
git push
```


> Congratulations, your dataset has now been uploaded to the Hugging Face Hub where anyone can load it in a single line of code! 🥳
```
dataset = load_dataset("namespace/your_dataset_name")
```

これであなたのデータセットはHugging Face Hubにアップロードされ、誰もが一行でロードできるようになりました(^▽^)/おめでとう！
```
dataset = load_dataset("ユーザ名か組織名/データセット名")
```
>Finally, don’t forget to enrich the dataset card to document your dataset and make it discoverable! Check out the Create a dataset card guide to learn more.

最後に、データセットの内容を文書化するデータセットカードに豊富な説明を付けることを忘れないでください。
データセットカードの作成方法は<a href="https://huggingface.co/docs/datasets/dataset_card">ここ</a>を参照してね。



#### Ask for a help and reviews
> If you need help with a dataset script, feel free to check the datasets forum: it’s possible that someone had similar issues and shared how they managed to fix them.

もしデータセットのスクリプトについて助けが必要であれば、<a href="https://discuss.huggingface.co/c/datasets/10">datasets forum</a>に来てね。誰かがあなたと似たような問題に直面して、ほかの誰かがそれを解決しているかも。

> Then if your script is ready and if you wish your dataset script to be reviewed by the Hugging Face team, you can open a discussion in the Community tab of your dataset with this message:
```
# Dataset rewiew request for <Dataset name>
## Description

<brief description of the dataset>
## Files to review
- file1
- file2
- ...
cc
```
> Members of the Hugging Face team will be happy to review your dataset script and give you advice.

もしスクリプトが仕上がり、Hugging Face チームメンバーの誰かからの評価が欲しかったらデータセットページのコミュ二ティータブでDiscussionを開いて、次のメッセージを送ってね。
HuggingFaceチームメンバーはあなたのデータセットスクリプトのレビューとアドバイスができてうれしく思います:D

### Datasets on GitHub (legacy)
> Datasets used to be hosted on our GitHub repository, but all datasets have now been migrated to the Hugging Face Hub.
The legacy GitHub datasets were added originally on our GitHub repository and therefore don’t have a namespace on the Hub: “squad”, “glue”, etc. unlike the other datasets that are named “username/dataset_name” or “org/dataset_name”.

データセットはHugging FaceのGithubリポジトリへホストされてきましたが、現在ではすべてのデータセットはHuggingFace Hubへ移動しています。Githubで公開されていたデータセットはそもそもGithubリポジトリにあり、"squad"や"glue"といった感じで、"username/dataset_name"とか、"org/dataset_name"のような他のデータセットと同じ名前は持っていません。

> The distinction between a Hub dataset within or without a namespace only comes from the legacy sharing workflow. It does not involve any ranking, decisioning, or opinion regarding the contents of the dataset itself.

ネームスペース(データセット名のうち、usernameとかorgの部分)を持つデータセットと持たないデータセットの違いは、ワークフローを共有する遺産に由来します。

> Those datasets are now maintained on the Hub: if you think a fix is needed, please use their “Community” tab to open a discussion or create a Pull Request. The code of these datasets is reviewed by the Hugging Face team.

それらのデータセットは現在Hugging Face Hubで維持・管理されています。もし修正が必要であればそれぞれのデータセットのコミュニティータブでディスカッションを開くか、```create a pull request```を行ってください（Github上でってこと？かも）。これらのデータセットのコードはHugging Faceチームによってレビューされます。


# What are Dataset Cards?

> Each dataset may be documented by the README.md file in the repository. This file is called a dataset card, and the Hugging Face Hub will render its contents on the dataset’s main page. To inform users about how to responsibly use the data, it’s a good idea to include information about any potential biases within the dataset. Generally, dataset cards help users understand the contents of the dataset and give context for how the dataset should be used.

それぞれのデータセットは、README.mdファイルによってリポジトリ内で文書化されます。このファイルはデータセットカードと呼ばれ、HuggingFace Hubはこの内容をデータセットのメインページに描画します。ユーザに責任をもってデータを使う方法を知らせるには、データセット内に含まれるすべての潜在的なバイアスについての情報を含めるとよいでしょう。一般的には、データセットカードはユーザがデータセットの内容を理解するのを助け、ユーザにデータセットがどのように使用されるべきかについての文脈（説明）を与えてくれます。

> You can also add dataset metadata to your card. The metadata describes important information about a dataset such as its license, language, and size. It also contains tags to help users discover a dataset on the Hub. Tags are defined in a YAML metadata section at the top of the README.md file.

またデータセットカードにはメタデータを付与することができます。メタデータはデータセットに関するライセンスや言語、サイズについての情報を説明します。また、HuggingFace内の他のユーザに発見されやすくするためのタグも付与できます。タグはYAML形式のメタデータセクション（README.mdファイルのトップ）で定義できます。

## Dataset card metadata
> A dataset repo will render its README.md as a dataset card. To control how the Hub displays the card, you should create a YAML section in the README file to define some metadata. Start by adding three --- at the top, then include all of the relevant metadata, and close the section with another group of --- like the example below:

データセットリポジトリはREADME.mdファイルをデータセットカードとして描画します。Hubがカードを表示する方法をコントロールするには、READMEファイルにYAMLセクションを作成しましょう。まずは3つの```---```をREADME.mdファイルのトップに加えることから始め、次にすべての関連メタデータを書き、そしてセクションを以下のような他のグループの```---```で閉じましょう。

```
language: 
- "List of ISO 639-1 code for your language"
- lang1
- lang2
pretty_name: "Pretty Name of the Dataset"
tags:
- tag1
- tag2
license: "any valid license identifier"
task_categories:
- task1
- task2
```

> The metadata that you add to the dataset card enables certain interactions on the Hub. For example:
> - Allow users to filter and discover datasets at https://huggingface.co/datasets. 
> - If you choose a license using the keywords listed in the right column of this table, the license will be displayed on the dataset page.

データセットカードに加えられたメタデータはHub上である種の交流を可能にします。例えば、
- 他のユーザがhttps://huggingface.co/datasets. でフィルターを介してデータセットを見つけられるようにします
- もしこのページ(https://huggingface.co/docs/hub/repositories-licenses
)の右側のカラム(列)からライセンスのキーワードを選択すれば、ライセンス情報がデータセットページに表示されます。

> When creating a README.md file in a dataset repository on the Hub, use Metadata UI to fill the main metadata:

README.mdファイルがデータセットリポジトリ内に作られたら、Metadata UIを使用して主要なメタデータを埋めることもできます

> To see metadata fields, see the detailed dataset card metadata specification here.

メタデータのフィールドを見るには、データセットカード作成の詳細が書かれた<a href="https://github.com/huggingface/hub-docs/blob/main/datasetcard.md?plain=1">このGithubのページ</a>を確認してね

### Dataset card creation guide
> For a step-by-step guide on creating a dataset card, check out the Create a dataset card guide.

データセット作成の一つ一つのステップについては以下を参照。
（かなり短いけどちょっと読んでおきたいページなので、そのままここで翻訳する）

--------------------------------------------------------------------
https://huggingface.co/docs/datasets/dataset_card

#### Create a dataset card
> Each dataset should have a dataset card to promote responsible usage and inform users of any potential biases within the dataset. This idea was inspired by the Model Cards proposed by Mitchell, 2018. Dataset cards help users understand a dataset’s contents, the context for using the dataset, how it was created, and any other considerations a user should be aware of.

全てのデータセットは責任ある使い方とデータセットに含まれる潜在的なバイアスを説明するために、データセットカードを持つべきです。このアイデアは2018年にMitchellによる提案されたモデルデータカードにインスパイアされています。データセットカードはユーザのデータセットの内容の理解、データセットの使い方、どのようにそのデータセットが作成されたのか、などユーザが知るべき情報に対する理解を助けます。

> Creating a dataset card is easy and can be done in a just a few steps:
> 1. Go to your dataset repository on the Hub and click on Create Dataset Card to create a new README.md file in your repository.
> 1. Use the Metadata UI to select the tags that describe your dataset. You can add a license, language, pretty_name, the task_categories, size_categories, and any other tags that you think are relevant. These tags help users discover and find your dataset on the Hub.
（For a complete, but not required, set of tag options you can also look at the Dataset Card specifications. This’ll have a few more tag options like multilinguality and language_creators which are useful but not absolutely necessary.）
> 3. Click on the Import dataset card template link to automatically create a template with all the relevant fields to complete. Fill out the template sections to the best of your ability. Take a look at the Dataset Card Creation Guide for more detailed information about what to include in each section of the card. For fields you are unable to complete, you can write [More Information Needed].

データセットカードを作成するのは簡単で、たった数ステップです。
1. huggingface hubのデータセットリポジトリで、```Create Dataset Card```をクリックしてREADMEファイルをリポジトリ内に作成してね
1. メタデータUIを使ってタグをデータセットを説明する選択し、ライセンスや言語、pretty_name(?)、タスクカテゴリ、サイズカテゴリなどの関連タグをつけてね。これらのタグはほかのユーザが検索をかけた時、あなたのデータセットを見つけやすくします。
（別に必須ではないけど、データセットカードの仕様についてタグをつけられます。これは）
1. ```Import dataset card template```のリンクを押して自動的にすべての関連したフィールドを埋めるテンプレートを作成してね。できるだけテンプレートセクションを埋めましょう。詳しくは<a href="https://github.com/huggingface/datasets/blob/main/templates/README_guide.md">Dataset Card Creation Guide</a>を見てね。もし埋められないセクションがあれば、[More Information Needed]って書いておいてね。

> Once you’re done, commit the changes to the README.md file and you’ll see the completed dataset card on your repository.
YAML also allows you to customize the way your dataset is loaded by defining splits and/or configurations without the need to write any code.
Feel free to take a look at the SNLI, CNN/DailyMail, and Allociné dataset cards as examples to help you get started.

ここまで終わったら、READMEファイルの変更をコミットして完了。
リポジトリで完成したデータセットを見れるよ。YMALファイルを付けると、分割方法や設定をノーコードで定義することで、データセットのロード方法をカスタマイズできるよ。
具体的な例として、SNLI, CNN/DailyMail, and Allociné データセットカードをご参照ください。

--------------------------------------------------------------------
> Reading through existing dataset cards, such as the ELI5 dataset card, is a great way to familiarize yourself with the common conventions.

慣例に従うのであれば、ELI5データセットカードなどを参照するのが良いでしょう。

### Linking a Paper
（論文へのリンク貼り付け）
> If the dataset card includes a link to a paper on arXiv, the Hub will extract the arXiv ID and include it in the dataset tags with the format arxiv:<PAPER ID>. Clicking on the tag will let you:
> - Visit the Paper page
> - Filter for other models on the Hub that cite the same paper.

もしデータセットカードにアーカイブの論文へのリンクが含まれていれば、HuggingFace HubはアーカイブIDを実行してデータセットカードのタグに```arxiv:<ID>```のフォーマットで付与します。タグをクリックすると、次のような選択肢が現れます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3520514/57ac651a-5b3a-ed6d-2182-a88a27240506.png)

- 上が論文ページへのリンク
- 下が同じ論文からの引用があるHuggingFace内の他のモデルを検索するためのフィルタを実行するボタン

-----------------------------------------------------------------------

# Create an image dataset

* CSVファイルを作ってみたはいいけど、データセットは大量のCSVじゃ、ちょっと処理しきれないよ...(;´･ω･)
* ということで普通はどうやってデータセットを作るのかを見ていく。

https://huggingface.co/docs/datasets/image_dataset

> There are two methods for creating and sharing an image dataset. This guide will show you how to:
> - Create an image dataset with ImageFolder and some metadata. This is a no-code solution for quickly creating an image dataset with several thousand images.
> - Create an image dataset by writing a loading script. This method is a bit more involved, but you have greater flexibility over how a dataset is defined, downloaded, and generated which can be useful for more complex or large scale image datasets.
>> You can control access to your dataset by requiring users to share their contact information first. Check out the Gated datasets guide for more information about how to enable this feature on the Hub.


画像データセットを作成し共有するには、二つの方法があります。
1. ImageFolderとメタデータで画像データセットを作成する。この方法では、ノーコードで素早く何千もの画像データセットを作成します。
1. ローディングスクリプトを書いて画像データセットを作成します。この方法は少々複雑ですが、より複雑で大規模の画像データセットを定義・ダウンロード・生成する際により大きな柔軟性を持たせることができます。
>> ユーザに彼らのコンタクトを共有させるために

## ImageFolder
> The ImageFolder is a dataset builder designed to quickly load an image dataset with several thousand images without requiring you to write any code.
>> 💡 Take a look at the Split pattern hierarchy to learn more about how ImageFolder creates dataset splits based on your dataset repository structure.

https://huggingface.co/docs/datasets/repository_structure#split-pattern-hierarchy

ImageFolderは素早く何千もの画像を含むデータセットを、ノーコードでダウンロードするために設計された、データセットビルダーです。
ImageFolderがどのようにデータセットリポジトリの構造からデータセットの分割を行うのかを知りたければ、"Sturucture your repository"のページを参照してね。

> ImageFolder automatically infers the class labels of your dataset based on the directory name. Store your dataset in a directory structure like:

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
```
> Then users can load your dataset by specifying imagefolder in load_dataset() and the directory in data_dir:

そうすれば、ユーザはload_dataset()関数でimagefolderと、data_dirのディレクトリを特定すればデータセットをロードすることができます。

```python
from datasets import load_dataset

dataset = load_dataset("imagefolder", data_dir="/path/to/folder")
```
> You can also use imagefolder to load datasets involving multiple splits. To do so, your dataset directory should have the following structure:

また、複数の分割（mulyiple spilits...って、データが混ざっているってことかな？）を含むデータセットをダウンロードする際にも、ImageFolderを利用することができます。そのためには、データセットディレクトリは次のような構造である必要があります。

```
folder/train/dog/golden_retriever.png
folder/train/cat/maine_coon.png
folder/test/dog/german_shepherd.png
folder/test/cat/bengal.png
```
> If all image files are contained in a single directory or if they are not on the same level of directory structure, label column won’t be added automatically. If you need it, set drop_labels=False explicitly.

もしすべての画像ファイルが一つのディレクトリ内に存在するか、それらが同ディレクトリ階層にない場合は、ラベルの行は自動的に付与されません。もしラベル付けが必要であれば、引数drop_labelsをFalseに明示的に設定してください。

> If there is additional information you’d like to include about your dataset, like text captions or bounding boxes, add it as a metadata.csv file in your folder. This lets you quickly create datasets for different computer vision tasks like text captioning or object detection. You can also use a JSONL file metadata.jsonl.

もし追加したい情報（テキストの説明やバウンディングボックス）があれば、それをメタデータ（フォルダのCSVファイル）に加えてください。これにより、ほかのコンピュータビジョンタスク（テキスト説明タスク、物体検知など）のためのデータセットをすばやく作成することができます。また、JSONLファイル（metadata.jsonl）を使うこともできます。

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

> You can also zip your images:

画像をzipファイルとして保存してもOK。
```
folder/metadata.csv
folder/train.zip
folder/test.zip
folder/valid.zip
```
> Your metadata.csv file must have a file_name column which links image files with their metadata:

メタデータ.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
```

> or using metadata.jsonl:
それか、metadata.jsonlを使ってもOK

```
{"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"}
```
>> If metadata files are present, the inferred labels based on the directory name are dropped by default. To include those labels, set drop_labels=False in load_dataset.

もしメタデータファイルが存在すれば、デフォルトでディレクトリの名前から推論されたラベルは落ちる（データに付与されません）。したがって、もしデータに推論されたラベルを付与したい場合はload_dataset関数の引数drop_labelsをFalseに設定して下さい。


------------------------------------------------------------------
### <font color="#ffe6ff">自分用メモ</font>

ってことは、ディレクトリ構造は
```
folder/train/metadata.csv
folder/train/0001.png
folder/train/0002.png
folder/train/0003.png
```
って感じで、CSVファイルの中は
```
file_name,additional_feature
0001.png,beautiful classic music
0002.png, beathoven
0003.png,Mozalt
```
みたいな感じにすればいいってこと？それか、メタデータはCSVファイルじゃなくてjsonファイルにして、
```
{"file_name": "0001.png", "caption": "beautiful classic music"}
{"file_name": "0002.png", "caption": "Beathoven"}
{"file_name": "0003.png", "additional_feature": Mozalt"}
```
と書く...ってこれはプログラムで処理しないといけないやつね。
って、下になんか例が載ってた(;´･ω･)

-----------------------------------------------------------------

### Image captioning
> Image captioning datasets have text describing an image. An example metadata.csv may look like:
画像説明データセットは画像を説明するテキストです。メタデータCSVファイルは、次のような形式で書くとよいでしょう。

```
file_name,text
0001.png,This is a golden retriever playing with a ball
0002.png,A german shepherd
0003.png,One chihuahua
```
> Load the dataset with ImageFolder, and it will create a text column for the image captions:
ImageFolderでデータセットをロードすると、ImageFolderは次のようなテキストカラムを生成します。

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

### Upload dataset to the Hub
> Once you’ve created a dataset, you can share it to the Hub with the push_to_hub() method. Make sure you have the huggingface_hub library installed and you’re logged in to your Hugging Face account (see the Upload with Python tutorial for more details).

データセットを作り終わったら、これをpush_to_hub()関数を使ってHubへpushできます。huggingface_hubライブラリがインストールされ、Huggingface アカウントにログインしていることを確認してね。
（詳細は<a href="https://huggingface.co/docs/datasets/upload_dataset#upload-with-python">Upload with Pyhton チュートリアル</a>を見てね。）

> Upload your dataset with push_to_hub():
```
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")
```

## Loading Script
> Write a dataset loading script to share a dataset. It defines a dataset’s splits and configurations, and handles downloading and generating a dataset. The script is located in the same folder or repository as the dataset and should have the same name.
データセットを共有するためのローディングスクリプトを書いていきます。データセットの分割や設定を定義し、ダウンロードやデータセットの生成を扱います。スクリプトはデータセットと同じフォルダ、或いはリポジトリ内にあり、データセットと同じ名前である必要があります。
```
my_dataset/
├── README.md
├── my_dataset.py
└── data/  # optional, may contain your images or TAR archives
```
> This structure allows your dataset to be loaded in one line:
この構造により、データセットを一行のコードでダウンロードできます。
```
from datasets import load_dataset
dataset = load_dataset("path/to/my_dataset")
```
> This guide will show you how to create a dataset loading script for image datasets, which is a bit different from creating a loading script for text datasets. You’ll learn how to:
> - Create a dataset builder class.
> - Create dataset configurations.
> - Add dataset metadata.
> - Download and define the dataset splits.
> - Generate the dataset.
> - Generate the dataset metadata (optional).
> - Upload the dataset to the Hub.
> The best way to learn is to open up an existing image dataset loading script, like Food-101, and follow along!
To help you get started, we created a loading script template you can copy and use as a starting point!

このガイドでは、テキストデータセットを生成するのとは少し異なる、画像データセットのためのローディングスクリプトを生成する方法を紹介します。
方法手順は以下の通りです。
- データセットビルダクラスを生成する
- データセットのメタデータを加える
- データセットのダウンロードし、データの分割を定義。
- データセットを生成する
- （必要があれば）データセットのメタデータを生成する
- Huggingface Hubにデータセットをアップロードする
最も良い学習方法は、既に存在している画像データセット<a herf="https://huggingface.co/datasets/food101/blob/main/food101.py">food101.py</a>を参考にして作ってみることです！また、<a href="https://github.com/huggingface/datasets/blob/main/templates/new_dataset_script.py">テンプレートのローディングスクリプト</a>もあります。


### Create a dataset builder class
> GeneratorBasedBuilder is the base class for datasets generated from a dictionary generator. Within this class, there are three methods to help create your dataset:
> - info stores information about your dataset like its description, license, and features.
> - split_generators downloads the dataset and defines its splits.
> - generate_examples generates the images and labels for each split.


GeneratorBasedBuilder は辞書型生成器から生成されたデータセットのための基本となるクラスです。このクラスでは、データセットを生成する3つの方法があります。
- info（クラスの前のコード部分）では、データセットの説明やライセンス、特徴などデータセットに関する情報を保存します
- split_generators（クラスの中身メソッド）はデータセットをダウンロードし、分割方法を定義します。
- generate_examples（クラスの中身メソッド）は分割されたデータに対して、それぞれ画像とラベルを生成します。

> Start by creating your dataset class as a subclass of GeneratorBasedBuilder and add the three methods. Don’t worry about filling in each of these methods yet, you’ll develop those over the next few sections:

まずはあなたのデータセットクラスをGeneratorBasedBuilderクラスの継承クラスとして生成します。メソッドすべてを埋める必要はないので、心配しないくださいね。次の数セクションでそれらをご説明します。
```
class Food101(datasets.GeneratorBasedBuilder):
    """Food-101 Images dataset"""

    def _info(self):

    def _split_generators(self, dl_manager):

    def _generate_examples(self, images, metadata_path):
```

### Multiple configurations
> In some cases, a dataset may have more than one configuration. For example, if you check out the Imagenette dataset, you’ll notice there are three subsets.

場合によっては、データセットは一つ以上の設定を持ちます。例えば、<a href="https://huggingface.co/datasets/frgfm/imagenette/tree/main/metadata">Imagennetデータセット</a>を見ると、3つもサブセットが存在することが分かります。

> To create different configurations, use the BuilderConfig class to create a subclass for your dataset. Provide the links to download the images and labels in data_url and metadata_urls:

異なる設定(config)を作成するには、BuilderCinfigクラスを使って継承クラスを作成します。data_urlやmetadata_url内にある画像とラベルへダウンロードリンクを入力してください。

```
class Food101Config(datasets.BuilderConfig):
    """Builder Config for Food-101"""
 
    def __init__(self, data_url, metadata_urls, **kwargs):
        """BuilderConfig for Food-101.
        Args:
          data_url: `string`, url to download the zip file from.
          metadata_urls: dictionary with keys 'train' and 'validation' containing the archive metadata URLs
          **kwargs: keyword arguments forwarded to super.
        """
        super(Food101Config, self).__init__(version=datasets.Version("1.0.0"), **kwargs)
        self.data_url = data_url
        self.metadata_urls = metadata_urls
```

> Now you can define your subsets at the top of GeneratorBasedBuilder. Imagine you want to create two subsets in the Food-101 dataset based on whether it is a breakfast or dinner food.
Define your subsets with Food101Config in a list in BUILDER_CONFIGS.
For each configuration, provide a name, description, and where to download the images and labels from.

ここで、GeneratorBasedBuilderのトップにサブセットデータを定義できます。
もし二つのサブセットデータ（朝食データと夕食データ）をFood-101に加える場合などを想定してください。
BUILDER_CONFIGリストにFood101Configサブセットを定義してください。
それぞれの設定には、Config引数の名前、説明、画像とラベルをどこからダウンロードするのかを提供してください。
```
class Food101(datasets.GeneratorBasedBuilder):
    """Food-101 Images dataset"""
 
    BUILDER_CONFIGS = [
        Food101Config(
            name="breakfast",
            description="Food types commonly eaten during breakfast.",
            data_url="https://link-to-breakfast-foods.zip",
            metadata_urls={
                "train": "https://link-to-breakfast-foods-train.txt", 
                "validation": "https://link-to-breakfast-foods-validation.txt"
            },
        ,
        Food101Config(
            name="dinner",
            description="Food types commonly eaten during dinner.",
            data_url="https://link-to-dinner-foods.zip",
            metadata_urls={
                "train": "https://link-to-dinner-foods-train.txt", 
                "validation": "https://link-to-dinner-foods-validation.txt"
            },
        )
    ]
```

> Now if users want to load the breakfast configuration, they can use the configuration name:

これで、ユーザが簡単な設定をロードしたい場合に設定名が使えます。
（下の例では、朝食データのみダウンロードできる）
```
from datasets import load_dataset
ds = load_dataset("food101", "breakfast", split="train")
```

### Add dataset metadata
> Adding information about your dataset is useful for users to learn more about it. This information is stored in the DatasetInfo class which is returned by the info method. Users can access this information by:

データセットに関する情報を追加することは、ユーザにはとても役立ちます。この情報infoメソッドによって返されるDatasetInfoクラスに保存されています。ユーザは、下のようなコードでこの情報にアクセスできます。
```
from datasets import load_dataset_builder
ds_builder = load_dataset_builder("food101")
ds_builder.info
```
> There is a lot of information you can specify about your dataset, but some important ones to include are:
> 1. description provides a concise description of the dataset.
> 1. features specify the dataset column types. Since you’re creating an image loading script, you’ll need to include the Image feature.
> 1. supervised_keys specify the input feature and label.
> 1. homepage provides a link to the dataset homepage.
> 1. citation is a BibTeX citation of the dataset.
> 1. license states the dataset’s license.

> You’ll notice a lot of the dataset information is defined earlier in the loading script which makes it easier to read. There are also other ~Datasets.Features you can input, so be sure to check out the full list for more details.

あなたが特定できるデータセットに関する情報は多く存在しますが、ここに含まれているべき最も重要な情報は：
1. データセットに関する詳細な説明
1. データセットのカラムの片を特定する特徴量。画像の特徴量もここに含みます
1. 入力の特徴量とラベルを特定するsupervised_keys(?)
1. データセットのホームページへのリンク
1. データセットのBibTeX（参考文献）の引用
1. データセットのライセンス

多くのデータセット情報が先にローディングスクリプトの中で定義されていることに気が付くでしょう。ほかにもデータセットの特徴量（Datastes.Features）として含められる情報があるので、詳細についてすべてのリストを確認してね。
```
def _info(self):
    return datasets.DatasetInfo(
        description=_DESCRIPTION,
        features=datasets.Features(
            {
                "image": datasets.Image(),
                "label": datasets.ClassLabel(names=_NAMES),
            }
        ),
        supervised_keys=("image", "label"),
        homepage=_HOMEPAGE,
        citation=_CITATION,
        license=_LICENSE,
        task_templates=[ImageClassification(image_column="image", label_column="label")],
    )
```

### Download and define the dataset splits
(データセットをダウンロードして分割する)
> Now that you’ve added some information about your dataset, the next step is to download the dataset and generate the splits.

ここまでで、データセットに関する情報を加えてきたので、ここからはデータセットをダウンロードして分割データを生成します。

> 1. Use the DownloadManager.download() method to download the dataset > and any other metadata you’d like to associate with it. This method accepts:
> - a name to a file inside a Hub dataset repository (in other words, the data/ folder)
> - a URL to a file hosted somewhere else
> - a list or dictionary of file names or URLs

> In the Food-101 loading script, you’ll notice again the URLs are defined earlier in the script.

DowloadManager.download()メソッドを使って、データセットや関連付けたい他のメタデータをダウンロードすることができます。この方法は、以下のものを受け入れます
- Huggingfaceのデータセットリポジトリのなかの、ファイルの名前
- ホストされたファイルへのURL
- ファイル名やURLの辞書型リスト
Food101の露ディングスクリプトでは、URLSがスクリプト内でより早く定地されていることに気が付くでしょう？

> After you’ve downloaded the dataset, use the SplitGenerator to organize the images and labels in each split. Name each split with a standard name like: Split.TRAIN, Split.TEST, and SPLIT.Validation.

データセットをダウンロードした後、SplitGeneratorを使って画像とラベルの分割データを構成します。それぞれの分割データをSplit.TRAIN, Split.TEST, SPILT.Validationのような名前にしてください。


> In the gen_kwargs parameter, specify the file paths to the images to iterate over and load. If necessary, you can use DownloadManager.iter_archive() to iterate over images in TAR archives. You can also specify the associated labels in the metadata_path. The images and metadata_path are actually passed onto the next step where you’ll actually generate the dataset.

gen_kwardsパラメータ内では、画像へのファイルパスを特定して繰り返し、ダウンロードします。必要があれば、DownloadManager.iter_archive()メソッドを使用して
metadata_path内で関連付けられたラベルを特定することもできます。引数```images```と```metadata_path```は、実際にデータセットを生成する次の段階で使用されます。

>> To stream a TAR archive file, you need to use DownloadManager.iter_archive()! The DownloadManager.download_and_extract() function does not support TAR archives in streaming mode.

TARファイルを流すには、DownloadManager.iter_archiveを使用する必要があります。DownloadManager.download_and_extract()関数はTARファイルをstreaming modeではサポートしていません。

```
def _split_generators(self, dl_manager):
    archive_path = dl_manager.download(_BASE_URL)
    split_metadata_paths = dl_manager.download(_METADATA_URLS)
    return [
        datasets.SplitGenerator(
            name=datasets.Split.TRAIN,
            gen_kwargs={
                "images": dl_manager.iter_archive(archive_path),
                "metadata_path": split_metadata_paths["train"],
            },
        ),
        datasets.SplitGenerator(
            name=datasets.Split.VALIDATION,
            gen_kwargs={
                "images": dl_manager.iter_archive(archive_path),
                "metadata_path": split_metadata_paths["test"],
            },
        ),
    ]
```

### Generate the dataset
> The last method in the GeneratorBasedBuilder class actually generates the images and labels in the dataset. It yields a dataset according to the stucture specified in features from the info method. As you can see, generate_examples accepts the images and metadata_path from the previous method as arguments.

GeneratorBasedBuilderクラスの最後のメソッドは、実際に画像とラベルをデータセット内に生成することです。infoメソッドの特徴から特定された構造から、データセットを生み出します(;´･ω･)？
見てもらえばわかるように、generate_examples は```images```と```metadata_path```を前のメソッドから引数として受け取ります。

>> To stream a TAR archive file, the metadata_path needs to be opened and read first. TAR files are accessed and yielded sequentially. This means you need to have the metadata information in hand first so you can yield it with its corresponding image.

TARファイルを流すには、metadata_pathを開いて先に読み込ませる必要があります。TARファイルは連続した列として読み込まれます。つまり、関連する画像と共にこれを生み出すために関連するメタデータ情報を取り扱う必要があります。

> Now you can write a function for opening and loading examples from the dataset:
```
def _generate_examples(self, images, metadata_path):
    """Generate images and labels for splits."""
    with open(metadata_path, encoding="utf-8") as f:
        files_to_keep = set(f.read().split("\n"))
    
    for file_path, file_obj in images:
        if file_path.startswith(_IMAGES_DIR):
            if file_path[len(_IMAGES_DIR) : -len(".jpg")] in files_to_keep:
                label = file_path.split("/")[2]
                yield file_path, {
                    "image": {"path": file_path, "bytes": file_obj.read()},
                    "label": label,
                }
```

### Generate the dataset metadata (optional)
> The dataset metadata can be generated and stored in the dataset card (README.md file).
Run the following command to generate your dataset metadata in README.md and make sure your new loading script works correctly:

データセットのメタデータが生成され、データセットカード(READ<E.mdファイル)の中に保存されます。次のコマンドを実行して、README.meの中にデータセットメタデータを生成し、新しいローディングスクリプトが正しく動くかを確認してください。
```
datasets-cli test path/to/<your-dataset-loading-script> --save_info --all_configs
```
> If your loading script passed the test, you should now have the dataset_info YAML fields in the header of the README.md file in your dataset folder.

もしローディングスクリプトがテストをパスすれば、データセットフォルダのREADME.mdファイルのトップにdataset_info YAMLのコード部分があるはずです。

### Upload the dataset to the Hub
> Once your script is ready, create a dataset card and upload it to the Hub.
Congratulations, you can now load your dataset from the Hub! 🥳

スクリプトが準備万端ならすぐに、データセットカードを作ってHubにアップロードしましょう! これであなたのデータセットをHuggingfaceHubからロードできますよ!
```
from datasets import load_dataset
load_dataset("<username>/my_dataset")
```


# 実際にLoadingScriptを書いてみた

## 参考にしたURL

https://huggingface.co/docs/datasets/v1.1.1/_modules/datasets/utils/download_manager.html

https://huggingface.co/docs/datasets/package_reference/builder_classes

https://huggingface.co/datasets/animelover/danbooru2022/blob/main/danbooru2022.py

https://huggingface.co/datasets/food101/blob/main/food101.py

https://huggingface.co/docs/datasets/about_dataset_load

https://huggingface.co/datasets/frgfm/imagenette/blob/main/imagenette.py

https://huggingface.co/docs/datasets/v1.2.1/add_dataset.html

DatasetInfo : 

https://huggingface.co/docs/datasets/package_reference/main_classes


* ファイルツリーの構造
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3520514/8126d69e-b7bb-728a-867a-a4144169fe9f.png)
* dataの中身はこんな感じ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3520514/992a1e0f-41e4-d426-8908-12ace0974915.png)

## _split_generators()
* LoadingScriptの中身が分かんないって感じたら、GoogleColabで一つ一つ試してみるのもありです。
```python
!pip install datasets
import datasets
from huggingface_hub import HfApi
from datasets import DownloadManager, DatasetInfo
from datasets.data_files import DataFilesDict
import os
import json

# AWSなど特別なデータの置き場がないので、
# 私の場合はHugggingfaceのAPIででーたの URLを取得する必要があります
dl_manager = DownloadManager()
_NAME = "mickylan2367/LoadingScriptPractice"
_REVISION = "main"
hfh_dataset_info = HfApi().dataset_info(_NAME, revision=_REVISION, timeout=100.0)
huh_dataset_info
```
出力は以下のようになる
```markdown
DatasetInfo: { 
  {'_id': '652500e0d4b61d080797cc9a',
   'author': 'mickylan2367',
   'cardData': {'language': ['en'], 'license': 'cc-by-sa-4.0', 'tags': ['music']},
   'citation': None,
   'description': None,
   'disabled': False,
   'downloads': 0,
   'gated': False,
   'id': 'mickylan2367/LoadingScriptPractice',
   'lastModified': '2023-10-10T11:04:50.000Z',
   'likes': 0,
   'private': False,
   'sha': '....',
   'siblings': [RepoFile: {'blob_id': None, 'lfs': None, 'rfilename': '.gitattributes', 'size': None},
                RepoFile: {'blob_id': None, 'lfs': None, 'rfilename': 'LoadingScriptPractice.py', 'size': None},
                RepoFile: {'blob_id': None, 'lfs': None, 'rfilename': 'README.md', 'size': None},
                RepoFile: {'blob_id': None, 'lfs': None, 'rfilename': 'data/data-0000.zip', 'size': None},
                RepoFile: {'blob_id': None, 'lfs': None, 'rfilename': 'data/metadata.jsonl', 'size': None}],
   'tags': ['language:en', 'license:cc-by-sa-4.0', 'music', 'region:us']}
}
```

* **.zipのURLをDict型として取得
```python
data_path = DataFilesDict.from_hf_repo(
    {datasets.Split.TRAIN: ["**"]},
    dataset_info=hfh_dataset_info,
    allowed_extensions=["zip", ".zip"],
)
data_path 
'''
{NamedSplit('train'): ['hf://datasets/mickylan2367/LoadingScriptPractice
@eec9b3698f77da2b7b861ef51dd6fa0b64473611/data/data-0000.zip']}
みたいにURLリストが付いた辞書が出てきます
'''
```

* URLからdl_managerでダウンロードしてiter_archive()にする。
* dl_manager.download(URL) : URLからダウンロードしてパスを返す
* dl_manager.iter_archive(PATH) : (ファイル名, オブジェクト)のタプル型イテレータ(for文で回せるオブジェクト型)を返す

```python
for iter in dl_manager.iter_archive(dl_manager.download(data_path["train"][0])):
    print(iter)

'''
出力は（ファイル名, zipされていたデータのオブジェクト）のタプル
('spectrogram_00000.png', <zipfile.ZipExtFile name='spectrogram_00000.png' mode='r' compress_type=deflate>)
('spectrogram_00001.png', <zipfile.ZipExtFile name='spectrogram_00001.png' mode='r' compress_type=deflate>)
('spectrogram_00002.png', <zipfile.ZipExtFile name='spectrogram_00002.png' mode='r' compress_type=deflate>)
('spectrogram_00003.png', <zipfile.ZipExtFile name='spectrogram_00003.png' mode='r' compress_type=deflate>)
('spectrogram_00004.png', <zipfile.ZipExtFile name='spectrogram_00004.png' mode='r' compress_type=deflate>)
('spectrogram_00005.png', <zipfile.ZipExtFile name='spectrogram_00005.png' mode='r' compress_type=deflate>)
('spectrogram_00006.png', <zipfile.ZipExtFile name='spectrogram_00006.png' mode='r' compress_type=deflate>)
('spectrogram_00007.png', <zipfile.ZipExtFile name='spectrogram_00007.png' mode='r' compress_type=deflate>)
'''
```
って感じで進めていきましょう。