Özellik kod çözmeyi özelleştirme

tfds.decode API, varsayılan özellik kod çözmeyi geçersiz kılmanıza olanak tanır. Ana kullanım durumu, daha iyi performans için görüntü kod çözme işlemini atlamaktır.

Kullanım örnekleri

Görüntü kod çözmenin atlanması

Kod çözme hattı üzerinde tam kontrole sahip olmak veya görüntülerin kodu çözülmeden önce bir filtre uygulamak (daha iyi performans için), görüntü kod çözme işlemini tamamen atlayabilirsiniz. Bu, hem tfds.features.Image hem de tfds.features.Video ile çalışır.

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

Görüntülerin kodu çözülmeden önce veri kümesini filtreleyin/karıştırın

Önceki örneğe benzer şekilde, görüntünün kodunu çözmeden önce ek tf.data ardışık düzen özelleştirmesi eklemek için tfds.decode.SkipDecoding() öğesini kullanabilirsiniz. Bu şekilde, filtrelenen görüntülerin kodu çözülmez ve daha büyük bir karıştırma arabelleği kullanabilirsiniz.

# 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)

Aynı anda kırpma ve kod çözme

Varsayılan tf.io.decode_image işlemini geçersiz kılmak için tfds.decode.make_decoder() dekoratörünü kullanarak yeni bir tfds.decode.Decoder nesnesi oluşturabilirsiniz.

@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(),
})

Hangisi şuna eşdeğerdir:

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']))

Video kod çözmeyi özelleştirme

Video Sequence(Image()) 'dır. Özel kod çözücüler uygulanırken bunlar ayrı karelere uygulanacaktır. Bu, görüntülere yönelik kod çözücülerin otomatik olarak videoyla uyumlu olduğu anlamına gelir.

@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(),
})

Hangisi şuna eşdeğerdir:

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

Yalnızca özelliklerin bir alt kümesinin kodunu çözün.

Yalnızca ihtiyacınız olan özellikleri belirterek bazı özellikleri tamamen atlamak da mümkündür. Diğer tüm özellikler göz ardı edilecek/atlanacak.

builder = tfds.builder('my_dataset')
builder.as_dataset(split='train', decoders=tfds.decode.PartialDecoding({
    'image': True,
    'metadata': {'num_objects', 'scene_name'},
    'objects': {'label'},
})

TFDS, verilen tfds.decode.PartialDecoding yapısıyla eşleşen builder.info.features alt kümesini seçecektir.

Yukarıdaki kodda, öne çıkanlar builder.info.features ile eşleşecek şekilde örtülü olarak çıkartılmıştır. Özellikleri açıkça tanımlamak da mümkündür. Yukarıdaki kod şuna eşdeğerdir:

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=[]),
    }),
})

Orijinal meta veriler (etiket adları, görüntü şekli,...) otomatik olarak yeniden kullanıldığından bunların sağlanmasına gerek yoktur.

tfds.decode.SkipDecoding , PartialDecoding(..., decoders={}) kwargs aracılığıyla tfds.decode.PartialDecoding öğesine aktarılabilir.