API tfds.decode
memungkinkan Anda mengganti decoding fitur default. Kasus penggunaan utamanya adalah melewatkan decoding gambar untuk kinerja yang lebih baik.
Contoh penggunaan
Melewatkan decoding gambar
Untuk mempertahankan kontrol penuh atas alur dekode, atau untuk menerapkan filter sebelum gambar didekode (untuk performa lebih baik), Anda dapat melewati dekode gambar sepenuhnya. Ini berfungsi dengan tfds.features.Image
dan tfds.features.Video
.
ds = tfds.load('imagenet2012', split='train', decoders={
'image': tfds.decode.SkipDecoding(),
})
for example in ds.take(1):
assert example['image'].dtype == tf.string # Images are not decoded
Filter/acak kumpulan data sebelum gambar didekodekan
Mirip dengan contoh sebelumnya, Anda dapat menggunakan tfds.decode.SkipDecoding()
untuk menyisipkan kustomisasi pipeline tf.data
tambahan sebelum mendekode gambar. Dengan begitu, gambar yang difilter tidak akan didekodekan dan Anda dapat menggunakan buffer acak yang lebih besar.
# Load the base dataset without decoding
ds, ds_info = tfds.load(
'imagenet2012',
split='train',
decoders={
'image': tfds.decode.SkipDecoding(), # Image won't be decoded here
},
as_supervised=True,
with_info=True,
)
# Apply filter and shuffle
ds = ds.filter(lambda image, label: label != 10)
ds = ds.shuffle(10000)
# Then decode with ds_info.features['image']
ds = ds.map(
lambda image, label: ds_info.features['image'].decode_example(image), label)
Memotong dan mendekode secara bersamaan
Untuk mengganti operasi tf.io.decode_image
default, Anda dapat membuat objek tfds.decode.Decoder
baru menggunakan dekorator tfds.decode.make_decoder()
.
@tfds.decode.make_decoder()
def decode_example(serialized_image, feature):
crop_y, crop_x, crop_height, crop_width = 10, 10, 64, 64
return tf.image.decode_and_crop_jpeg(
serialized_image,
[crop_y, crop_x, crop_height, crop_width],
channels=feature.feature.shape[-1],
)
ds = tfds.load('imagenet2012', split='train', decoders={
# With video, decoders are applied to individual frames
'image': decode_example(),
})
Yang setara dengan:
def decode_example(serialized_image, feature):
crop_y, crop_x, crop_height, crop_width = 10, 10, 64, 64
return tf.image.decode_and_crop_jpeg(
serialized_image,
[crop_y, crop_x, crop_height, crop_width],
channels=feature.shape[-1],
)
ds, ds_info = tfds.load(
'imagenet2012',
split='train',
with_info=True,
decoders={
'image': tfds.decode.SkipDecoding(), # Skip frame decoding
},
)
ds = ds.map(functools.partial(decode_example, feature=ds_info.features['image']))
Menyesuaikan decoding video
Video adalah Sequence(Image())
. Saat menerapkan decoder khusus, dekoder tersebut akan diterapkan ke frame individual. Ini berarti decoder untuk gambar secara otomatis kompatibel dengan video.
@tfds.decode.make_decoder()
def decode_example(serialized_image, feature):
crop_y, crop_x, crop_height, crop_width = 10, 10, 64, 64
return tf.image.decode_and_crop_jpeg(
serialized_image,
[crop_y, crop_x, crop_height, crop_width],
channels=feature.feature.shape[-1],
)
ds = tfds.load('ucf101', split='train', decoders={
# With video, decoders are applied to individual frames
'video': decode_example(),
})
Yang setara dengan:
def decode_frame(serialized_image):
"""Decodes a single frame."""
crop_y, crop_x, crop_height, crop_width = 10, 10, 64, 64
return tf.image.decode_and_crop_jpeg(
serialized_image,
[crop_y, crop_x, crop_height, crop_width],
channels=ds_info.features['video'].shape[-1],
)
def decode_video(example):
"""Decodes all individual frames of the video."""
video = example['video']
video = tf.map_fn(
decode_frame,
video,
dtype=ds_info.features['video'].dtype,
parallel_iterations=10,
)
example['video'] = video
return example
ds, ds_info = tfds.load('ucf101', split='train', with_info=True, decoders={
'video': tfds.decode.SkipDecoding(), # Skip frame decoding
})
ds = ds.map(decode_video) # Decode the video
Hanya memecahkan kode sub-kumpulan fitur.
Anda juga dapat melewatkan beberapa fitur sepenuhnya dengan hanya menentukan fitur yang Anda perlukan. Semua fitur lainnya akan diabaikan/dilewati.
builder = tfds.builder('my_dataset')
builder.as_dataset(split='train', decoders=tfds.decode.PartialDecoding({
'image': True,
'metadata': {'num_objects', 'scene_name'},
'objects': {'label'},
})
TFDS akan memilih subset dari builder.info.features
yang cocok dengan struktur tfds.decode.PartialDecoding
yang diberikan.
Dalam kode di atas, fitur unggulan diekstraksi secara implisit agar cocok dengan builder.info.features
. Dimungkinkan juga untuk mendefinisikan fitur secara eksplisit. Kode di atas setara dengan:
builder = tfds.builder('my_dataset')
builder.as_dataset(split='train', decoders=tfds.decode.PartialDecoding({
'image': tfds.features.Image(),
'metadata': {
'num_objects': tf.int64,
'scene_name': tfds.features.Text(),
},
'objects': tfds.features.Sequence({
'label': tfds.features.ClassLabel(names=[]),
}),
})
Metadata asli (nama label, bentuk gambar,...) secara otomatis digunakan kembali sehingga tidak perlu menyediakannya.
tfds.decode.SkipDecoding
dapat diteruskan ke tfds.decode.PartialDecoding
, melalui kwarg PartialDecoding(..., decoders={})
.