সাধারণ বাস্তবায়ন gotchas

এই পৃষ্ঠাটি একটি নতুন ডেটাসেট প্রয়োগ করার সময় সাধারণ বাস্তবায়ন গোটচা বর্ণনা করে।

লিগ্যাসি SplitGenerator এড়ানো উচিত

পুরানো tfds.core.SplitGenerator API বাতিল করা হয়েছে।

def _split_generator(...):
  return [
      tfds.core.SplitGenerator(name='train', gen_kwargs={'path': train_path}),
      tfds.core.SplitGenerator(name='test', gen_kwargs={'path': test_path}),
  ]

দ্বারা প্রতিস্থাপিত করা উচিত:

def _split_generator(...):
  return {
      'train': self._generate_examples(path=train_path),
      'test': self._generate_examples(path=test_path),
  }

যুক্তি : নতুন API কম শব্দভাষা এবং আরও স্পষ্ট। পুরানো API ভবিষ্যতের সংস্করণে সরানো হবে।

নতুন ডেটাসেট একটি ফোল্ডারে স্বয়ংসম্পূর্ণ হওয়া উচিত

tensorflow_datasets/ সংগ্রহস্থলের ভিতরে একটি ডেটাসেট যোগ করার সময়, অনুগ্রহ করে নিশ্চিত করুন যে ডেটাসেট-এ-ফোল্ডার কাঠামো অনুসরণ করুন (সমস্ত চেকসাম, ডামি ডেটা, বাস্তবায়ন কোড একটি ফোল্ডারে স্বয়ংসম্পূর্ণ)।

  • পুরানো ডেটাসেট (খারাপ): <category>/<ds_name>.py
  • নতুন ডেটাসেট (ভাল): <category>/<ds_name>/<ds_name>.py

টেমপ্লেট তৈরি করতে TFDS CLI ( tfds new , or gtfds new googlers) ব্যবহার করুন।

যুক্তি : পুরানো কাঠামোর জন্য চেকসাম, জাল ডেটার জন্য পরম পাথ প্রয়োজন এবং অনেক জায়গায় ডেটাসেট ফাইলগুলি বিতরণ করা হয়েছিল। এটি TFDS সংগ্রহস্থলের বাইরে ডেটাসেটগুলি বাস্তবায়ন করা কঠিন করে তুলছিল। সামঞ্জস্যের জন্য, নতুন কাঠামো এখন সর্বত্র ব্যবহার করা উচিত।

বর্ণনা তালিকা মার্কডাউন হিসাবে ফর্ম্যাট করা উচিত

DatasetInfo.description str মার্কডাউন হিসাবে ফর্ম্যাট করা হয়েছে। মার্কডাউন তালিকার প্রথম আইটেমের আগে একটি খালি লাইন প্রয়োজন:

_DESCRIPTION = """
Some text.
                      # << Empty line here !!!
1. Item 1
2. Item 1
3. Item 1
                      # << Empty line here !!!
Some other text.
"""

যুক্তি : খারাপভাবে বিন্যাসিত বিবরণ আমাদের ক্যাটালগ ডকুমেন্টেশনে ভিজ্যুয়াল আর্টিফ্যাক্ট তৈরি করে। খালি লাইন ব্যতীত, উপরের পাঠ্যটি এইভাবে রেন্ডার করা হবে:

কিছু লেখা। 1. আইটেম 1 2. আইটেম 1 3. আইটেম 1 অন্য কিছু পাঠ্য

ClassLabel নাম ভুলে গেছি

tfds.features.ClassLabel ব্যবহার করার সময়, names= অথবা names_file= ( num_classes=10 এর পরিবর্তে) সহ মানব-পাঠযোগ্য লেবেল str প্রদান করার চেষ্টা করুন।

features = {
    'label': tfds.features.ClassLabel(names=['dog', 'cat', ...]),
}

যুক্তি : মানুষের পাঠযোগ্য লেবেল অনেক জায়গায় ব্যবহার করা হয়:

  • _generate_examples এ সরাসরি str yield করার অনুমতি দিন: yield {'label': 'dog'}
  • info.features['label'].names এর মত ব্যবহারকারীদের মধ্যে প্রকাশ করা হয়েছে (রূপান্তর পদ্ধতি .str2int('dog') ,... এছাড়াও উপলব্ধ)
  • ভিজ্যুয়ালাইজেশনে ব্যবহৃত হয় tfds.show_examples , tfds.as_dataframe

ছবির আকৃতি ভুলে গেছি

tfds.features.Image , tfds.features.Video ব্যবহার করার সময়, যদি ছবিগুলির স্থির আকৃতি থাকে, সেগুলি স্পষ্টভাবে উল্লেখ করা উচিত:

features = {
    'image': tfds.features.Image(shape=(256, 256, 3)),
}

যুক্তি : এটি স্ট্যাটিক আকৃতির অনুমানের অনুমতি দেয় (যেমন ds.element_spec['image'].shape ), যা ব্যাচিংয়ের জন্য প্রয়োজন (অজানা আকৃতির ব্যাচের ছবিগুলিকে প্রথমে আকার পরিবর্তন করতে হবে)।

tfds.features.Tensor এর পরিবর্তে আরো নির্দিষ্ট ধরনের পছন্দ করুন

যখন সম্ভব, সাধারণ tfds.features.Tensor এর পরিবর্তে আরও নির্দিষ্ট ধরনের tfds.features.ClassLabel , tfds.features.BBoxFeatures ,... পছন্দ করুন।

যুক্তি : আরও শব্দার্থগতভাবে সঠিক হওয়ার পাশাপাশি, নির্দিষ্ট বৈশিষ্ট্যগুলি ব্যবহারকারীদের অতিরিক্ত মেটাডেটা প্রদান করে এবং সরঞ্জাম দ্বারা সনাক্ত করা হয়।

গ্লোবাল স্পেসে অলস আমদানি

বৈশ্বিক স্থান থেকে অলস আমদানি বলা উচিত নয়। উদাহরণস্বরূপ নিম্নলিখিত ভুল:

tfds.lazy_imports.apache_beam # << Error: Import beam in the global scope

def f() -> beam.Map:
  ...

যুক্তি : গ্লোবাল স্কোপে অলস আমদানি ব্যবহার করা সমস্ত tfds ব্যবহারকারীদের জন্য মডিউল আমদানি করবে, অলস আমদানির উদ্দেশ্যকে পরাজিত করবে।

গতিশীলভাবে কম্পিউটিং ট্রেন/পরীক্ষা বিভাজন

যদি ডেটাসেট অফিসিয়াল বিভাজন প্রদান না করে, তাহলে TFDSও করা উচিত নয়। নিম্নলিখিত এড়ানো উচিত:

_TRAIN_TEST_RATIO = 0.7

def _split_generator():
  ids = list(range(num_examples))
  np.random.RandomState(seed).shuffle(ids)

  # Split train/test
  train_ids = ids[_TRAIN_TEST_RATIO * num_examples:]
  test_ids = ids[:_TRAIN_TEST_RATIO * num_examples]
  return {
      'train': self._generate_examples(train_ids),
      'test': self._generate_examples(test_ids),
  }

যুক্তি : TFDS মূল ডেটার মতোই ডেটাসেটগুলি সরবরাহ করার চেষ্টা করে৷ সাব-স্প্লিট API ব্যবহার করা উচিত ব্যবহারকারীদের গতিশীলভাবে তাদের পছন্দের সাবস্প্লিট তৈরি করতে দেওয়ার জন্য:

ds_train, ds_test = tfds.load(..., split=['train[:80%]', 'train[80%:]'])

পাইথন শৈলী গাইড

pathlib API ব্যবহার করতে পছন্দ করুন

tf.io.gfile API-এর পরিবর্তে, pathlib API ব্যবহার করা বাঞ্ছনীয়। সমস্ত dl_manager পদ্ধতি GCS, S3,... এর সাথে সামঞ্জস্যপূর্ণ pathlib-এর মতো বস্তু প্রদান করে।

path = dl_manager.download_and_extract('http://some-website/my_data.zip')

json_path = path / 'data/file.json'

json.loads(json_path.read_text())

যুক্তি : pathlib API হল একটি আধুনিক অবজেক্ট ওরিয়েন্টেড ফাইল API যা বয়লারপ্লেট অপসারণ করে। .read_text() / .read_bytes() ব্যবহার করে ফাইলগুলি সঠিকভাবে বন্ধ হওয়ার নিশ্চয়তা দেয়।

যদি পদ্ধতিটি self ব্যবহার না করে তবে এটি একটি ফাংশন হওয়া উচিত

যদি একটি ক্লাস পদ্ধতি self ব্যবহার না করে তবে এটি একটি সাধারণ ফাংশন হওয়া উচিত (ক্লাসের বাইরে সংজ্ঞায়িত)।

যুক্তি : এটি পাঠকের কাছে এটি স্পষ্ট করে তোলে যে ফাংশনের পার্শ্ব প্রতিক্রিয়া নেই, বা লুকানো ইনপুট/আউটপুট নেই:

x = f(y)  # Clear inputs/outputs

x = self.f(y)  # Does f depend on additional hidden variables ? Is it stateful ?

পাইথনে অলস আমদানি

আমরা অলসভাবে TensorFlow এর মত বড় মডিউল আমদানি করি। অলস আমদানি মডিউলটির প্রকৃত আমদানিকে মডিউলের প্রথম ব্যবহারে পিছিয়ে দেয়। সুতরাং যে ব্যবহারকারীদের এই বড় মডিউলটির প্রয়োজন নেই তারা কখনই এটি আমদানি করবে না। আমরা etils.epy.lazy_imports ব্যবহার করি।

from tensorflow_datasets.core.utils.lazy_imports_utils import tensorflow as tf
# After this statement, TensorFlow is not imported yet

...

features = tfds.features.Image(dtype=tf.uint8)
# After using it (`tf.uint8`), TensorFlow is now imported

হুডের নিচে, LazyModule ক্লাস একটি ফ্যাক্টরি হিসেবে কাজ করে, যেটি আসলে মডিউলটি আমদানি করবে যখন একটি অ্যাট্রিবিউট অ্যাক্সেস করা হয় ( __getattr__ )।

আপনি এটি একটি প্রসঙ্গ পরিচালকের সাথে সুবিধাজনকভাবে ব্যবহার করতে পারেন:

from etils import epy

with epy.lazy_imports(error_callback=..., success_callback=...):
  import some_big_module