Muat tfrecord eksternal dengan TFDS

Jika Anda memiliki proto tf.train.Example (di dalam .tfrecord , .riegeli ,...), yang telah dibuat oleh alat pihak ketiga, yang ingin Anda muat langsung dengan tfds API, maka halaman ini cocok untuk Anda.

Untuk memuat file .tfrecord , Anda hanya perlu:

  • Ikuti konvensi penamaan TFDS.
  • Tambahkan file metadata ( dataset_info.json , features.json ) di sepanjang file tfrecord Anda.

Keterbatasan:

Konvensi penamaan file

TFDS mendukung penentuan templat untuk nama file, yang memberikan fleksibilitas untuk menggunakan skema penamaan file yang berbeda. Templat diwakili oleh tfds.core.ShardedFileTemplate dan mendukung variabel berikut: {DATASET} , {SPLIT} , {FILEFORMAT} , {SHARD_INDEX} , {NUM_SHARDS} , dan {SHARD_X_OF_Y} . Misalnya, skema penamaan file default TFDS adalah: {DATASET}-{SPLIT}.{FILEFORMAT}-{SHARD_X_OF_Y} . Untuk MNIST, ini berarti nama file terlihat seperti berikut:

  • mnist-test.tfrecord-00000-of-00001
  • mnist-train.tfrecord-00000-of-00001

Tambahkan metadata

Menyediakan struktur fitur

Agar TFDS dapat memecahkan kode proto tf.train.Example , Anda perlu menyediakan struktur tfds.features yang sesuai dengan spesifikasi Anda. Misalnya:

features = tfds.features.FeaturesDict({
    'image':
        tfds.features.Image(
            shape=(256, 256, 3),
            doc='Picture taken by smartphone, downscaled.'),
    'label':
        tfds.features.ClassLabel(names=['dog', 'cat']),
    'objects':
        tfds.features.Sequence({
            'camera/K': tfds.features.Tensor(shape=(3,), dtype=tf.float32),
        }),
})

Sesuai dengan spesifikasi tf.train.Example berikut:

{
    'image': tf.io.FixedLenFeature(shape=(), dtype=tf.string),
    'label': tf.io.FixedLenFeature(shape=(), dtype=tf.int64),
    'objects/camera/K': tf.io.FixedLenSequenceFeature(shape=(3,), dtype=tf.int64),
}

Menentukan fitur memungkinkan TFDS untuk secara otomatis memecahkan kode gambar, video,... Seperti kumpulan data TFDS lainnya, metadata fitur (misalnya nama label,...) akan ditampilkan kepada pengguna (misalnya info.features['label'].names ).

Jika Anda mengontrol jalur pipa pembangkitan

Jika Anda membuat himpunan data di luar TFDS tetapi masih mengontrol alur pembuatan, Anda dapat menggunakan tfds.features.FeatureConnector.serialize_example untuk menyandikan data Anda dari dict[np.ndarray] ke tf.train.Example proto bytes :

with tf.io.TFRecordWriter('path/to/file.tfrecord') as writer:
  for ex in all_exs:
    ex_bytes = features.serialize_example(data)
    writer.write(ex_bytes)

Ini akan memastikan kompatibilitas fitur dengan TFDS.

Demikian pula, feature.deserialize_example ada untuk memecahkan kode proto ( example )

Jika Anda tidak mengontrol saluran pembangkitan

Jika Anda ingin melihat bagaimana tfds.features direpresentasikan dalam tf.train.Example , Anda dapat memeriksanya di colab:

  • Untuk menerjemahkan tfds.features ke dalam struktur tf.train.Example yang dapat dibaca manusia, Anda dapat memanggil features.get_serialized_info() .
  • Untuk mendapatkan FixedLenFeature ,... spec yang tepat diteruskan ke tf.io.parse_single_example , Anda dapat menggunakan spec = features.tf_example_spec

Dapatkan statistik tentang perpecahan

TFDS perlu mengetahui jumlah pasti contoh dalam setiap pecahan. Ini diperlukan untuk fitur seperti len(ds) , atau API subplit : split='train[75%:]' .

  • Jika Anda memiliki informasi ini, Anda dapat secara eksplisit membuat daftar tfds.core.SplitInfo dan melompat ke bagian berikutnya:

    split_infos = [
        tfds.core.SplitInfo(
            name='train',
            shard_lengths=[1024, ...],  # Num of examples in shard0, shard1,...
            num_bytes=0,  # Total size of your dataset (if unknown, set to 0)
        ),
        tfds.core.SplitInfo(name='test', ...),
    ]
    
  • Jika Anda tidak mengetahui informasi ini, Anda dapat menghitungnya menggunakan skrip compute_split_info.py (atau dalam skrip Anda sendiri dengan tfds.folder_dataset.compute_split_info ). Ini akan meluncurkan beam pipeline yang akan membaca semua pecahan pada direktori tertentu dan menghitung informasinya.

Tambahkan file metadata

Untuk secara otomatis menambahkan file metadata yang tepat di sepanjang kumpulan data Anda, gunakan tfds.folder_dataset.write_metadata :

tfds.folder_dataset.write_metadata(
    data_dir='/path/to/my/dataset/1.0.0/',
    features=features,
    # Pass the `out_dir` argument of compute_split_info (see section above)
    # You can also explicitly pass a list of `tfds.core.SplitInfo`.
    split_infos='/path/to/my/dataset/1.0.0/',
    # Pass a custom file name template or use None for the default TFDS
    # file name template.
    filename_template='{SPLIT}-{SHARD_X_OF_Y}.{FILEFORMAT}',

    # Optionally, additional DatasetInfo metadata can be provided
    # See:
    # https://www.tensorflow.org/datasets/api_docs/python/tfds/core/DatasetInfo
    description="""Multi-line description."""
    homepage='http://my-project.org',
    supervised_keys=('image', 'label'),
    citation="""BibTex citation.""",
)

Setelah fungsi dipanggil satu kali di direktori kumpulan data Anda, file metadata ( dataset_info.json ,...) telah ditambahkan dan kumpulan data Anda siap dimuat dengan TFDS (lihat bagian selanjutnya).

Muat kumpulan data dengan TFDS

Langsung dari folder

Setelah metadata dibuat, kumpulan data dapat dimuat menggunakan tfds.builder_from_directory yang mengembalikan tfds.core.DatasetBuilder dengan TFDS API standar (seperti tfds.builder ):

builder = tfds.builder_from_directory('~/path/to/my_dataset/3.0.0/')

# Metadata are available as usual
builder.info.splits['train'].num_examples

# Construct the tf.data.Dataset pipeline
ds = builder.as_dataset(split='train[75%:]')
for ex in ds:
  ...

Langsung dari beberapa folder

Dimungkinkan juga untuk memuat data dari beberapa folder. Hal ini dapat terjadi, misalnya, dalam pembelajaran penguatan ketika beberapa agen masing-masing menghasilkan kumpulan data terpisah dan Anda ingin memuat semuanya secara bersamaan. Kasus penggunaan lainnya adalah ketika kumpulan data baru dibuat secara rutin, misalnya kumpulan data baru per hari, dan Anda ingin memuat data dari rentang tanggal.

Untuk memuat data dari beberapa folder, gunakan tfds.builder_from_directories , yang mengembalikan tfds.core.DatasetBuilder dengan TFDS API standar (seperti tfds.builder ):

builder = tfds.builder_from_directories(builder_dirs=[
    '~/path/my_dataset/agent1/1.0.0/',
    '~/path/my_dataset/agent2/1.0.0/',
    '~/path/my_dataset/agent3/1.0.0/',
])

# Metadata are available as usual
builder.info.splits['train'].num_examples

# Construct the tf.data.Dataset pipeline
ds = builder.as_dataset(split='train[75%:]')
for ex in ds:
  ...

Struktur folder (opsional)

Untuk kompatibilitas yang lebih baik dengan TFDS, Anda dapat mengatur data Anda sebagai <data_dir>/<dataset_name>[/<dataset_config>]/<dataset_version> . Misalnya:

data_dir/
    dataset0/
        1.0.0/
        1.0.1/
    dataset1/
        config0/
            2.0.0/
        config1/
            2.0.0/

Ini akan membuat kumpulan data Anda kompatibel dengan tfds.load / tfds.builder API, cukup dengan menyediakan data_dir/ :

ds0 = tfds.load('dataset0', data_dir='data_dir/')
ds1 = tfds.load('dataset1/config0', data_dir='data_dir/')