התאמה אישית של פענוח תכונה

ה-API של tfds.decode מאפשר לך לעקוף את פענוח התכונה המוגדרת כברירת מחדל. מקרה השימוש העיקרי הוא לדלג על פענוח התמונה לביצועים טובים יותר.

דוגמאות לשימוש

דילוג על פענוח התמונה

כדי לשמור על שליטה מלאה על צינור הפענוח, או להחיל פילטר לפני פענוח התמונות (לביצועים טובים יותר), תוכל לדלג לחלוטין על פענוח התמונה. זה עובד גם עם tfds.features.Image וגם עם 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

סנן/ערבב את מערך הנתונים לפני פענוח התמונות

בדומה לדוגמה הקודמת, אתה יכול להשתמש ב- tfds.decode.SkipDecoding() כדי להוסיף התאמה אישית נוספת של צינור tf.data לפני פענוח התמונה. כך התמונות המסוננות לא יפוענחו ותוכלו להשתמש במאגר עירוב גדול יותר.

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

חיתוך ופענוח בו זמנית

כדי לעקוף את פעולת ברירת המחדל tf.io.decode_image , אתה יכול ליצור אובייקט tfds.decode.Decoder חדש באמצעות הדקורטור 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(),
})

מה שמקביל ל:

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

התאמה אישית של פענוח וידאו

הווידאו הם Sequence(Image()) . בעת החלת מפענחים מותאמים אישית, הם יחולו על מסגרות בודדות. המשמעות היא שמפענחים לתמונות תואמים אוטומטית לווידאו.

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

מה שמקביל ל:

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

פענוח רק תת-סט של התכונות.

אפשר גם לדלג לחלוטין על תכונות מסוימות על ידי ציון התכונות הדרושות לך בלבד. כל שאר התכונות יתעלמו/ידלגו.

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

TFDS יבחר את קבוצת המשנה של builder.info.features התואמת למבנה הנתון tfds.decode.PartialDecoding .

בקוד שלמעלה, המוצגים נשלפים באופן מרומז כדי להתאים ל builder.info.features . אפשר גם להגדיר במפורש את התכונות. הקוד שלמעלה שווה ערך ל:

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

המטא-נתונים המקוריים (שמות תווית, צורת תמונה,...) נמצאים בשימוש חוזר אוטומטי ולכן אין צורך לספק אותם.

ניתן להעביר tfds.decode.SkipDecoding אל tfds.decode.PartialDecoding , דרך ה- PartialDecoding(..., decoders={}) kwargs.