Özel veri kümeleri yazma

Bu kılavuzu izleyerek (TFDS'de veya kendi deponuzda) yeni bir veri seti oluşturabilirsiniz.

İstediğiniz veri setinin mevcut olup olmadığını görmek için veri setleri listemizi kontrol edin.

Özetle

Yeni bir veri seti yazmanın en kolay yolu TFDS CLI'yı kullanmaktır:

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

Yeni veri setini tfds.load('my_dataset') ile kullanmak için:

  • tfds.load , ~/tensorflow_datasets/my_dataset/ dizininde oluşturulan veri setini (örneğin tfds build komutuyla) otomatik olarak algılar ve yükler.
  • Alternatif olarak, veri setinizi kaydetmek için import my.project.datasets.my_dataset aktarabilirsiniz:
import my.project.datasets.my_dataset  # Register `my_dataset`

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

Genel Bakış

Veri kümeleri her türlü formatta ve her türlü yerde dağıtılır ve her zaman makine öğrenimi işlem hattına beslenmeye hazır bir formatta saklanmazlar. İşte burada TFDS devreye giriyor.

TFDS, bu veri kümelerini standart bir biçime (harici veri -> serileştirilmiş dosyalar) dönüştürür ve bu dosyalar daha sonra makine öğrenimi işlem hattına (serileştirilmiş dosyalar -> tf.data.Dataset ) yüklenebilir. Serileştirme işlemi yalnızca bir kez yapılır. Sonraki erişimler, önceden işlenmiş bu dosyalardan doğrudan okuma yapacaktır.

Ön işlemenin büyük kısmı otomatik olarak yapılır. Her veri seti, tfds.core.DatasetBuilder bir alt sınıfını uygular ve bu sınıf şunları belirtir:

  • Verilerin nereden geldiği (yani URL'leri);
  • Veri kümesinin görünümü (yani özellikleri);
  • Verilerin nasıl bölünmesi gerektiği (örneğin TRAIN ve TEST );
  • ve veri kümesindeki bireysel örnekler.

Veri setinizi yazın.

Varsayılan şablon: tfds new

Gerekli şablon Python dosyalarını oluşturmak için TFDS CLI'yı kullanın.

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

Bu komut, aşağıdaki yapıya sahip yeni bir my_dataset/ klasörü oluşturacaktır:

my_dataset/
    __init__.py
    README.md # Markdown description of the dataset.
    CITATIONS.bib # Bibtex citation for the dataset.
    TAGS.txt # List of tags describing the dataset.
    my_dataset_dataset_builder.py # Dataset definition
    my_dataset_dataset_builder_test.py # Test
    dummy_data/ # (optional) Fake data (used for testing)
    checksum.tsv # (optional) URL checksums (see `checksums` section).

Burada TODO(my_dataset) ifadesini arayın ve buna göre düzenleyin.

Veri kümesi örneği

Tüm veri kümeleri, çoğu tekrarlayan kodu halleden tfds.core.DatasetBuilder alt sınıfları olarak uygulanmıştır. Şunları destekler:

İşte tfds.core.GeneratorBasedBuilder temel alan minimal bir veri seti oluşturucu örneği:

class Builder(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 self.dataset_info_from_configs(
        features=tfds.features.FeaturesDict({
            'image': tfds.features.Image(shape=(256, 256, 3)),
            'label': tfds.features.ClassLabel(
                names=['no', 'yes'],
                doc='Whether this is a picture of a cat'),
        }),
    )

  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',
      }

Bazı özel veri formatları için, veri işlemenin büyük bir kısmını üstlenecek kullanıma hazır veri seti oluşturucuları sağladığımızı lütfen unutmayın.

Şimdi, üzerine yazılacak 3 soyut yöntemi ayrıntılı olarak inceleyelim.

_info : veri kümesi meta verileri

_info veri kümesi meta verilerini içeren tfds.core.DatasetInfo döndürür.

def _info(self):
  # The `dataset_info_from_configs` base method will construct the
  # `tfds.core.DatasetInfo` object using the passed-in parameters and
  # adding: builder (self), description/citations/tags from the config
  # files located in the same package.
  return self.dataset_info_from_configs(
      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,
  )

Çoğu alanın açıklaması kendiliğinden anlaşılır olmalıdır. Bazı açıklamalar:

BibText CITATIONS.bib dosyasını yazma:

  • Veri seti web sitesinde alıntı yapma talimatlarını arayın (BibTex formatında kullanın).
  • arXiv makaleleri için: makaleyi bulun ve sağ taraftaki BibText bağlantısına tıklayın.
  • Makaleyi Google Scholar'da bulun ve başlığın altındaki çift tırnak işaretine tıklayın, açılan pencerede ise BibTeX seçin.
  • Eğer ilgili bir makale yoksa (örneğin, sadece bir web sitesi varsa), özel bir BibTeX girdisi oluşturmak için BibTeX Çevrimiçi Düzenleyicisini kullanabilirsiniz (açılır menüde Online girdi türü seçeneği bulunur).

TAGS.txt dosyasını güncelleme:

  • Oluşturulan dosyada izin verilen tüm etiketler önceden doldurulmuştur.
  • Veri kümesiyle ilgili olmayan tüm etiketleri kaldırın.
  • Geçerli etiketler tensorflow_datasets/core/valid_tags.txt dosyasında listelenmiştir.
  • Bu listeye etiket eklemek için lütfen bir pull request gönderin.

Veri kümesinin sırasını koruyun.

Varsayılan olarak, veri kümelerindeki kayıtlar, veri kümesi genelinde sınıfların dağılımını daha homojen hale getirmek için depolanırken karıştırılır, çünkü genellikle aynı sınıfa ait kayıtlar ardışıktır. Veri kümesinin _generate_examples tarafından sağlanan anahtara göre sıralanmasını belirtmek için disable_shuffling alanı True olarak ayarlanmalıdır. Varsayılan olarak False olarak ayarlanmıştır.

def _info(self):
  return self.dataset_info_from_configs(
    # [...]
    disable_shuffling=True,
    # [...]
  )

Karıştırma işlemini devre dışı bırakmanın, parçaların artık paralel olarak okunamaması nedeniyle performans üzerinde olumsuz bir etkisi olduğunu unutmayın.

_split_generators : verileri indirir ve böler.

Kaynak verilerin indirilmesi ve çıkarılması

Çoğu veri seti, web'den veri indirmeyi gerektirir. Bu işlem, _split_generators tfds.download.DownloadManager giriş argümanı kullanılarak yapılır. dl_manager aşağıdaki yöntemlere sahiptir:

  • download : http(s):// ve ftp(s):// adreslerini destekler.
  • extract : şu anda .zip , .gz ve .tar dosyalarını desteklemektedir.
  • download_and_extract : dl_manager.extract(dl_manager.download(urls)) ile aynıdır.

Bu yöntemlerin tümü, pathlib.Path benzeri nesneler olan tfds.core.Path ( epath.Path diğer adları) döndürür.

Bu yöntemler, aşağıdaki gibi keyfi iç içe yapıları ( list , dict ) destekler:

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/'),
}

Manuel indirme ve çıkarma

Bazı veriler otomatik olarak indirilemez (örneğin oturum açmayı gerektirir), bu durumda kullanıcı kaynak verileri manuel olarak indirip manual_dir/ dizinine yerleştirecektir (varsayılan olarak ~/tensorflow_datasets/downloads/manual/ ).

Dosyalara daha sonra dl_manager.manual_dir aracılığıyla erişilebilir:

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 konumu, tfds build --manual_dir= komutuyla veya tfds.download.DownloadConfig kullanılarak özelleştirilebilir.

Arşivi doğrudan okuyun

dl_manager.iter_archive arşivleri ayıklamadan, sırayla okur. Bu, bazı dosya sistemlerinde depolama alanından tasarruf sağlayabilir ve performansı artırabilir.

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

fobj with open('rb') as fobj: (örneğin fobj.read() )

Veri kümesi bölümlerini belirtme

Eğer veri seti önceden tanımlanmış bölümlerle geliyorsa (örneğin MNIST train ve test bölümleri varsa), bunları koruyun. Aksi takdirde, yalnızca tek bir " all bölümü belirtin. Kullanıcılar, alt bölüm API'si ile dinamik olarak kendi alt bölümlerini oluşturabilirler (örneğin split='train[80%:]' ). Yukarıda belirtilen " all dışında herhangi bir alfabetik dizenin bölüm adı olarak kullanılabileceğini unutmayın.

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 : Örnek oluşturucu

_generate_examples kaynak verilerden her bir bölüm için örnekler oluşturur.

Bu yöntem tipik olarak kaynak veri kümesi öğelerini (örneğin bir CSV dosyası) okuyacak ve (key, feature_dict) ikilileri üretecektir:

  • key : Örnek tanımlayıcı. Örnekleri hash(key) kullanarak deterministik olarak karıştırmak veya karıştırma devre dışı bırakıldığında key'e göre sıralamak için kullanılır ( Veri kümesi sırasını koruma bölümüne bakın). Şu şekilde olmalıdır:
    • Benzersiz : İki örnek aynı anahtarı kullanırsa, bir istisna fırlatılacaktır.
    • Belirleyici : download_dir , os.path.listdir sırasına bağlı olmamalıdır... Verilerin iki kez oluşturulması aynı anahtarı vermelidir.
    • Karşılaştırılabilir : Karıştırma devre dışı bırakılırsa, veri kümesini sıralamak için anahtar kullanılacaktır.
  • feature_dict : Örnek değerleri içeren bir dict .
    • Yapı tfds.core.DatasetInfo tanımlanan features= yapısıyla eşleşmelidir.
    • Karmaşık veri tipleri (resim, video, ses,...) otomatik olarak kodlanacaktır.
    • Her özellik genellikle birden fazla giriş türünü kabul eder (örneğin video, /path/to/vid.mp4 , np.array(shape=(l, h, w, c)) , List[paths] , List[np.array(shape=(h, w, c)] , List[img_bytes] ,...).
    • Daha fazla bilgi için özellik bağlantı kılavuzuna bakın.
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'],
      }

Dosya erişimi ve tf.io.gfile

Bulut depolama sistemlerini desteklemek için Python'ın yerleşik G/Ç işlemlerini kullanmaktan kaçının.

Bunun yerine, dl_manager doğrudan Google Cloud depolama ile uyumlu pathlib benzeri nesneler döndürür:

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

json_path = path / 'data/file.json'

json.loads(json_path.read_text())

Alternatif olarak, dosya işlemleri için yerleşik API yerine tf.io.gfile API'sini kullanabilirsiniz:

Pathlib, tf.io.gfile tercih edilmelidir (bkz. rational .

Ek bağımlılıklar

Bazı veri kümeleri, yalnızca oluşturma aşamasında ek Python bağımlılıkları gerektirir. Örneğin, SVHN veri kümesi bazı verileri yüklemek için scipy kullanır.

TFDS deposuna veri seti ekliyorsanız, tensorflow-datasets paketinin boyutunu küçük tutmak için lütfen tfds.core.lazy_imports kullanın. Kullanıcılar ek bağımlılıkları yalnızca ihtiyaç duyduklarında yükleyecektir.

lazy_imports kullanmak için:

  • Veri setiniz için setup.py dosyasındaki DATASET_EXTRAS bölümüne bir giriş ekleyin. Bu sayede kullanıcılar, örneğin pip install 'tensorflow-datasets[svhn]' kullanarak ek bağımlılıkları yükleyebilirler.
  • İçe aktarma işleminiz için LazyImporter ve LazyImportsTest bir giriş ekleyin.
  • DatasetBuilder bağımlılığa (örneğin, tfds.core.lazy_imports.scipy ) erişmek için tfds.core.lazy_imports kullanın.

Bozuk veriler

Bazı veri kümeleri tamamen temiz değildir ve bazı bozuk veriler içerir (örneğin, resimler JPEG dosyalarındadır ancak bazıları geçersiz JPEG'dir). Bu örnekler atlanmalıdır, ancak veri kümesi açıklamasında kaç örneğin atlandığı ve neden atlandığı belirtilmelidir.

Veri kümesi yapılandırması/varyantları (tfds.core.BuilderConfig)

Bazı veri kümelerinin, verilerin ön işlenmesi ve diske yazılması için birden fazla varyantı veya seçeneği olabilir. Örneğin, cycle_gan'ın her nesne çifti için bir yapılandırması vardır ( cycle_gan/horse2zebra , cycle_gan/monet2photo ,...).

Bu işlem tfds.core.BuilderConfig aracılığıyla yapılır:

  1. Yapılandırma nesnenizi tfds.core.BuilderConfig sınıfının bir alt sınıfı olarak tanımlayın. Örneğin, MyDatasetConfig .

    @dataclasses.dataclass
    class MyDatasetConfig(tfds.core.BuilderConfig):
      img_size: Tuple[int, int] = (0, 0)
    
  2. MyDataset sınıfında, veri kümesinin sunduğu MyDatasetConfig listeleyen BUILDER_CONFIGS = [] sınıf üyesini tanımlayın.

    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. MyDataset self.builder_config kullanarak veri üretimini yapılandırabilirsiniz (örneğin shape=self.builder_config.img_size ). Bu, _info() 'da farklı değerler ayarlamayı veya veri indirme erişimini değiştirmeyi içerebilir.

Notlar:

  • Her yapılandırma dosyasının benzersiz bir adı vardır. Bir yapılandırma dosyasının tam nitelikli adı dataset_name/config_name şeklindedir (örneğin coco/2017 ).
  • Belirtilmediği takdirde, BUILDER_CONFIGS ilk yapılandırma kullanılacaktır (örneğin tfds.load('c4') varsayılan olarak c4/en kullanır).

BuilderConfig kullanan bir veri kümesi örneği için anli bakın.

Sürüm

Versiyon iki farklı anlama gelebilir:

  • "Harici" orijinal veri sürümü: örneğin COCO v2019, v2017,...
  • "Dahili" TFDS kod sürümü: örneğin tfds.features.FeaturesDict içindeki bir özelliği yeniden adlandırmak, _generate_examples bir hatayı düzeltmek.

Bir veri setini güncellemek için:

  • "Harici" veri güncellemesi için: Birden fazla kullanıcı aynı anda belirli bir yıla/sürüme erişmek isteyebilir. Bu, sürüm başına bir tfds.core.BuilderConfig (örneğin coco/2017 , coco/2019 ) veya sürüm başına bir sınıf (örneğin Voc2007 , Voc2012 ) kullanılarak yapılır.
  • "Dahili" kod güncellemesi için: Kullanıcılar yalnızca en son sürümü indirir. Herhangi bir kod güncellemesi, anlamsal sürümlemeyi takip ederek VERSION sınıf özniteliğini artırmalıdır (örneğin 1.0.0 VERSION = tfds.core.Version('2.0.0') 'a).

Kayıt için içe aktarma ekleyin

tfds.load ve tfds.builder otomatik olarak kaydedilmesi için, veri kümesi modülünü projenizin __init__ metoduna eklemeyi unutmayın.

import my_project.datasets.my_dataset  # Register MyDataset

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

Örneğin, tensorflow/datasets katkıda bulunuyorsanız, modülün içe aktarımını alt dizinindeki __init__.py dosyasına ekleyin (örneğin image/__init__.py ).

Sık karşılaşılan uygulama sorunlarını kontrol edin.

Lütfen uygulama sırasında karşılaşılabilecek yaygın sorunları kontrol edin.

Veri setinizi test edin

İndirin ve hazırlayın: tfds build

Veri setini oluşturmak için, my_dataset/ dizininden tfds build çalıştırın:

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

Geliştirme için bazı faydalı bayraklar:

  • --pdb : Bir istisna oluştuğunda hata ayıklama moduna girin.
  • --overwrite : Veri seti daha önce oluşturulmuşsa mevcut dosyaları siler.
  • --max_examples_per_split : Tüm veri setini değil, yalnızca ilk X örneği (varsayılan olarak 1) oluşturun.
  • --register_checksums : İndirilen URL'lerin sağlama toplamlarını kaydeder. Yalnızca geliştirme aşamasında kullanılmalıdır.

Tüm bayrakların listesi için CLI belgelerine bakın.

Sağlama toplamları

Veri kümelerinizin sağlama toplamlarını kaydetmeniz, kesinliği garanti altına almak, dokümantasyona yardımcı olmak vb. amaçlarla önerilir. Bu işlem, veri kümesini --register_checksums seçeneğiyle oluşturarak yapılır (önceki bölüme bakınız).

Veri kümelerinizi PyPI üzerinden yayınlıyorsanız, checksums.tsv dosyalarını dışa aktarmayı unutmayın (örneğin, setup.py dosyanızın package_data klasöründe).

Veri kümenizi birim testine tabi tutun.

tfds.testing.DatasetBuilderTestCase bir veri kümesini tam olarak test etmek için kullanılan temel bir TestCase senaryosudur. Kaynak veri kümesinin yapısını taklit eden "kukla veriler"i test verisi olarak kullanır.

  • Test verileri my_dataset/dummy_data/ dizinine yerleştirilmeli ve indirilen ve çıkarılan kaynak veri kümesi öğelerini taklit etmelidir. Bu, manuel olarak veya bir komut dosyası ( örnek komut dosyası ) ile otomatik olarak oluşturulabilir.
  • Test verilerinizin farklı veri kümelerini bölmeye aldığınızdan emin olun, çünkü veri kümelerinizin bölmeleri çakışırsa test başarısız olur.
  • Test verileri telif hakkıyla korunan herhangi bir materyal içermemelidir . Şüpheniz varsa, orijinal veri kümesindeki materyali kullanarak veri oluşturmayın.
import tensorflow_datasets as tfds
from . import my_dataset_dataset_builder


class MyDatasetTest(tfds.testing.DatasetBuilderTestCase):
  """Tests for my_dataset dataset."""
  DATASET_CLASS = my_dataset_dataset_builder.Builder
  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 my_dataset/dummy_data dir.
      'name2': 'file2',
  }


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

Veri setini test etmek için aşağıdaki komutu çalıştırın.

python my_dataset_test.py

Bize geri bildirim gönderin

Veri seti oluşturma iş akışını sürekli olarak iyileştirmeye çalışıyoruz, ancak bunu yalnızca sorunların farkında olursak yapabiliriz. Veri setini oluştururken hangi sorunlarla veya hatalarla karşılaştınız? Kafa karıştırıcı veya ilk denemede çalışmayan bir kısım oldu mu?

Lütfen geri bildirimlerinizi GitHub üzerinden paylaşın.