مساعدة في حماية الحاجز المرجاني العظيم مع TensorFlow على Kaggle تاريخ التحدي

كتابة مجموعات البيانات المخصصة

اتبع هذا الدليل لإنشاء مجموعة بيانات جديدة (إما في TFDS أو في المستودع الخاص بك).

تحقق لدينا قائمة من قواعد البيانات لمعرفة ما إذا كانت مجموعة البيانات التي تريد موجود بالفعل.

TL ؛ DR

أسهل طريقة لكتابة بيانات جديدة هي استخدام TFDS CLI :

cd path/to/my/project/datasets/
tfds new my_dataset  # Create `my_dataset/my_dataset.py` template files
# [...] Manually modify `my_dataset/my_dataset.py` to implement your dataset.
cd my_dataset/
tfds build  # Download and prepare the dataset to `~/tensorflow_datasets/`

لاستخدام بيانات جديدة مع tfds.load('my_dataset') :

  • tfds.load تلقائيا كشف وتحميل مجموعة البيانات ولدت في ~/tensorflow_datasets/my_dataset/ (على سبيل المثال عن طريق tfds build ).
  • بدلا من ذلك، يمكنك بشكل صريح import my.project.datasets.my_dataset لتسجيل بيانات الخاصة بك:
import my.project.datasets.my_dataset  # Register `my_dataset`

ds = tfds.load('my_dataset')  # `my_dataset` registered

ملخص

يتم توزيع مجموعات البيانات بجميع أنواع التنسيقات وفي جميع أنواع الأماكن ، ولا يتم تخزينها دائمًا بتنسيق جاهز لإدخاله في خط أنابيب التعلم الآلي. أدخل TFDS.

TFDS تجهيز تلك قواعد البيانات في شكل موحد (البيانات الخارجية -> ملفات تسلسل)، ومن ثم يمكن تحميلها كما خط أنابيب آلة التعلم (ملفات تسلسل -> tf.data.Dataset ). يتم إجراء التسلسل مرة واحدة فقط. سيقرأ الوصول اللاحق من تلك الملفات المعالجة مسبقًا مباشرةً.

تتم معظم عمليات المعالجة المسبقة تلقائيًا. كل الأدوات بيانات فئة فرعية من tfds.core.DatasetBuilder ، الذي يحدد:

  • من أين تأتي البيانات (أي عناوين URL الخاصة بها) ؛
  • كيف تبدو مجموعة البيانات (أي ميزاتها) ؛
  • كيف يجب أن تكون البيانات انقسام (على سبيل المثال TRAIN و TEST
  • والأمثلة الفردية في مجموعة البيانات.

اكتب مجموعة البيانات الخاصة بك

القالب الافتراضي: tfds new

استخدام TFDS CLI لإنشاء ملفات الثعبان القالب المطلوب.

cd path/to/project/datasets/  # Or use `--dir=path/to/project/datasets/` below
tfds new my_dataset

وهذا الأمر يولد الجديد my_dataset/ المجلد مع البنية التالية:

my_dataset/
    __init__.py
    my_dataset.py # Dataset definition
    my_dataset_test.py # (optional) Test
    dummy_data/ # (optional) Fake data (used for testing)
    checksum.tsv # (optional) URL checksums (see `checksums` section).

البحث عن TODO(my_dataset) هنا وتعديل وفقا لذلك.

مثال على مجموعة البيانات

يتم تنفيذ جميع قواعد البيانات كما tfds.core.GeneratorBasedBuilder ، والفئات الفرعية من tfds.core.DatasetBuilder الذي يهتم معظم النمطي. انها تؤيد:

  • مجموعات البيانات الصغيرة / المتوسطة التي يمكن إنشاؤها على جهاز واحد (هذا البرنامج التعليمي).
  • مجموعات البيانات الكبيرة جدا والتي تتطلب التوليد الموزع (باستخدام أباتشي شعاع ، انظر لدينا دليل بيانات ضخمة )

فيما يلي مثال بسيط لفئة مجموعة البيانات:

class MyDataset(tfds.core.GeneratorBasedBuilder):
  """DatasetBuilder for my_dataset dataset."""

  VERSION = tfds.core.Version('1.0.0')
  RELEASE_NOTES = {
      '1.0.0': 'Initial release.',
  }

  def _info(self) -> tfds.core.DatasetInfo:
    """Dataset metadata (homepage, citation,...)."""
    return tfds.core.DatasetInfo(
        builder=self,
        features=tfds.features.FeaturesDict({
            'image': tfds.features.Image(shape=(256, 256, 3)),
            'label': tfds.features.ClassLabel(names=['no', 'yes']),
        }),
    )

  def _split_generators(self, dl_manager: tfds.download.DownloadManager):
    """Download the data and define splits."""
    extracted_path = dl_manager.download_and_extract('http://data.org/data.zip')
    # dl_manager returns pathlib-like objects with `path.read_text()`,
    # `path.iterdir()`,...
    return {
        'train': self._generate_examples(path=extracted_path / 'train_images'),
        'test': self._generate_examples(path=extracted_path / 'test_images'),
    }

  def _generate_examples(self, path) -> Iterator[Tuple[Key, Example]]:
    """Generator of examples for each split."""
    for img_path in path.glob('*.jpeg'):
      # Yields (key, example)
      yield img_path.name, {
          'image': img_path,
          'label': 'yes' if img_path.name.startswith('yes_') else 'no',
      }

دعونا نرى بالتفصيل الطرق المجردة الثلاثة للكتابة فوقها.

_info : مجموعة البيانات الفوقية

_info عوائد tfds.core.DatasetInfo التي تحتوي على بيانات التعريف بيانات .

def _info(self):
  return tfds.core.DatasetInfo(
      builder=self,
      # Description and homepage used for documentation
      description="""
      Markdown description of the dataset. The text will be automatically
      stripped and dedent.
      """,
      homepage='https://dataset-homepage.org',
      features=tfds.features.FeaturesDict({
          'image_description': tfds.features.Text(),
          'image': tfds.features.Image(),
          # Here, 'label' can be 0-4.
          'label': tfds.features.ClassLabel(num_classes=5),
      }),
      # If there's a common `(input, target)` tuple from the features,
      # specify them here. They'll be used if as_supervised=True in
      # builder.as_dataset.
      supervised_keys=('image', 'label'),
      # Specify whether to disable shuffling on the examples. Set to False by default.
      disable_shuffling=False,
      # Bibtex citation for the dataset
      citation=r"""
      @article{my-awesome-dataset-2020,
               author = {Smith, John},}
      """,
  )

يجب أن تكون معظم الحقول لا تحتاج إلى شرح. بعض الدقة:

  • features : هذا تحديد هيكل مجموعة البيانات والشكل و... دعم الأنواع المعقدة البيانات (الصوت والفيديو ومتواليات متداخلة، ...). اطلع على الميزات المتوفرة أو دليل موصل ميزة للمزيد من المعلومات.
  • disable_shuffling : انظر القسم الحفاظ على بيانات النظام .
  • citation : للعثور على BibText الاقتباس:
    • ابحث في موقع الويب الخاص بمجموعة البيانات عن تعليمات الاقتباس (استخدم ذلك بتنسيق BibTex).
    • ل أرخايف أوراق: العثور على ورقة وانقر على BibText الموجود على الجانب الأيمن.
    • العثور على ورقة على الباحث العلمي من Google وانقر على علامة اقتباس مزدوجة تحت عنوان وعلى المنبثقة، انقر فوق BibTeX .
    • إذا كان هناك أي ورقة المرتبطة (على سبيل المثال، هناك فقط موقع على شبكة الانترنت)، يمكنك استخدام محرر ببتخ اون لاين لإنشاء ببتخ دخول مخصصة (القائمة المنسدلة لها Online نوع الدخول).

الحفاظ على ترتيب مجموعة البيانات

بشكل افتراضي ، يتم خلط سجلات مجموعات البيانات عند تخزينها لجعل توزيع الفئات أكثر اتساقًا عبر مجموعة البيانات ، نظرًا لأن السجلات التي تنتمي إلى نفس الفئة غالبًا ما تكون متجاورة. من أجل تحديد أن مجموعة البيانات يجب أن يتم فرز بواسطة مفتاح ولدت التي تقدمها _generate_examples مجال disable_shuffling يجب تعيين إلى True . افتراضيا يتم تعيين إلى False .

def _info(self):
  return tfds.core.DatasetInfo(
    # [...]
    disable_shuffling=True,
    # [...]
  )

ضع في اعتبارك أن تعطيل التبديل العشوائي له تأثير على الأداء حيث لا يمكن قراءة الأجزاء بالتوازي بعد الآن.

_split_generators : التنزيلات والانقسامات البيانات

تنزيل واستخراج بيانات المصدر

تحتاج معظم مجموعات البيانات إلى تنزيل البيانات من الويب. ويتم ذلك باستخدام tfds.download.DownloadManager حجة مدخلات _split_generators . dl_manager ديه الأساليب التالية:

  • download : يدعم http(s):// ، ftp(s)://
  • extract : حاليا يدعم .zip ، .gz ، و .tar الملفات.
  • download_and_extract : نفس dl_manager.extract(dl_manager.download(urls))

كل تلك الأساليب ترجع tfds.core.ReadOnlyPath ، والتي هي pathlib.Path مثل الكائنات.

هذه الأساليب التعسفية يدعم بنية متداخلة ( list ، dict )، مثل:

extracted_paths = dl_manager.download_and_extract({
    'foo': 'https://example.com/foo.zip',
    'bar': 'https://example.com/bar.zip',
})
# This returns:
assert extracted_paths == {
    'foo': Path('/path/to/extracted_foo/'),
    'bar': Path('/path/extracted_bar/'),
}

تنزيل يدوي واستخراج

بعض البيانات لا يمكن تحميلها تلقائيا (على سبيل المثال يتطلب تسجيل الدخول)، في هذه الحالة، سوف المستخدم يدويا تحميل البيانات المصدر ووضعه في manual_dir/ (الافتراضي ~/tensorflow_datasets/downloads/manual/ ).

ومن ثم يمكن الوصول إليها من خلال الملفات dl_manager.manual_dir :

class MyDataset(tfds.core.GeneratorBasedBuilder):

  MANUAL_DOWNLOAD_INSTRUCTIONS = """
  Register into https://example.org/login to get the data. Place the `data.zip`
  file in the `manual_dir/`.
  """

  def _split_generators(self, dl_manager):
    # data_path is a pathlib-like `Path('<manual_dir>/data.zip')`
    archive_path = dl_manager.manual_dir / 'data.zip'
    # Extract the manually downloaded `data.zip`
    extracted_path = dl_manager.extract(archive_path)
    ...

و manual_dir موقع يمكن تخصيص مع tfds build --manual_dir= أو باستخدام tfds.download.DownloadConfig .

قراءة الأرشيف مباشرة

dl_manager.iter_archive يقرأ والمحفوظات بالتتابع دون استخراج لهم. يمكن أن يؤدي ذلك إلى توفير مساحة التخزين وتحسين الأداء في بعض أنظمة الملفات.

for filename, fobj in dl_manager.iter_archive('path/to/archive.zip'):
  ...

fobj لديه نفس الأساليب كما with open('rb') as fobj: (على سبيل المثال fobj.read() )

تحديد تقسيمات مجموعة البيانات

إذا كانت مجموعة البيانات يأتي مع الانقسامات-محددة مسبقا (على سبيل المثال MNIST ديه train و test انشقاقات)، والحفاظ على تلك. خلاف ذلك، حدد واحد فقط tfds.Split.TRAIN الانقسام. يمكن للمستخدمين إنشاء حيوي subsplits الخاصة بهم مع API subsplit (على سبيل المثال split='train[80%:]' ).

def _split_generators(self, dl_manager):
  # Download source data
  extracted_path = dl_manager.download_and_extract(...)

  # Specify the splits
  return {
      'train': self._generate_examples(
          images_path=extracted_path / 'train_imgs',
          label_path=extracted_path / 'train_labels.csv',
      ),
      'test': self._generate_examples(
          images_path=extracted_path / 'test_imgs',
          label_path=extracted_path / 'test_labels.csv',
      ),
  }

_generate_examples : مولد مثال

_generate_examples يولد الأمثلة لكل انشق عن مصدر البيانات.

وهذه الطريقة سوف تقرأ عادة التحف بيانات المصدر (مثل CSV ملف) والعائد (key, feature_dict) الصفوف:

  • key : مثال المعرف. تستخدم لحتمي خلط الأمثلة باستخدام hash(key) أو إلى نوع من مفتاح عند تعطيل خلط (انظر القسم الحفاظ على بيانات النظام ). يجب ان يكون:
    • فريدة من نوعها: إذا مثالين استخدام نفس المفتاح، وسيتم طرح استثناء.
    • حتمية: يجب أن لا تعتمد على download_dir ، os.path.listdir النظام، ... توليد البيانات مرتين ينبغي أن تسفر نفس المفتاح.
    • مقارنة: إذا تم تعطيل خلط مفتاح ستستخدم لفرز البيانات.
  • feature_dict : A dict التي تحتوي على قيم سبيل المثال.
    • الهيكل يجب أن يتطابق مع features= بنية المعرفة في tfds.core.DatasetInfo .
    • سيتم تشفير أنواع البيانات المعقدة (صورة ، فيديو ، صوت ، ...) تلقائيًا.
    • كل ميزة في كثير من الأحيان يقبل أنواع المدخلات متعددة (على سبيل المثال الفيديو يقبل /path/to/vid.mp4 ، np.array(shape=(l, h, w, c)) ، List[paths] ، List[np.array(shape=(h, w, c)] ، List[img_bytes] ، ...)
    • انظر دليل موصل ميزة للمزيد من المعلومات.
def _generate_examples(self, images_path, label_path):
  # Read the input data out of the source files
  with label_path.open() as f:
    for row in csv.DictReader(f):
      image_id = row['image_id']
      # And yield (key, feature_dict)
      yield image_id, {
          'image_description': row['description'],
          'image': images_path / f'{image_id}.jpeg',
          'label': row['label'],
      }

الوصول إلى الملفات و tf.io.gfile

من أجل دعم أنظمة التخزين السحابية ، تجنب استخدام عمليات الإدخال / الإخراج المضمنة في Python.

بدلا من ذلك، dl_manager عوائد pathlib مثل الأجسام متوافقة مباشرة مع التخزين في السحاب من Google:

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

json_path = path / 'data/file.json'

json.loads(json_path.read_text())

بدلا من ذلك، استخدم tf.io.gfile API بدلا من المدمج في لعمليات ملف:

يجب أن يفضل Pathlib إلى tf.io.gfile (انظر عقلانية .

التبعيات الإضافية

تتطلب بعض مجموعات البيانات تبعيات Python إضافية أثناء الإنشاء فقط. على سبيل المثال، يستخدم SVHN بيانات scipy لتحميل بعض البيانات.

إذا كنت تقوم بإضافة مجموعة البيانات في مستودع TFDS، يرجى استخدام tfds.core.lazy_imports للحفاظ على tensorflow-datasets مجموعة صغيرة. سيقوم المستخدمون بتثبيت تبعيات إضافية حسب الحاجة فقط.

لاستخدام lazy_imports :

  • إضافة إدخال بيانات الخاصة بك إلى DATASET_EXTRAS في setup.py . هذا يجعل من ذلك أنه يمكن للمستخدمين القيام به، على سبيل المثال، pip install 'tensorflow-datasets[svhn]' لتثبيت تبعيات إضافية.
  • إضافة إدخال للاستيراد الخاص ل LazyImporter وإلى LazyImportsTest .
  • استخدام tfds.core.lazy_imports للوصول إلى الاعتماد (على سبيل المثال، tfds.core.lazy_imports.scipy ) في حياتك DatasetBuilder .

بيانات تالفة

بعض مجموعات البيانات ليست نظيفة تمامًا وتحتوي على بعض البيانات الفاسدة (على سبيل المثال ، الصور موجودة في ملفات JPEG لكن بعضها غير صالح بتنسيق JPEG). يجب تخطي هذه الأمثلة ، ولكن اترك ملاحظة في وصف مجموعة البيانات عن عدد الأمثلة التي تم إسقاطها ولماذا.

تكوين / متغيرات مجموعة البيانات (tfds.core.BuilderConfig)

قد تحتوي بعض مجموعات البيانات على متغيرات متعددة ، أو خيارات لكيفية معالجة البيانات مسبقًا وكتابتها على القرص. على سبيل المثال، cycle_gan ديه التكوين واحد لكل أزواج الكائن ( cycle_gan/horse2zebra ، cycle_gan/monet2photo ، ...).

ويتم ذلك من خلال tfds.core.BuilderConfig الصورة:

  1. تحديد كائن تكوين ك فئة فرعية من tfds.core.BuilderConfig . على سبيل المثال، MyDatasetConfig .

    @dataclasses.dataclass
    class MyDatasetConfig(tfds.core.BuilderConfig):
      img_size: Tuple[int, int] = (0, 0)
    
  2. تحديد BUILDER_CONFIGS = [] عضو فئة في MyDataset التي تسرد MyDatasetConfig الصورة التي تم الكشف عن مجموعة البيانات.

    class MyDataset(tfds.core.GeneratorBasedBuilder):
      VERSION = tfds.core.Version('1.0.0')
      # pytype: disable=wrong-keyword-args
      BUILDER_CONFIGS = [
          # `name` (and optionally `description`) are required for each config
          MyDatasetConfig(name='small', description='Small ...', img_size=(8, 8)),
          MyDatasetConfig(name='big', description='Big ...', img_size=(32, 32)),
      ]
      # pytype: enable=wrong-keyword-args
    
  3. استخدام self.builder_config في MyDataset لتوليد البيانات تكوين (على سبيل المثال shape=self.builder_config.img_size ). وقد يشمل ذلك تحديد قيم مختلفة في _info() أو تغيير الوصول تحميل البيانات.

ملحوظات:

  • كل تكوين له اسم فريد. اسم مؤهل بشكل كامل من التكوين هو dataset_name/config_name (مثل coco/2017 ).
  • إذا لم يكن محددا، التكوين الأولى في BUILDER_CONFIGS سيتم استخدام (على سبيل المثال tfds.load('c4') الافتراضية إلى c4/en )

انظر anli مثالا لمجموعة البيانات التي تستخدم BuilderConfig الصورة.

الإصدار

يمكن أن يشير الإصدار إلى معنيين مختلفين:

  • إصدار البيانات الأصلية "الخارجية": على سبيل المثال COCO v2019، v2017، ...
  • في "الداخلية" TFDS رمز إصدار: على سبيل المثال إعادة تسمية ميزة في tfds.features.FeaturesDict ، إصلاح خلل في _generate_examples

لتحديث مجموعة بيانات:

  • لتحديث البيانات "الخارجية": قد يرغب العديد من المستخدمين في الوصول إلى سنة / إصدار معين في وقت واحد. ويتم ذلك باستخدام أحد tfds.core.BuilderConfig في نسخة (على سبيل المثال coco/2017 ، coco/2019 ) أو فئة واحدة في نسخة (على سبيل المثال Voc2007 ، Voc2012 ).
  • لتحديث الكود "الداخلي": يقوم المستخدمون بتنزيل أحدث إصدار فقط. أي تحديث كود يجب أن تزيد من VERSION سمة فئة (على سبيل المثال من 1.0.0 إلى VERSION = tfds.core.Version('2.0.0') ) عقب الإصدارات الدلالي .

إضافة استيراد للتسجيل

لا ننسى لاستيراد وحدة بيانات لمشروعك __init__ أن تكون مسجلة تلقائيا في tfds.load ، tfds.builder .

import my_project.datasets.my_dataset  # Register MyDataset

ds = tfds.load('my_dataset')  # MyDataset available

على سبيل المثال، إذا كنت المساهمة في tensorflow/datasets ، إضافة إلى استيراد وحدة الدليل الخاص في __init__.py (على سبيل المثال image/__init__.py .

تحقق من مشاكل التنفيذ الشائعة

يرجى مراجعة ل gotchas التنفيذ المشتركة .

اختبر مجموعة البيانات الخاصة بك

تحميل وإعداد: tfds build

لإنشاء مجموعة البيانات، تشغيل tfds build من my_dataset/ الدليل:

cd path/to/datasets/my_dataset/
tfds build --register_checksums

بعض العلامات المفيدة للتطوير:

  • --pdb : أدخل وضع التصحيح إذا تم رفع استثناء.
  • --overwrite : حذف الملفات الموجودة إذا تم إنشاء مجموعة البيانات بالفعل.
  • --max_examples_per_split : توليد فقط الأمثلة الأولى X (الافتراضي إلى 1)، بدلا من البيانات الكاملة.
  • --register_checksums : سجل اختبارية من عناوين المواقع التي تم تحميلها. يجب استخدامه فقط أثناء التطوير.

اطلع على وثائق CLI عن القائمة الكاملة للأعلام.

المجاميع الاختبارية

فمن المستحسن لتسجيل اختبارية من قواعد البيانات لضمان الحتمية، والمساعدة مع الوثائق، ... ويتم ذلك عن طريق توليد بيانات مع --register_checksums (انظر القسم السابق).

إذا كنت الافراج عن مجموعات البيانات الخاصة بك من خلال PyPI، لا ننسى لتصدير checksums.tsv الملفات (على سبيل المثال في package_data الخاص بك setup.py ).

وحدة اختبار مجموعة البيانات الخاصة بك

tfds.testing.DatasetBuilderTestCase هو قاعدة TestCase لممارسة كامل مجموعة البيانات. ويستخدم "البيانات الوهمية" كبيانات اختبار تحاكي بنية مجموعة البيانات المصدر.

  • وينبغي وضع بيانات الاختبار في my_dataset/dummy_data/ الدليل، وينبغي أن تحاكي التحف مصدر بيانات كما تحميلها واستخراجها. ويمكن إنشاؤها يدويا أو تلقائيا مع برنامج نصي ( مثال البرنامج النصي ).
  • تأكد من استخدام بيانات مختلفة في تقسيمات بيانات الاختبار ، حيث سيفشل الاختبار إذا تداخلت أقسام مجموعة البيانات.
  • يجب أن لا تحتوي على بيانات الاختبار أي مواد محفوظة الحقوق. إذا كنت في شك ، فلا تنشئ البيانات باستخدام مادة من مجموعة البيانات الأصلية.
import tensorflow_datasets as tfds
from . import my_dataset


class MyDatasetTest(tfds.testing.DatasetBuilderTestCase):
  """Tests for my_dataset dataset."""
  DATASET_CLASS = my_dataset.MyDataset
  SPLITS = {
      'train': 3,  # Number of fake train example
      'test': 1,  # Number of fake test example
  }

  # If you are calling `download/download_and_extract` with a dict, like:
  #   dl_manager.download({'some_key': 'http://a.org/out.txt', ...})
  # then the tests needs to provide the fake output paths relative to the
  # fake data directory
  DL_EXTRACT_RESULT = {
      'name1': 'path/to/file1',  # Relative to dummy_data/my_dataset dir.
      'name2': 'file2',
  }


if __name__ == '__main__':
  tfds.testing.test_main()

قم بتشغيل الأمر التالي لاختبار مجموعة البيانات.

python my_dataset_test.py

أرسل لنا ردود الفعل

نحاول باستمرار تحسين سير عمل إنشاء مجموعة البيانات ، ولكن لا يمكننا القيام بذلك إلا إذا كنا على دراية بالمشكلات. ما المشكلات والأخطاء التي واجهتها أثناء إنشاء مجموعة البيانات؟ هل كان هناك جزء كان محيرًا أو معياريًا أو لا يعمل في المرة الأولى؟ يرجى نشاطركم ردود الفعل على جيثب .