परफ़ॉर्मेंस से जुड़ी सलाह

यह दस्तावेज़ TensorFlow डेटासेट (TFDS)-विशिष्ट प्रदर्शन युक्तियाँ प्रदान करता है। ध्यान दें कि TFDS डेटासेट को tf.data.Dataset ऑब्जेक्ट के रूप में प्रदान करता है, इसलिए tf.data गाइड की सलाह अभी भी लागू होती है।

बेंचमार्क डेटासेट

किसी भी tf.data.Dataset ऑब्जेक्ट को बेंचमार्क करने के लिए tfds.benchmark(ds) उपयोग करें।

परिणामों को सामान्य करने के लिए batch_size= इंगित करना सुनिश्चित करें (उदाहरण के लिए 100 इटर/सेकंड -> 3200 पूर्व/सेकंड)। यह किसी भी पुनरावर्तनीय (जैसे tfds.benchmark(tfds.as_numpy(ds)) ) के साथ काम करता है।

ds = tfds.load('mnist', split='train').batch(32).prefetch()
# Display some benchmark statistics
tfds.benchmark(ds, batch_size=32)
# Second iteration is much faster, due to auto-caching
tfds.benchmark(ds, batch_size=32)

छोटे डेटासेट (1 जीबी से कम)

सभी TFDS डेटासेट डिस्क पर डेटा को TFRecord प्रारूप में संग्रहीत करते हैं। छोटे डेटासेट (जैसे MNIST, CIFAR-10/-100) के लिए, .tfrecord से पढ़ने पर महत्वपूर्ण ओवरहेड जुड़ सकता है।

चूंकि वे डेटासेट मेमोरी में फिट होते हैं, इसलिए डेटासेट को कैशिंग या प्री-लोड करके प्रदर्शन में उल्लेखनीय सुधार करना संभव है। ध्यान दें कि टीएफडीएस स्वचालित रूप से छोटे डेटासेट को कैश करता है (निम्न अनुभाग में विवरण है)।

डेटासेट को कैशिंग करना

यहां डेटा पाइपलाइन का एक उदाहरण दिया गया है जो छवियों को सामान्य करने के बाद डेटासेट को स्पष्ट रूप से कैश करता है।

def normalize_img(image, label):
  """Normalizes images: `uint8` -> `float32`."""
  return tf.cast(image, tf.float32) / 255., label


ds, ds_info = tfds.load(
    'mnist',
    split='train',
    as_supervised=True,  # returns `(img, label)` instead of dict(image=, ...)
    with_info=True,
)
# Applying normalization before `ds.cache()` to re-use it.
# Note: Random transformations (e.g. images augmentations) should be applied
# after both `ds.cache()` (to avoid caching randomness) and `ds.batch()` (for
# vectorization [1]).
ds = ds.map(normalize_img, num_parallel_calls=tf.data.AUTOTUNE)
ds = ds.cache()
# For true randomness, we set the shuffle buffer to the full dataset size.
ds = ds.shuffle(ds_info.splits['train'].num_examples)
# Batch after shuffling to get unique batches at each epoch.
ds = ds.batch(128)
ds = ds.prefetch(tf.data.experimental.AUTOTUNE)

इस डेटासेट पर पुनरावृत्ति करते समय, कैशिंग के कारण दूसरी पुनरावृत्ति पहले की तुलना में बहुत तेज़ होगी।

ऑटो-कैशिंग

डिफ़ॉल्ट रूप से, TFDS ऑटो-कैश ( ds.cache() के साथ) डेटासेट जो निम्नलिखित बाधाओं को पूरा करते हैं:

  • कुल डेटासेट आकार (सभी विभाजन) परिभाषित है और <250 MiB
  • shuffle_files अक्षम है, या केवल एक ही शार्ड पढ़ा जाता है

tfds.load में try_autocaching=False को tfds.ReadConfig पास करके ऑटो-कैशिंग से बाहर निकलना संभव है। यह देखने के लिए कि क्या कोई विशिष्ट डेटासेट ऑटो-कैश का उपयोग करेगा, डेटासेट कैटलॉग दस्तावेज़ पर एक नज़र डालें।

संपूर्ण डेटा को एकल टेंसर के रूप में लोड किया जा रहा है

यदि आपका डेटासेट मेमोरी में फिट बैठता है, तो आप संपूर्ण डेटासेट को एकल Tensor या NumPy सरणी के रूप में भी लोड कर सकते हैं। सभी उदाहरणों को एक ही tf.Tensor में बैच करने के लिए batch_size=-1 सेट करके ऐसा करना संभव है। फिर tf.Tensor से np.array में रूपांतरण के लिए tfds.as_numpy का उपयोग करें।

(img_train, label_train), (img_test, label_test) = tfds.as_numpy(tfds.load(
    'mnist',
    split=['train', 'test'],
    batch_size=-1,
    as_supervised=True,
))

बड़े डेटासेट

बड़े डेटासेट को शार्प किया जाता है (कई फ़ाइलों में विभाजित किया जाता है) और आमतौर पर मेमोरी में फिट नहीं होते हैं, इसलिए उन्हें कैश नहीं किया जाना चाहिए।

फेरबदल और प्रशिक्षण

प्रशिक्षण के दौरान, डेटा को अच्छी तरह से फेरबदल करना महत्वपूर्ण है - खराब तरीके से फेरबदल किए गए डेटा के परिणामस्वरूप प्रशिक्षण सटीकता कम हो सकती है।

रिकॉर्ड्स को शफ़ल करने के लिए ds.shuffle उपयोग करने के अलावा, आपको कई फ़ाइलों में विभाजित बड़े डेटासेट के लिए अच्छा शफ़ल व्यवहार प्राप्त करने के लिए shuffle_files=True भी सेट करना चाहिए। अन्यथा, युग उसी क्रम में शार्ड पढ़ेंगे, और इसलिए डेटा वास्तव में यादृच्छिक नहीं होगा।

ds = tfds.load('imagenet2012', split='train', shuffle_files=True)

इसके अतिरिक्त, जब shuffle_files=True , TFDS options.deterministic अक्षम कर देता है, जिससे प्रदर्शन को थोड़ा बढ़ावा मिल सकता है। नियतात्मक फेरबदल प्राप्त करने के लिए, tfds.ReadConfig के साथ इस सुविधा से ऑप्ट-आउट करना संभव है: या तो read_config.shuffle_seed सेट करके या read_config.options.deterministic ओवरराइट करके।

श्रमिकों के बीच अपना डेटा स्वचालित रूप से साझा करें (टीएफ)

एकाधिक श्रमिकों पर प्रशिक्षण करते समय, आप tfds.ReadConfig के input_context तर्क का उपयोग कर सकते हैं, इसलिए प्रत्येक कार्यकर्ता डेटा का एक सबसेट पढ़ेगा।

input_context = tf.distribute.InputContext(
    input_pipeline_id=1,  # Worker id
    num_input_pipelines=4,  # Total number of workers
)
read_config = tfds.ReadConfig(
    input_context=input_context,
)
ds = tfds.load('dataset', split='train', read_config=read_config)

यह सबस्प्लिट एपीआई का पूरक है। सबसे पहले, सबप्लिट एपीआई लागू किया जाता है: train[:50%] पढ़ने के लिए फ़ाइलों की एक सूची में परिवर्तित किया जाता है। फिर, उन फ़ाइलों पर एक ds.shard() op लागू किया जाता है। उदाहरण के लिए, num_input_pipelines=2 के साथ train[:50%] का उपयोग करते समय, प्रत्येक 2 कर्मचारी 1/4 डेटा पढ़ेंगे।

जब shuffle_files=True , फ़ाइलें एक कार्यकर्ता के भीतर शफ़ल की जाती हैं, लेकिन सभी श्रमिकों के बीच नहीं। प्रत्येक कार्यकर्ता युगों के बीच फ़ाइलों के समान उपसमूह को पढ़ेगा।

श्रमिकों के बीच अपने डेटा को स्वचालित रूप से साझा करें (जैक्स)

जैक्स के साथ, आप अपने डेटा को श्रमिकों के बीच वितरित करने के लिए tfds.split_for_jax_process या tfds.even_splits API का उपयोग कर सकते हैं। स्प्लिट एपीआई गाइड देखें।

split = tfds.split_for_jax_process('train', drop_remainder=True)
ds = tfds.load('my_dataset', split=split)

tfds.split_for_jax_process इसके लिए एक सरल उपनाम है:

# The current `process_index` loads only `1 / process_count` of the data.
splits = tfds.even_splits('train', n=jax.process_count(), drop_remainder=True)
split = splits[jax.process_index()]

तेज़ छवि डिकोडिंग

डिफ़ॉल्ट रूप से, टीएफडीएस स्वचालित रूप से छवियों को डीकोड करता है। हालाँकि, ऐसे मामले हैं जहां tfds.decode.SkipDecoding के साथ छवि डिकोडिंग को छोड़ना और मैन्युअल रूप से tf.io.decode_image op को लागू करना अधिक प्रभावी हो सकता है:

  • उदाहरणों को फ़िल्टर करते समय ( tf.data.Dataset.filter के साथ), उदाहरणों को फ़िल्टर करने के बाद छवियों को डीकोड करने के लिए।
  • छवियों को क्रॉप करते समय, फ़्यूज्ड tf.image.decode_and_crop_jpeg ऑप का उपयोग करें।

दोनों उदाहरणों का कोड डिकोड गाइड में उपलब्ध है।

अप्रयुक्त सुविधाओं को छोड़ें

यदि आप केवल सुविधाओं के सबसेट का उपयोग कर रहे हैं, तो कुछ सुविधाओं को पूरी तरह से छोड़ना संभव है। यदि आपके डेटासेट में कई अप्रयुक्त सुविधाएं हैं, तो उन्हें डिकोड न करने से प्रदर्शन में काफी सुधार हो सकता है। https://www.tensorflow.org/datasets/decode#only_decode_a_sub-set_of_the_features देखें

tf.data मेरी सारी RAM का उपयोग करता है!

यदि आपकी रैम सीमित है, या यदि आप tf.data उपयोग करते समय समानांतर में कई डेटासेट लोड कर रहे हैं, तो यहां कुछ विकल्प दिए गए हैं जो मदद कर सकते हैं:

बफ़र आकार को ओवरराइड करें

builder.as_dataset(
  read_config=tfds.ReadConfig(
    ...
    override_buffer_size=1024,  # Save quite a bit of RAM.
  ),
  ...
)

यह TFRecordDataset (या समतुल्य) को दिए गए buffer_size को ओवरराइड करता है: https://www.tensorflow.org/api_docs/python/tf/data/TFRecordDataset#args

जादुई व्यवहार को रोकने के लिए tf.data.Dataset.with_options का उपयोग करें

https://www.tensorflow.org/api_docs/python/tf/data/Dataset#with_options

options = tf.data.Options()

# Stop magic stuff that eats up RAM:
options.autotune.enabled = False
options.experimental_distribute.auto_shard_policy = (
  tf.data.experimental.AutoShardPolicy.OFF)
options.experimental_optimization.inject_prefetch = False

data = data.with_options(options)