این راهنما را برای ایجاد یک مجموعه داده جدید (چه در TFDS یا در مخزن خود) دنبال کنید.
لیست مجموعه داده های ما را بررسی کنید تا ببینید آیا مجموعه داده مورد نظر شما از قبل وجود دارد یا خیر.
TL; DR
ساده ترین راه برای نوشتن یک مجموعه داده جدید استفاده از 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 های آن).
- آنچه مجموعه داده به نظر می رسد (یعنی ویژگی های آن).
- چگونه داده ها باید تقسیم شوند (به عنوان مثال
TRAIN
وTEST
). - و نمونه های فردی در مجموعه داده.
مجموعه داده خود را بنویسید
قالب پیش فرض: 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 ، به راهنمای مجموعه داده عظیم ما مراجعه کنید)
در اینجا یک نمونه حداقلی از سازنده مجموعه داده است که بر اساس 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
: دانلود و تقسیم داده ها
دانلود و استخراج داده های منبع
اکثر مجموعه داده ها نیاز به دانلود داده ها از وب دارند. این کار با استفاده از آرگومان ورودی tfds.download.DownloadManager
از _split_generators
انجام می شود. 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
split را مشخص کنید. کاربران می توانند به صورت پویا زیرشاخه های خود را با 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)
یا برای مرتبسازی بر اساس کلید در صورت غیرفعالسازی به هم زدن استفاده میشود (به بخش حفظ ترتیب مجموعه دادهها مراجعه کنید). باید باشد:- منحصر به فرد : اگر دو مثال از یک کلید استفاده کنند، یک استثنا ایجاد می شود.
- قطعی : نباید به ترتیب
download_dir
،os.path.listdir
وابسته باشد،... با تولید دوبار داده باید همان کلید را به دست آورد. - comparable : در صورت غیرفعال بودن درهمرفتن، از کلید برای مرتبسازی مجموعه داده استفاده میشود.
-
feature_dict
:dict
که حاوی مقادیر مثال است.- ساختار باید با
features=
ساختار تعریف شده درtfds.core.DatasetInfo
مطابقت داشته باشد. - انواع داده های پیچیده (تصویر، ویدئو، صدا،...) به طور خودکار کدگذاری می شوند.
- هر ویژگی اغلب انواع ورودی را میپذیرد (مثلاً پذیرش
/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
به منظور پشتیبانی از سیستمهای ذخیرهسازی ابری، از استفاده از عملیات ورودی/خروجی داخلی پایتون خودداری کنید.
در عوض، dl_manager
اشیایی شبیه pathlib را که مستقیماً با فضای ذخیرهسازی Google Cloud سازگار هستند، برمیگرداند:
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 مراجعه کنید.
وابستگی های اضافی
برخی از مجموعههای داده فقط در طول تولید به وابستگیهای اضافی پایتون نیاز دارند. به عنوان مثال، مجموعه داده SVHN از scipy
برای بارگذاری برخی از داده ها استفاده می کند.
اگر مجموعه داده را به مخزن TFDS اضافه میکنید، لطفاً از tfds.core.lazy_imports
برای کوچک نگه داشتن بسته tensorflow-datasets
استفاده کنید. کاربران فقط در صورت نیاز وابستگی های اضافی را نصب می کنند.
برای استفاده از lazy_imports
:
- یک ورودی برای مجموعه داده خود به
DATASET_EXTRAS
درsetup.py
اضافه کنید. این باعث میشود که کاربران بتوانند، برای مثال،pip install 'tensorflow-datasets[svhn]'
برای نصب وابستگیهای اضافی انجام دهند. - یک ورودی برای واردات خود به
LazyImporter
و بهLazyImportsTest
اضافه کنید. - از
tfds.core.lazy_imports
برای دسترسی به وابستگی (مثلاtfds.core.lazy_imports.scipy
) درDatasetBuilder
خود استفاده کنید.
داده های خراب
برخی از مجموعههای داده کاملاً تمیز نیستند و حاوی برخی دادههای خراب هستند (به عنوان مثال، تصاویر در فایلهای 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)
عضو کلاس
BUILDER_CONFIGS = []
را درMyDataset
تعریف کنید کهMyDatasetConfig
هایی را که مجموعه داده نشان می دهد لیست می کند.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-args
از
self.builder_config
درMyDataset
برای پیکربندی تولید داده استفاده کنید (به عنوان مثالshape=self.builder_config.img_size
). این ممکن است شامل تنظیم مقادیر مختلف در_info()
یا تغییر دسترسی به داده های دانلود باشد.
یادداشت ها:
- هر پیکربندی یک نام منحصر به فرد دارد. نام کاملاً واجد شرایط یک پیکربندی،
dataset_name/config_name
است (به عنوان مثالcoco/2017
). - اگر مشخص نشده باشد، اولین پیکربندی در
BUILDER_CONFIGS
استفاده خواهد شد (به عنوان مثالtfds.load('c4')
پیشفرضc4/en
)
برای مثالی از مجموعه داده ای که از BuilderConfig
s استفاده می کند، 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')
) پس از نسخهسازی معنایی .
یک واردات برای ثبت اضافه کنید
فراموش نکنید که ماژول مجموعه داده را به پروژه __init__
خود وارد کنید تا به طور خودکار در tfds.load
، tfds.builder
ثبت شود.
import my_project.datasets.my_dataset # Register MyDataset
ds = tfds.load('my_dataset') # MyDataset available
برای مثال، اگر در tensorflow/datasets
مشارکت میکنید، وارد کردن ماژول را به فهرست فرعی __init__.py
آن اضافه کنید (مثلاً image/__init__.py
.
گوچاهای پیاده سازی رایج را بررسی کنید
لطفاً گوچاهای پیاده سازی رایج را بررسی کنید.
مجموعه داده خود را تست کنید
دانلود و آماده سازی: tfds build
برای تولید مجموعه داده، tfds build
از پوشه my_dataset/
اجرا کنید:
cd path/to/datasets/my_dataset/
tfds build --register_checksums
برخی از پرچم های مفید برای توسعه:
-
--pdb
: در صورت وجود استثنا، وارد حالت اشکال زدایی شوید. -
--overwrite
: اگر مجموعه داده قبلاً تولید شده باشد، فایل های موجود را حذف کنید. -
--max_examples_per_split
: فقط اولین نمونه های X را تولید کنید (به طور پیش فرض 1)، به جای مجموعه داده کامل. -
--register_checksums
: چک جمع های آدرس های دانلود شده را ضبط کنید. فقط باید در حین توسعه استفاده شود.
برای فهرست کامل پرچمها به مستندات CLI مراجعه کنید.
جمع های چک
توصیه میشود جمعهای کنترلی مجموعه دادههای خود را برای تضمین قطعیت، کمک به مستندسازی،... این کار با تولید مجموعه داده با --register_checksums
انجام میشود (به بخش قبلی مراجعه کنید).
اگر مجموعه داده های خود را از طریق PyPI منتشر می کنید، فراموش نکنید که فایل های checksums.tsv
را صادر کنید (مثلاً در package_data
setup.py
خود).
مجموعه داده خود را واحد آزمایش کنید
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 به اشتراک بگذارید.