이 가이드를 따라 새 데이터셋을 생성하세요(TFDS 또는 사용자 고유의 저장소에 생성 가능).
원하는 데이터셋이 있는지 확인하려면 데이터셋 목록을 참조하세요.
요약
새 데이터셋을 작성하는 가장 쉬운 방법은 TFDS CLI를 사용하는 것입니다.
cd path/to/my/project/datasets/
tfds new my_dataset # Create `my_dataset/my_dataset.py` template files
# [...] Manually modify `my_dataset/my_dataset_dataset_builder.py` to implement your dataset.
cd my_dataset/
tfds build # Download and prepare the dataset to `~/tensorflow_datasets/`
tfds.load('my_dataset') 를 사용하여 새 데이터셋을 사용하려면 다음과 같이 하세요.
-
tfds.load~/tensorflow_datasets/my_dataset/에 생성된 데이터셋(예:tfds build)을 자동으로 감지하고 로드합니다. - 또는
import my.project.datasets.my_dataset데이터셋을 등록할 수도 있습니다.
import my.project.datasets.my_dataset # Register `my_dataset`
ds = tfds.load('my_dataset') # `my_dataset` registered
개요
데이터셋은 다양한 형식과 위치에 분산되어 있으며, 머신러닝 파이프라인에 바로 입력할 수 있는 형식으로 저장되어 있지 않은 경우가 많습니다. 바로 이러한 문제를 해결하기 위해 TFDS가 등장했습니다.
TFDS는 이러한 데이터 세트를 표준 형식(외부 데이터 -> 직렬화된 파일)으로 처리하며, 이 형식은 머신 러닝 파이프라인에서 로드할 수 있습니다(직렬화된 파일 -> tf.data.Dataset ). 직렬화는 한 번만 수행됩니다. 이후에는 사전 처리된 파일에서 직접 읽어옵니다.
대부분의 전처리 작업은 자동으로 수행됩니다. 각 데이터셋은 tfds.core.DatasetBuilder 의 하위 클래스를 구현하며, 이 클래스는 다음과 같은 사항을 명시합니다.
- 데이터가 어디에서 오는지(즉, URL)
- 데이터셋의 형태(즉, 특징)는 무엇인가?
- 데이터를 어떻게 분할해야 하는지 (예:
TRAINTEST); - 그리고 데이터 세트에 포함된 개별 예시들입니다.
데이터셋을 작성하세요
기본 템플릿: tfds new
TFDS CLI를 사용하여 필요한 템플릿 파이썬 파일을 생성하십시오.
cd path/to/project/datasets/ # Or use `--dir=path/to/project/datasets/` below
tfds new my_dataset
이 명령을 실행하면 다음과 같은 구조의 my_dataset/ 폴더가 새로 생성됩니다.
my_dataset/
__init__.py
README.md # Markdown description of the dataset.
CITATIONS.bib # Bibtex citation for the dataset.
TAGS.txt # List of tags describing the dataset.
my_dataset_dataset_builder.py # Dataset definition
my_dataset_dataset_builder_test.py # Test
dummy_data/ # (optional) Fake data (used for testing)
checksum.tsv # (optional) URL checksums (see `checksums` section).
여기서 TODO(my_dataset) 를 검색하고 필요에 따라 수정하세요.
데이터셋 예시
모든 데이터셋은 tfds.core.DatasetBuilder 의 서브클래스로 구현되어 있으며, 대부분의 상용구 코드는 이 클래스에서 처리됩니다. 다음을 지원합니다.
- 단일 컴퓨터에서 생성할 수 있는 소규모/중규모 데이터 세트(본 튜토리얼).
- 분산 생성이 필요한 매우 큰 데이터 세트( Apache Beam 사용, 대규모 데이터 세트 가이드 참조)
다음은 tfds.core.GeneratorBasedBuilder 를 기반으로 하는 최소한의 데이터셋 빌더 예제입니다.
class Builder(tfds.core.GeneratorBasedBuilder):
"""DatasetBuilder for my_dataset dataset."""
VERSION = tfds.core.Version('1.0.0')
RELEASE_NOTES = {
'1.0.0': 'Initial release.',
}
def _info(self) -> tfds.core.DatasetInfo:
"""Dataset metadata (homepage, citation,...)."""
return self.dataset_info_from_configs(
features=tfds.features.FeaturesDict({
'image': tfds.features.Image(shape=(256, 256, 3)),
'label': tfds.features.ClassLabel(
names=['no', 'yes'],
doc='Whether this is a picture of a cat'),
}),
)
def _split_generators(self, dl_manager: tfds.download.DownloadManager):
"""Download the data and define splits."""
extracted_path = dl_manager.download_and_extract('http://data.org/data.zip')
# dl_manager returns pathlib-like objects with `path.read_text()`,
# `path.iterdir()`,...
return {
'train': self._generate_examples(path=extracted_path / 'train_images'),
'test': self._generate_examples(path=extracted_path / 'test_images'),
}
def _generate_examples(self, path) -> Iterator[Tuple[Key, Example]]:
"""Generator of examples for each split."""
for img_path in path.glob('*.jpeg'):
# Yields (key, example)
yield img_path.name, {
'image': img_path,
'label': 'yes' if img_path.name.startswith('yes_') else 'no',
}
참고로, 특정 데이터 형식의 경우 대부분의 데이터 처리를 자동으로 수행해주는 바로 사용할 수 있는 데이터셋 구축 도구를 제공합니다.
덮어쓸 3가지 추상 메서드를 자세히 살펴보겠습니다.
_info : 데이터셋 메타데이터
_info 데이터셋 메타데이터를 포함하는 tfds.core.DatasetInfo 를 반환합니다.
def _info(self):
# The `dataset_info_from_configs` base method will construct the
# `tfds.core.DatasetInfo` object using the passed-in parameters and
# adding: builder (self), description/citations/tags from the config
# files located in the same package.
return self.dataset_info_from_configs(
homepage='https://dataset-homepage.org',
features=tfds.features.FeaturesDict({
'image_description': tfds.features.Text(),
'image': tfds.features.Image(),
# Here, 'label' can be 0-4.
'label': tfds.features.ClassLabel(num_classes=5),
}),
# If there's a common `(input, target)` tuple from the features,
# specify them here. They'll be used if as_supervised=True in
# builder.as_dataset.
supervised_keys=('image', 'label'),
# Specify whether to disable shuffling on the examples. Set to False by default.
disable_shuffling=False,
)
대부분의 항목은 설명이 필요 없을 정도로 명확합니다. 몇 가지 추가 설명은 다음과 같습니다.
-
features: 데이터셋의 구조, 형태 등을 지정합니다. 복잡한 데이터 유형(오디오, 비디오, 중첩 시퀀스 등)을 지원합니다. 자세한 내용은 사용 가능한 기능 또는 기능 커넥터 가이드를 참조하세요. -
disable_shuffling: 데이터셋 순서 유지 섹션을 참조하세요.
BibText CITATIONS.bib 파일 작성:
- 데이터셋 웹사이트에서 인용 지침(BibTex 형식으로 작성)을 검색하세요.
- arXiv 논문의 경우, 해당 논문을 찾은 후 오른쪽의
BibText링크를 클릭하세요. - Google Scholar 에서 해당 논문을 찾고 제목 아래에 있는 큰따옴표를 클릭한 다음 팝업 창에서
BibTeX클릭하세요. - 관련 논문이 없는 경우(예: 웹사이트만 있는 경우), BibTeX 온라인 편집기를 사용하여 사용자 지정 BibTeX 항목을 만들 수 있습니다(드롭다운 메뉴에
Online항목 유형이 있습니다).
TAGS.txt 파일 업데이트:
- 생성된 파일에는 허용된 모든 태그가 미리 채워져 있습니다.
- 데이터셋에 적용되지 않는 모든 태그를 제거하세요.
- 유효한 태그 목록은 tensorflow_datasets/core/valid_tags.txt 파일에 있습니다.
- 해당 목록에 태그를 추가하려면 PR을 보내주세요.
데이터셋 순서를 유지하세요
기본적으로 데이터셋의 레코드는 저장 시 무작위로 섞입니다. 이는 동일한 클래스에 속하는 레코드가 연속적으로 나타나는 경우가 많기 때문에 데이터셋 전체에 걸쳐 클래스 분포를 더욱 균일하게 하기 위함입니다. _generate_examples 함수에서 생성된 키를 기준으로 데이터셋을 정렬하려면 disable_shuffling 필드를 True 로 설정해야 합니다. 기본값은 False 입니다.
def _info(self):
return self.dataset_info_from_configs(
# [...]
disable_shuffling=True,
# [...]
)
셔플링을 비활성화하면 샤드를 더 이상 병렬로 읽을 수 없으므로 성능에 영향을 미친다는 점을 유념하십시오.
_split_generators : 데이터를 다운로드하고 분할합니다.
원본 데이터 다운로드 및 압축 해제
대부분의 데이터 세트는 웹에서 데이터를 다운로드해야 합니다. 이는 _split_generators 의 tfds.download.DownloadManager 입력 인수를 사용하여 수행됩니다. dl_manager 에는 다음과 같은 메서드가 있습니다.
-
download:http(s)://,ftp(s)://를 지원합니다. -
extract: 현재.zip,.gz및.tar파일을 지원합니다. -
download_and_extract:dl_manager.extract(dl_manager.download(urls))와 동일합니다.
이러한 모든 메서드는 tfds.core.Path ( epath.Path 의 별칭)를 반환하며, 이는 pathlib.Path와 유사한 객체입니다.
이러한 메서드는 다음과 같은 임의의 중첩 구조( list , dict )를 지원합니다.
extracted_paths = dl_manager.download_and_extract({
'foo': 'https://example.com/foo.zip',
'bar': 'https://example.com/bar.zip',
})
# This returns:
assert extracted_paths == {
'foo': Path('/path/to/extracted_foo/'),
'bar': Path('/path/extracted_bar/'),
}
수동 다운로드 및 압축 해제
일부 데이터는 자동으로 다운로드할 수 없습니다(예: 로그인 필요). 이 경우 사용자는 소스 데이터를 수동으로 다운로드하여 manual_dir/ (기본값은 ~/tensorflow_datasets/downloads/manual/ )에 배치해야 합니다.
그러면 dl_manager.manual_dir 통해 파일에 접근할 수 있습니다.
class MyDataset(tfds.core.GeneratorBasedBuilder):
MANUAL_DOWNLOAD_INSTRUCTIONS = """
Register into https://example.org/login to get the data. Place the `data.zip`
file in the `manual_dir/`.
"""
def _split_generators(self, dl_manager):
# data_path is a pathlib-like `Path('<manual_dir>/data.zip')`
archive_path = dl_manager.manual_dir / 'data.zip'
# Extract the manually downloaded `data.zip`
extracted_path = dl_manager.extract(archive_path)
...
manual_dir 위치는 tfds build --manual_dir= 사용하거나 tfds.download.DownloadConfig 사용하여 사용자 지정할 수 있습니다.
아카이브를 직접 읽어보세요
dl_manager.iter_archive 아카이브를 압축 해제하지 않고 순차적으로 읽습니다. 이렇게 하면 저장 공간을 절약하고 일부 파일 시스템에서 성능을 향상시킬 수 있습니다.
for filename, fobj in dl_manager.iter_archive('path/to/archive.zip'):
...
fobj with open('rb') as fobj: 동일한 메서드를 가지고 있습니다. (예: fobj.read() )
데이터셋 분할 지정
데이터셋에 미리 정의된 분할(예: MNIST 는 train 및 test 분할)이 있는 경우, 해당 분할을 그대로 유지하세요. 그렇지 않은 경우, all 분할(all) 하나만 지정하면 됩니다. 사용자는 subsplit API를 사용하여 동적으로 하위 분할을 생성할 수 있습니다(예: split='train[80%:]' ). 위에서 언급한 전체 분할( all 제외하고, 모든 알파벳 문자열을 분할 이름으로 사용할 수 있습니다.
def _split_generators(self, dl_manager):
# Download source data
extracted_path = dl_manager.download_and_extract(...)
# Specify the splits
return {
'train': self._generate_examples(
images_path=extracted_path / 'train_imgs',
label_path=extracted_path / 'train_labels.csv',
),
'test': self._generate_examples(
images_path=extracted_path / 'test_imgs',
label_path=extracted_path / 'test_labels.csv',
),
}
_generate_examples : 예제 생성기
_generate_examples 원본 데이터에서 각 분할에 대한 예제를 생성합니다.
이 메서드는 일반적으로 소스 데이터셋 아티팩트(예: CSV 파일)를 읽어 (key, feature_dict) 튜플을 생성합니다.
-
key: 예제 식별자.hash(key)사용하여 예제를 확정적으로 섞거나, 섞기가 비활성화된 경우 key를 기준으로 정렬하는 데 사용됩니다( 데이터 세트 순서 유지 섹션 참조). 올바른 형식은 다음과 같습니다.- 고유성 : 두 예제가 동일한 키를 사용하는 경우 예외가 발생합니다.
- 결정론적 :
download_dir,os.path.listdir순서 등에 의존해서는 안 됩니다. 데이터를 두 번 생성해도 동일한 키가 생성되어야 합니다. - 비교 가능 : 셔플링이 비활성화된 경우 키가 데이터 세트를 정렬하는 데 사용됩니다.
-
feature_dict: 예제 값을 담고 있는dict.- 구조는
tfds.core.DatasetInfo에 정의된features=구조와 일치해야 합니다. - 이미지, 비디오, 오디오 등과 같은 복잡한 데이터 유형은 자동으로 인코딩됩니다.
- 각 기능은 종종 여러 입력 유형을 허용합니다(예: 비디오는
/path/to/vid.mp4,np.array(shape=(l, h, w, c)),List[paths],List[np.array(shape=(h, w, c)],List[img_bytes],...)를 허용합니다). - 자세한 내용은 기능 커넥터 가이드를 참조하세요.
- 구조는
def _generate_examples(self, images_path, label_path):
# Read the input data out of the source files
with label_path.open() as f:
for row in csv.DictReader(f):
image_id = row['image_id']
# And yield (key, feature_dict)
yield image_id, {
'image_description': row['description'],
'image': images_path / f'{image_id}.jpeg',
'label': row['label'],
}
파일 접근 및 tf.io.gfile
클라우드 스토리지 시스템을 지원하려면 파이썬 내장 I/O 연산 사용을 피해야 합니다.
대신, dl_manager Google Cloud 스토리지와 직접 호환되는 pathlib과 유사한 객체를 반환합니다.
path = dl_manager.download_and_extract('http://some-website/my_data.zip')
json_path = path / 'data/file.json'
json.loads(json_path.read_text())
또는 파일 작업을 위해 내장 함수 대신 tf.io.gfile API를 사용할 수도 있습니다.
-
open->tf.io.gfile.GFile -
os.rename->tf.io.gfile.rename - ...
Pathlib은 tf.io.gfile 보다 우선적으로 사용되어야 합니다( rational 참조).
추가 종속성
일부 데이터 세트는 생성 과정에서만 추가적인 Python 종속성이 필요합니다. 예를 들어, SVHN 데이터 세트는 일부 데이터를 로드하기 위해 scipy 사용합니다.
TFDS 저장소에 데이터셋을 추가하는 경우, tfds.core.lazy_imports 사용하여 tensorflow-datasets 패키지의 크기를 작게 유지해 주세요. 사용자는 필요한 경우에만 추가 종속성을 설치하면 됩니다.
lazy_imports 사용하려면:
-
setup.py의DATASET_EXTRAS에 데이터셋 항목을 추가하세요. 이렇게 하면 사용자가 예를 들어pip install 'tensorflow-datasets[svhn]'와 같이 명령어를 사용하여 추가 종속성을 설치할 수 있습니다. - 가져오기 항목을
LazyImporter와LazyImportsTest에 추가하세요. -
DatasetBuilder에서 종속성(예:tfds.core.lazy_imports.scipy)에 접근하려면tfds.core.lazy_imports사용하세요.
손상된 데이터
일부 데이터셋은 완벽하게 깨끗하지 않고 손상된 데이터가 포함되어 있을 수 있습니다(예: 이미지가 JPEG 파일 형식이지만 유효하지 않은 JPEG 형식인 경우). 이러한 데이터셋은 제외해야 하지만, 제외된 데이터셋의 수와 그 이유를 데이터셋 설명에 명시해야 합니다.
데이터셋 구성/변형(tfds.core.BuilderConfig)
일부 데이터 세트는 데이터 전처리 및 디스크 저장 방식에 대한 여러 변형 또는 옵션을 가질 수 있습니다. 예를 들어 cycle_gan은 객체 쌍별로 하나의 구성( cycle_gan/horse2zebra , cycle_gan/monet2photo 등)을 가지고 있습니다.
이는 tfds.core.BuilderConfig 를 통해 수행됩니다.
구성 객체를
tfds.core.BuilderConfig의 하위 클래스로 정의하십시오. 예를 들어,MyDatasetConfig.@dataclasses.dataclass class MyDatasetConfig(tfds.core.BuilderConfig): img_size: Tuple[int, int] = (0, 0)MyDataset에 데이터셋이 노출하는MyDatasetConfig목록을 지정하는BUILDER_CONFIGS = []클래스 멤버를 정의합니다.class MyDataset(tfds.core.GeneratorBasedBuilder): VERSION = tfds.core.Version('1.0.0') # pytype: disable=wrong-keyword-args BUILDER_CONFIGS = [ # `name` (and optionally `description`) are required for each config MyDatasetConfig(name='small', description='Small ...', img_size=(8, 8)), MyDatasetConfig(name='big', description='Big ...', img_size=(32, 32)), ] # pytype: enable=wrong-keyword-argsMyDataset에서self.builder_config사용하여 데이터 생성 방식을 구성하세요(예:shape=self.builder_config.img_size). 여기에는_info()에 다른 값을 설정하거나 다운로드 데이터 접근 권한을 변경하는 것이 포함될 수 있습니다.
참고:
- 각 설정에는 고유한 이름이 있습니다. 설정의 정규화된 이름은
dataset_name/config_name(예:coco/2017)입니다. - 별도로 지정하지 않으면
BUILDER_CONFIGS의 첫 번째 구성이 사용됩니다(예:tfds.load('c4')기본적으로c4/en으로 설정됨).
BuilderConfig 를 사용하는 데이터셋의 예시는 anli 참조하세요.
버전
버전은 두 가지 다른 의미를 가질 수 있습니다.
- "외부" 원본 데이터 버전: 예: COCO v2019, v2017,...
- "내부" TFDS 코드 버전: 예:
tfds.features.FeaturesDict에서 기능 이름 변경,_generate_examples의 버그 수정
데이터셋을 업데이트하려면:
- "외부" 데이터 업데이트의 경우: 여러 사용자가 특정 연도/버전에 동시에 액세스해야 할 수 있습니다. 이를 위해서는 버전별로 하나의
tfds.core.BuilderConfig(예:coco/2017,coco/2019) 또는 버전별로 하나의 클래스(예:Voc2007,Voc2012)를 사용합니다. - "내부" 코드 업데이트의 경우: 사용자는 최신 버전만 다운로드합니다. 모든 코드 업데이트는 시맨틱 버전 관리 에 따라
VERSION클래스 속성을 증가시켜야 합니다(예:1.0.0에서VERSION = tfds.core.Version('2.0.0')으로).
등록을 위한 가져오기를 추가합니다.
tfds.load 및 tfds.builder 에 자동으로 등록되도록 프로젝트의 __init__ 메서드에 데이터셋 모듈을 임포트하는 것을 잊지 마세요.
import my_project.datasets.my_dataset # Register MyDataset
ds = tfds.load('my_dataset') # MyDataset available
예를 들어, tensorflow/datasets 에 기여하는 경우 해당 하위 디렉터리의 __init__.py (예: image/__init__.py )에 모듈 가져오기를 추가하세요.
일반적인 구현상의 문제점을 확인하세요
일반적인 구현상의 문제점을 확인해 주세요.
데이터셋을 테스트하세요
다운로드 및 준비: tfds build
데이터셋을 생성하려면 my_dataset/ 디렉토리에서 tfds build 실행하세요.
cd path/to/datasets/my_dataset/
tfds build --register_checksums
개발에 유용한 플래그 몇 가지:
-
--pdb: 예외가 발생하면 디버깅 모드로 진입합니다. -
--overwrite: 데이터 세트가 이미 생성된 경우 기존 파일을 삭제합니다. -
--max_examples_per_split: 전체 데이터셋 대신 처음 X개의 예제만 생성합니다(기본값은 1). -
--register_checksums: 다운로드한 URL의 체크섬을 기록합니다. 개발 환경에서만 사용해야 합니다.
전체 플래그 목록은 CLI 설명서를 참조하십시오.
체크섬
데이터셋의 체크섬을 기록하는 것이 결정성을 보장하고 문서화에 도움이 되므로 권장됩니다. 이는 --register_checksums 옵션을 사용하여 데이터셋을 생성함으로써 수행됩니다(이전 섹션 참조).
PyPI를 통해 데이터셋을 배포하는 경우, checksums.tsv 파일을 내보내는 것을 잊지 마세요(예: setup.py 의 package_data 에).
데이터셋에 대한 단위 테스트를 수행하세요.
tfds.testing.DatasetBuilderTestCase 는 데이터셋을 완벽하게 테스트하기 위한 기본 TestCase 입니다. 이 테스트 케이스는 원본 데이터셋의 구조를 모방한 "더미 데이터"를 테스트 데이터로 사용합니다.
- 테스트 데이터는
my_dataset/dummy_data/디렉토리에 저장해야 하며, 다운로드 및 압축 해제된 원본 데이터셋의 구성 요소와 동일해야 합니다. 이 데이터는 수동으로 생성하거나 스크립트를 사용하여 자동으로 생성할 수 있습니다( 예시 스크립트 참조 ). - 테스트 데이터 분할 시에는 반드시 서로 다른 데이터를 사용해야 합니다. 데이터셋 분할 시 데이터가 겹치면 테스트가 실패할 수 있습니다.
- 테스트 데이터에는 저작권이 있는 자료가 포함되어서는 안 됩니다 . 확실하지 않은 경우, 원본 데이터 세트의 자료를 사용하여 데이터를 생성하지 마십시오.
import tensorflow_datasets as tfds
from . import my_dataset_dataset_builder
class MyDatasetTest(tfds.testing.DatasetBuilderTestCase):
"""Tests for my_dataset dataset."""
DATASET_CLASS = my_dataset_dataset_builder.Builder
SPLITS = {
'train': 3, # Number of fake train example
'test': 1, # Number of fake test example
}
# If you are calling `download/download_and_extract` with a dict, like:
# dl_manager.download({'some_key': 'http://a.org/out.txt', ...})
# then the tests needs to provide the fake output paths relative to the
# fake data directory
DL_EXTRACT_RESULT = {
'name1': 'path/to/file1', # Relative to my_dataset/dummy_data dir.
'name2': 'file2',
}
if __name__ == '__main__':
tfds.testing.test_main()
데이터셋을 테스트하려면 다음 명령어를 실행하세요.
python my_dataset_test.py
의견을 보내주세요
저희는 데이터셋 생성 워크플로우를 지속적으로 개선하려고 노력하고 있지만, 문제점을 파악해야만 개선이 가능합니다. 데이터셋을 생성하는 동안 어떤 문제나 오류를 경험하셨나요? 이해하기 어려웠던 부분이나 처음 실행했을 때 제대로 작동하지 않았던 부분이 있었나요?
GitHub 에 의견을 공유해 주세요.