यह दस्तावेज़ 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
ओवरराइट करके।
श्रमिकों के बीच अपना डेटा स्वचालित रूप से साझा करें (TF)
एकाधिक श्रमिकों पर प्रशिक्षण करते समय, आप 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)