কর্মক্ষমতা টিপস

এই নথিটি TensorFlow ডেটাসেট (TFDS)-নির্দিষ্ট কর্মক্ষমতা টিপস প্রদান করে। মনে রাখবেন যে TFDS ডেটাসেটগুলিকে tf.data.Dataset অবজেক্ট হিসাবে সরবরাহ করে, তাই tf.data গাইডের পরামর্শ এখনও প্রযোজ্য।

বেঞ্চমার্ক ডেটাসেট

যেকোনো tf.data.Dataset অবজেক্টকে বেঞ্চমার্ক করতে tfds.benchmark(ds) ব্যবহার করুন।

ফলাফল স্বাভাবিক করতে batch_size= নির্দেশ করতে ভুলবেন না (যেমন 100 iter/sec -> 3200 ex/sec)। এটি যেকোনো পুনরাবৃত্তিযোগ্য (যেমন 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 থেকে পড়া উল্লেখযোগ্য ওভারহেড যোগ করতে পারে।

যেহেতু এই ডেটাসেটগুলি মেমরিতে ফিট করে, ডেটাসেটটি ক্যাশে বা প্রি-লোড করার মাধ্যমে উল্লেখযোগ্যভাবে কর্মক্ষমতা উন্নত করা সম্ভব। মনে রাখবেন যে TFDS স্বয়ংক্রিয়ভাবে ছোট ডেটাসেট ক্যাশ করে (নিম্নলিখিত বিভাগে বিশদ বিবরণ রয়েছে)।

ডেটাসেট ক্যাশে করা হচ্ছে

এখানে একটি ডেটা পাইপলাইনের উদাহরণ রয়েছে যা চিত্রগুলিকে স্বাভাবিক করার পরে স্পষ্টভাবে ডেটাসেট ক্যাশে করে।

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.loadtry_autocaching=False to tfds.ReadConfig পাস করে অটো-ক্যাশিং থেকে অপ্ট আউট করা সম্ভব। একটি নির্দিষ্ট ডেটাসেট স্বয়ংক্রিয় ক্যাশে ব্যবহার করবে কিনা তা দেখতে ডেটাসেট ক্যাটালগ ডকুমেন্টেশন দেখুন।

একটি একক টেনসর হিসাবে সম্পূর্ণ ডেটা লোড করা হচ্ছে

যদি আপনার ডেটাসেট মেমরিতে ফিট হয়, তাহলে আপনি সম্পূর্ণ ডেটাসেটটিকে একটি একক টেনসর বা 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)

এটি সাবস্প্লিট API-এর পরিপূরক। প্রথমে, সাবপ্লিট API প্রয়োগ করা হয়: train[:50%] পড়ার জন্য ফাইলগুলির একটি তালিকায় রূপান্তরিত হয়। তারপর, একটি ds.shard() op ঐ ফাইলগুলিতে প্রয়োগ করা হয়। উদাহরণস্বরূপ, num_input_pipelines=2 সহ train[:50%] ব্যবহার করার সময়, 2 জন কর্মী প্রত্যেকে 1/4 ডেটা পড়বে।

যখন shuffle_files=True , তখন ফাইলগুলি একজন শ্রমিকের মধ্যে নাড়াচাড়া করা হয়, কিন্তু কর্মীদের মধ্যে নয়। প্রতিটি কর্মী যুগের মধ্যে ফাইলগুলির একই উপসেট পড়বে।

কর্মীদের মধ্যে আপনার ডেটা স্বয়ংক্রিয়ভাবে ভাগ করুন (জ্যাক্স)

Jax এর সাথে, আপনি কর্মীদের মধ্যে আপনার ডেটা বিতরণ করতে tfds.split_for_jax_process বা tfds.even_splits API ব্যবহার করতে পারেন। বিভক্ত 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 স্বয়ংক্রিয়ভাবে ছবি ডিকোড করে। যাইহোক, এমন কিছু ক্ষেত্রে আছে যেখানে tfds.decode.SkipDecoding এর মাধ্যমে ইমেজ ডিকোডিং এড়িয়ে যাওয়া এবং ম্যানুয়ালি tf.io.decode_image op প্রয়োগ করা আরও বেশি কার্যকরী হতে পারে:

  • উদাহরণগুলি ফিল্টার করার সময় ( tf.data.Dataset.filter সহ), উদাহরণগুলি ফিল্টার করার পরে চিত্রগুলিকে ডিকোড করার জন্য৷
  • ছবি ক্রপ করার সময়, ফিউজড tf.image.decode_and_crop_jpeg op ব্যবহার করতে।

উভয় উদাহরণের কোড ডিকোড গাইডে উপলব্ধ।

অব্যবহৃত বৈশিষ্ট্যগুলি এড়িয়ে যান

আপনি যদি শুধুমাত্র বৈশিষ্ট্যগুলির একটি উপসেট ব্যবহার করেন তবে কিছু বৈশিষ্ট্য সম্পূর্ণভাবে এড়িয়ে যাওয়া সম্ভব৷ যদি আপনার ডেটাসেটে অনেকগুলি অব্যবহৃত বৈশিষ্ট্য থাকে, সেগুলিকে ডিকোড না করলে তা উল্লেখযোগ্যভাবে পারফরম্যান্স উন্নত করতে পারে। https://www.tensorflow.org/datasets/decode#only_decode_a_sub-set_of_the_features দেখুন

tf.data আমার সমস্ত RAM ব্যবহার করে!

আপনি যদি 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)