Ikuti panduan ini untuk membuat dataset baru (baik di TFDS atau di repositori Anda sendiri).
Periksa daftar dataset kami untuk melihat apakah dataset yang Anda inginkan sudah tersedia.
Ringkasan singkat:
Cara termudah untuk menulis dataset baru adalah dengan menggunakan 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/`
Untuk menggunakan dataset baru dengan tfds.load('my_dataset') :
-
tfds.loadakan secara otomatis mendeteksi dan memuat dataset yang dihasilkan di~/tensorflow_datasets/my_dataset/(misalnya olehtfds build). - Alternatifnya, Anda dapat secara eksplisit
import my.project.datasets.my_datasetuntuk mendaftarkan dataset Anda:
import my.project.datasets.my_dataset # Register `my_dataset`
ds = tfds.load('my_dataset') # `my_dataset` registered
Ringkasan
Dataset didistribusikan dalam berbagai format dan di berbagai tempat, dan tidak selalu disimpan dalam format yang siap untuk dimasukkan ke dalam alur kerja pembelajaran mesin. Di sinilah TFDS berperan.
TFDS memproses dataset tersebut ke dalam format standar (data eksternal -> file yang diserialisasi), yang kemudian dapat dimuat sebagai pipeline pembelajaran mesin (file yang diserialisasi -> tf.data.Dataset ). Serialisasi hanya dilakukan sekali. Akses selanjutnya akan membaca langsung dari file yang telah diproses sebelumnya.
Sebagian besar pra-pemrosesan dilakukan secara otomatis. Setiap dataset mengimplementasikan subkelas dari tfds.core.DatasetBuilder , yang menentukan:
- Dari mana data tersebut berasal (yaitu URL-nya);
- Seperti apa tampilan dataset tersebut (yaitu fitur-fiturnya);
- Bagaimana data harus dibagi (misalnya,
TRAINdanTEST); - dan contoh-contoh individual dalam dataset tersebut.
Tuliskan dataset Anda
Templat default: tfds new
Gunakan TFDS CLI untuk menghasilkan file template python yang dibutuhkan.
cd path/to/project/datasets/ # Or use `--dir=path/to/project/datasets/` below
tfds new my_dataset
Perintah ini akan membuat folder my_dataset/ baru dengan struktur sebagai berikut:
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).
Cari TODO(my_dataset) di sini dan modifikasi sesuai kebutuhan.
Contoh dataset
Semua dataset diimplementasikan sebagai subkelas dari tfds.core.DatasetBuilder , yang menangani sebagian besar kode berulang. Dataset ini mendukung:
- Kumpulan data kecil/sedang yang dapat dihasilkan pada satu mesin (tutorial ini).
- Kumpulan data yang sangat besar yang memerlukan pembangkitan terdistribusi (menggunakan Apache Beam , lihat panduan kumpulan data besar kami)
Berikut adalah contoh minimal dari pembuat dataset yang didasarkan pada 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',
}
Perlu dicatat bahwa, untuk beberapa format data spesifik, kami menyediakan pembuat dataset siap pakai untuk menangani sebagian besar pemrosesan data.
Mari kita lihat secara detail 3 metode abstrak untuk menimpa.
_info : metadata dataset
_info mengembalikan tfds.core.DatasetInfo yang berisi metadata dataset .
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,
)
Sebagian besar kolom seharusnya mudah dipahami. Beberapa penjelasan tambahan:
-
features: Ini menentukan struktur, bentuk, dan lain-lain dari dataset. Mendukung tipe data kompleks (audio, video, urutan bersarang, ...). Lihat fitur yang tersedia atau panduan konektor fitur untuk informasi lebih lanjut. -
disable_shuffling: Lihat bagian Memelihara urutan dataset .
Menulis file BibText CITATIONS.bib :
- Cari petunjuk pengutipan di situs web dataset (gunakan format BibTex).
- Untuk makalah arXiv : temukan makalah tersebut dan klik tautan
BibTextdi sisi kanan. - Temukan makalah tersebut di Google Scholar dan klik tanda kutip ganda di bawah judul, lalu pada jendela pop-up, klik
BibTeX. - Jika tidak ada makalah terkait (misalnya, hanya ada situs web), Anda dapat menggunakan Editor Online BibTeX untuk membuat entri BibTeX khusus (menu tarik-turun memiliki tipe entri
Online).
Memperbarui file TAGS.txt :
- Semua tag yang diizinkan sudah terisi otomatis dalam file yang dihasilkan.
- Hapus semua tag yang tidak berlaku untuk dataset tersebut.
- Tag yang valid tercantum dalam tensorflow_datasets/core/valid_tags.txt .
- Untuk menambahkan tag ke daftar tersebut, silakan kirim PR.
Pertahankan urutan dataset.
Secara default, dataset diacak saat disimpan untuk membuat distribusi kelas lebih seragam di seluruh dataset, karena seringkali dataset yang termasuk dalam kelas yang sama berdekatan. Untuk menentukan bahwa dataset harus diurutkan berdasarkan kunci yang dihasilkan oleh _generate_examples , field disable_shuffling harus diatur ke True . Secara default, nilainya adalah False .
def _info(self):
return self.dataset_info_from_configs(
# [...]
disable_shuffling=True,
# [...]
)
Perlu diingat bahwa menonaktifkan pengacakan (shuffling) akan berdampak pada performa karena shard tidak dapat lagi dibaca secara paralel.
_split_generators : mengunduh dan membagi data
Mengunduh dan mengekstrak data sumber
Sebagian besar dataset perlu mengunduh data dari web. Ini dilakukan dengan menggunakan argumen input tfds.download.DownloadManager dari _split_generators . dl_manager memiliki metode-metode berikut:
-
download: mendukunghttp(s)://,ftp(s):// -
extract: saat ini mendukung file.zip,.gz, dan.tar. -
download_and_extract: Sama dengandl_manager.extract(dl_manager.download(urls))
Semua metode tersebut mengembalikan tfds.core.Path (alias untuk epath.Path ), yang merupakan objek mirip pathlib.Path .
Metode-metode tersebut mendukung struktur bersarang sembarang ( list , dict ), seperti:
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/'),
}
Pengunduhan dan ekstraksi manual
Beberapa data tidak dapat diunduh secara otomatis (misalnya memerlukan login), dalam hal ini, pengguna akan mengunduh data sumber secara manual dan menempatkannya di manual_dir/ (secara default ~/tensorflow_datasets/downloads/manual/ ).
File kemudian dapat diakses melalui 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)
...
Lokasi manual_dir dapat disesuaikan dengan tfds build --manual_dir= atau menggunakan tfds.download.DownloadConfig .
Baca arsip secara langsung
dl_manager.iter_archive membaca arsip secara berurutan tanpa mengekstraknya. Hal ini dapat menghemat ruang penyimpanan dan meningkatkan kinerja pada beberapa sistem file.
for filename, fobj in dl_manager.iter_archive('path/to/archive.zip'):
...
fobj memiliki metode yang sama seperti with open('rb') as fobj: (misalnya fobj.read() )
Menentukan pembagian dataset
Jika dataset sudah dilengkapi dengan pembagian yang telah ditentukan sebelumnya (misalnya MNIST memiliki pembagian data train dan test ), pertahankan pembagian tersebut. Jika tidak, cukup tentukan satu pembagian " all . Pengguna dapat membuat sub-pembagian sendiri secara dinamis dengan API sub-pembagian (misalnya split='train[80%:]' ). Perhatikan bahwa string alfabet apa pun dapat digunakan sebagai nama pembagian, selain all yang telah disebutkan sebelumnya.
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 : Generator contoh
_generate_examples menghasilkan contoh untuk setiap pemisahan dari data sumber.
Metode ini biasanya akan membaca artefak dataset sumber (misalnya file CSV) dan menghasilkan tuple (key, feature_dict) :
-
key: Pengidentifikasi contoh. Digunakan untuk mengacak contoh secara deterministik menggunakanhash(key)atau untuk mengurutkan berdasarkan key ketika pengacakan dinonaktifkan (lihat bagian Memelihara urutan dataset ). Seharusnya:- unik : Jika dua contoh menggunakan kunci yang sama, pengecualian akan muncul.
- Deterministik : Seharusnya tidak bergantung pada
download_dir,os.path.listdirorder,... Pembuatan data dua kali seharusnya menghasilkan kunci yang sama. - sebanding : Jika pengacakan dinonaktifkan, kunci akan digunakan untuk mengurutkan dataset.
-
feature_dict: Sebuahdictyang berisi nilai-nilai contoh.- Struktur tersebut harus sesuai dengan struktur
features=yang didefinisikan dalamtfds.core.DatasetInfo. - Tipe data kompleks (gambar, video, audio,...) akan dienkode secara otomatis.
- Setiap fitur sering menerima beberapa tipe input (misalnya video menerima
/path/to/vid.mp4,np.array(shape=(l, h, w, c)),List[paths],List[np.array(shape=(h, w, c)],List[img_bytes],...) - Lihat panduan konektor fitur untuk informasi selengkapnya.
- Struktur tersebut harus sesuai dengan struktur
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'],
}
Akses file dan tf.io.gfile
Untuk mendukung sistem penyimpanan Cloud, hindari penggunaan operasi I/O bawaan Python.
Sebaliknya, dl_manager mengembalikan objek mirip pathlib yang kompatibel langsung dengan penyimpanan 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())
Alternatifnya, gunakan API tf.io.gfile sebagai pengganti fungsi bawaan untuk operasi file:
-
open->tf.io.gfile.GFile -
os.rename->tf.io.gfile.rename - ...
Pathlib sebaiknya lebih diutamakan daripada tf.io.gfile (lihat alasannya) .
Ketergantungan tambahan
Beberapa dataset hanya memerlukan dependensi Python tambahan selama proses pembuatan. Misalnya, dataset SVHN menggunakan scipy untuk memuat beberapa data.
Jika Anda menambahkan dataset ke repositori TFDS, harap gunakan tfds.core.lazy_imports agar paket tensorflow-datasets tetap kecil. Pengguna hanya akan menginstal dependensi tambahan jika diperlukan.
Untuk menggunakan lazy_imports :
- Tambahkan entri untuk dataset Anda ke dalam
DATASET_EXTRASdisetup.py. Ini memungkinkan pengguna untuk melakukan, misalnya,pip install 'tensorflow-datasets[svhn]'untuk menginstal dependensi tambahan. - Tambahkan entri untuk impor Anda ke
LazyImporterdan keLazyImportsTest. - Gunakan
tfds.core.lazy_importsuntuk mengakses dependensi (misalnya,tfds.core.lazy_imports.scipy) diDatasetBuilderAnda.
Data rusak
Beberapa dataset tidak sepenuhnya bersih dan mengandung beberapa data yang rusak (misalnya, gambar berada dalam file JPEG tetapi beberapa di antaranya adalah JPEG yang tidak valid). Contoh-contoh ini sebaiknya diabaikan, tetapi cantumkan catatan dalam deskripsi dataset tentang berapa banyak contoh yang dihilangkan dan alasannya.
Konfigurasi/varian dataset (tfds.core.BuilderConfig)
Beberapa dataset mungkin memiliki beberapa varian, atau opsi tentang bagaimana data diproses dan ditulis ke disk. Misalnya, cycle_gan memiliki satu konfigurasi per pasangan objek ( cycle_gan/horse2zebra , cycle_gan/monet2photo , ...).
Hal ini dilakukan melalui tfds.core.BuilderConfig :
Tetapkan objek konfigurasi Anda sebagai subkelas dari
tfds.core.BuilderConfig. Misalnya,MyDatasetConfig.@dataclasses.dataclass class MyDatasetConfig(tfds.core.BuilderConfig): img_size: Tuple[int, int] = (0, 0)Definisikan anggota kelas
BUILDER_CONFIGS = []diMyDatasetyang mencantumkanMyDatasetConfigyang diekspos oleh dataset tersebut.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-argsGunakan
self.builder_configdiMyDatasetuntuk mengkonfigurasi pembuatan data (misalnyashape=self.builder_config.img_size). Ini mungkin termasuk mengatur nilai yang berbeda di_info()atau mengubah akses unduhan data.
Catatan:
- Setiap konfigurasi memiliki nama yang unik. Nama lengkap dari sebuah konfigurasi adalah
dataset_name/config_name(misalnyacoco/2017). - Jika tidak ditentukan, konfigurasi pertama dalam
BUILDER_CONFIGSakan digunakan (misalnyatfds.load('c4')default kec4/en)
Lihat anli untuk contoh dataset yang menggunakan BuilderConfig .
Versi
Versi dapat merujuk pada dua arti yang berbeda:
- Versi data asli "eksternal": misalnya COCO v2019, v2017,...
- Versi kode TFDS "internal": misalnya, mengganti nama fitur di
tfds.features.FeaturesDict, memperbaiki bug di_generate_examples
Untuk memperbarui dataset:
- Untuk pembaruan data "eksternal": Beberapa pengguna mungkin ingin mengakses tahun/versi tertentu secara bersamaan. Hal ini dilakukan dengan menggunakan satu
tfds.core.BuilderConfigper versi (misalnyacoco/2017,coco/2019) atau satu kelas per versi (misalnyaVoc2007,Voc2012). - Untuk pembaruan kode "internal": Pengguna hanya mengunduh versi terbaru. Setiap pembaruan kode harus meningkatkan atribut kelas
VERSION(misalnya dari1.0.0menjadiVERSION = tfds.core.Version('2.0.0')) sesuai dengan versi semantik .
Tambahkan impor untuk pendaftaran
Jangan lupa mengimpor modul dataset ke __init__ proyek Anda agar secara otomatis terdaftar di tfds.load dan tfds.builder .
import my_project.datasets.my_dataset # Register MyDataset
ds = tfds.load('my_dataset') # MyDataset available
Misalnya, jika Anda berkontribusi pada tensorflow/datasets , tambahkan impor modul ke __init__.py di subdirektori tersebut (misalnya image/__init__.py ).
Periksa kesalahan umum dalam implementasi.
Silakan periksa kesalahan umum yang mungkin terjadi saat implementasi .
Uji dataset Anda
Unduh dan siapkan: tfds build
Untuk membuat dataset, jalankan tfds build dari direktori my_dataset/ :
cd path/to/datasets/my_dataset/
tfds build --register_checksums
Beberapa flag yang berguna untuk pengembangan:
-
--pdb: Masuk ke mode debugging jika terjadi pengecualian. -
--overwrite: Hapus file yang sudah ada jika dataset sudah dibuat. -
--max_examples_per_split: Hanya menghasilkan X contoh pertama (defaultnya 1), bukan seluruh dataset. -
--register_checksums: Merekam checksum dari URL yang diunduh. Sebaiknya hanya digunakan selama pengembangan.
Lihat dokumentasi CLI untuk daftar lengkap flag.
Checksum
Disarankan untuk mencatat checksum dari dataset Anda untuk menjamin determinisme, membantu dokumentasi, dan lain-lain. Hal ini dilakukan dengan menghasilkan dataset menggunakan opsi --register_checksums (lihat bagian sebelumnya).
Jika Anda merilis dataset Anda melalui PyPI, jangan lupa untuk mengekspor file checksums.tsv (misalnya di package_data pada setup.py Anda).
Lakukan pengujian unit pada dataset Anda.
tfds.testing.DatasetBuilderTestCase adalah TestCase dasar untuk menguji sebuah dataset secara menyeluruh. TestCase ini menggunakan "data dummy" sebagai data uji yang meniru struktur dataset sumber.
- Data uji harus ditempatkan di direktori
my_dataset/dummy_data/dan harus meniru artefak dataset sumber seperti yang diunduh dan diekstrak. Data uji dapat dibuat secara manual atau otomatis dengan skrip ( contoh skrip ). - Pastikan untuk menggunakan data yang berbeda dalam pembagian data uji Anda, karena pengujian akan gagal jika pembagian dataset Anda tumpang tindih.
- Data uji tidak boleh mengandung materi yang dilindungi hak cipta . Jika ragu, jangan membuat data menggunakan materi dari dataset asli.
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()
Jalankan perintah berikut untuk menguji dataset.
python my_dataset_test.py
Kirimkan masukan kepada kami
Kami terus berupaya untuk meningkatkan alur kerja pembuatan dataset, tetapi hanya dapat melakukannya jika kami mengetahui masalahnya. Masalah atau kesalahan apa yang Anda temui saat membuat dataset? Apakah ada bagian yang membingungkan, atau tidak berfungsi pada percobaan pertama?
Silakan sampaikan masukan Anda di GitHub .