TFDS ve determinizm

TensorFlow.org'da görüntüleyin Google Colab'da çalıştırın GitHub'da görüntüle Not defterini indir

Bu belge şunları açıklar:

  • TFDS determinizmi garanti eder
  • TFDS örnekleri hangi sırayla okur?
  • Çeşitli uyarılar ve yakalamalar

Kurmak

veri kümeleri

TFDS'nin verileri nasıl okuduğunu anlamak için bazı bağlamlara ihtiyaç vardır.

Nesil boyunca, TFDS standardize orijinal veri yazma .tfrecord dosyaları. Büyük veri setleri için, birden .tfrecord dosyalar oluşturulur, her çoklu örnekler içeren. Her çağrı .tfrecord bir shard dosyası.

Bu kılavuz, 1024 parçaya sahip olan imagenet'i kullanır:

import re
import tensorflow_datasets as tfds

imagenet = tfds.builder('imagenet2012')

num_shards = imagenet.info.splits['train'].num_shards
num_examples = imagenet.info.splits['train'].num_examples
print(f'imagenet has {num_shards} shards ({num_examples} examples)')
imagenet has 1024 shards (1281167 examples)

Veri kümesi örnek kimliklerini bulma

Yalnızca determinizm hakkında bilgi edinmek istiyorsanız aşağıdaki bölüme geçebilirsiniz.

Her veri kümesi, örneğin benzersiz bir ile tanımlanır id (örneğin 'imagenet2012-train.tfrecord-01023-of-01024__32' ). Bunu kurtarabilirsiniz id geçirerek read_config.add_tfds_id = True bir katacak 'tfds_id' dan dict anahtarı tf.data.Dataset .

Bu öğreticide, veri kümesinin örnek kimliklerini yazdıracak küçük bir util tanımlıyoruz (insanlar tarafından daha okunabilir olması için tamsayıya dönüştürülmüş):

Okurken determinizm

Bu bölüm içinde deterministim garanti açıklıyor tfds.load .

İle shuffle_files=False (varsayılan)

Varsayılan TFDS deterministik örnekleri verim ile ( shuffle_files=False )

# Same as: imagenet.as_dataset(split='train').take(20)
print_ex_ids(imagenet, split='train', take=20)
print_ex_ids(imagenet, split='train', take=20)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 1251, 1252, 1253, 1254]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 1251, 1252, 1253, 1254]

Performans için, TFDS kullanarak aynı anda birden fazla kırıkları okundu tf.data.Dataset.interleave . Biz TFDS 16 örnek okuduktan sonra kırığa 2'ye geçmek bu örnekte gördüğünüz ( ..., 14, 15, 1251, 1252, ... ). Interleave feryat hakkında daha fazlası.

Benzer şekilde, alt bölünmüş API de belirleyicidir:

print_ex_ids(imagenet, split='train[67%:84%]', take=20)
print_ex_ids(imagenet, split='train[67%:84%]', take=20)
[858382, 858383, 858384, 858385, 858386, 858387, 858388, 858389, 858390, 858391, 858392, 858393, 858394, 858395, 858396, 858397, 859533, 859534, 859535, 859536]
[858382, 858383, 858384, 858385, 858386, 858387, 858388, 858389, 858390, 858391, 858392, 858393, 858394, 858395, 858396, 858397, 859533, 859534, 859535, 859536]

Konum eğitim birden fazla dönem için size Eğer (rasgelelik sınırlıdır böylece bütün dönemini aynı sırada kırıkları okuyacaktı, yukarıdaki kurulum tavsiye edilmez ds = ds.shuffle(buffer) boyutunu tampon).

İle shuffle_files=True

İle shuffle_files=True okuma artık belirleyici değil bu yüzden, kırıklara, her dönem için karıştırılır.

print_ex_ids(imagenet, split='train', shuffle_files=True, take=20)
print_ex_ids(imagenet, split='train', shuffle_files=True, take=20)
[568017, 329050, 329051, 329052, 329053, 329054, 329056, 329055, 568019, 568020, 568021, 568022, 568023, 568018, 568025, 568024, 568026, 568028, 568030, 568031]
[43790, 43791, 43792, 43793, 43796, 43794, 43797, 43798, 43795, 43799, 43800, 43801, 43802, 43803, 43804, 43805, 43806, 43807, 43809, 43810]

Belirleyici dosya karıştırma elde etmek için aşağıdaki tarife bakın.

Determinizm uyarısı: ara değişkenler

Değişen read_config.interleave_cycle_length , read_config.interleave_block_length örnekleri sırasını değiştirir.

TFDS dayanır tf.data.Dataset.interleave performansını artırmak ve bellek kullanımını azaltmak, sadece bir kerede birkaç kırıkları yüklemek için.

Örnek sıranın yalnızca, aralıklı bağımsız değişkenlerin sabit bir değeri için aynı olması garanti edilir. Bkz Interleave doc anlamak için cycle_length ve block_length tekabül de.

  • cycle_length=16 , block_length=16 (varsayılan, yukarıdaki ile aynı):
print_ex_ids(imagenet, split='train', take=20)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 1251, 1252, 1253, 1254]
  • cycle_length=3 , block_length=2 :
read_config = tfds.ReadConfig(
    interleave_cycle_length=3,
    interleave_block_length=2,
)
print_ex_ids(imagenet, split='train', read_config=read_config, take=20)
[0, 1, 1251, 1252, 2502, 2503, 2, 3, 1253, 1254, 2504, 2505, 4, 5, 1255, 1256, 2506, 2507, 6, 7]

İkinci örnekte, veri kümesi 2 (okuma görüyoruz block_length=2 bir kırıkta) örnekleri, daha sonra bir sonraki kırıkta geçin. Her 2 * 3 ( cycle_length=3 ) örnekleri, ilk kırığa (geri döner shard0-ex0, shard0-ex1, shard1-ex0, shard1-ex1, shard2-ex0, shard2-ex1, shard0-ex2, shard0-ex3, shard1-ex2, shard1-ex3, shard2-ex2,... ).

Alt bölme ve örnek sipariş

Her örnek bir kimlik vardır 0, 1, ..., num_examples-1 . Subsplit API (örneğin örnekler bir dilim seçin train[:x] seçin 0, 1, ..., x-1 ).

Ancak, alt bölme içinde, örnekler artan kimlik sırasına göre okunmaz (parçalar ve araya girme nedeniyle).

Daha spesifik olarak, ds.take(x) ve split='train[:x]' eşdeğer değildir!

Bu, örneklerin farklı parçalardan geldiği yukarıdaki serpiştirme örneğinde kolayca görülebilir.

print_ex_ids(imagenet, split='train', take=25)  # tfds.load(..., split='train').take(25)
print_ex_ids(imagenet, split='train[:25]', take=-1)  # tfds.load(..., split='train[:25]')
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 1251, 1252, 1253, 1254, 1255, 1256, 1257, 1258, 1259]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24]

16 (block_length) örnekleri sonra .take(25) ise bir sonraki kırığa geçer train[:25] birinci kırıkta gelen örnekleri okumaya devam edin.

Tarifler

Belirleyici dosya karıştırma elde edin

Deterministik karıştırmaya sahip olmanın 2 yolu vardır:

  1. Ayar shuffle_seed . Not: Bu, her çağda çekirdeğin değiştirilmesini gerektirir, aksi takdirde parçalar, çağ arasında aynı sırada okunur.
read_config = tfds.ReadConfig(
    shuffle_seed=32,
)

# Deterministic order, different from the default shuffle_files=False above
print_ex_ids(imagenet, split='train', shuffle_files=True, read_config=read_config, take=22)
print_ex_ids(imagenet, split='train', shuffle_files=True, read_config=read_config, take=22)
[176411, 176412, 176413, 176414, 176415, 176416, 176417, 176418, 176419, 176420, 176421, 176422, 176423, 176424, 176425, 176426, 710647, 710648, 710649, 710650, 710651, 710652]
[176411, 176412, 176413, 176414, 176415, 176416, 176417, 176418, 176419, 176420, 176421, 176422, 176423, 176424, 176425, 176426, 710647, 710648, 710649, 710650, 710651, 710652]
  1. Kullanılması experimental_interleave_sort_fn : Bu kırıkları okumak ve hangi sırayla yerine güvenmek yerine hangi üzerinde tam kontrol sağlayan ds.shuffle sırayla.
def _reverse_order(file_instructions):
  return list(reversed(file_instructions))

read_config = tfds.ReadConfig(
    experimental_interleave_sort_fn=_reverse_order,
)

# Last shard (01023-of-01024) is read first
print_ex_ids(imagenet, split='train', read_config=read_config, take=5)
[1279916, 1279917, 1279918, 1279919, 1279920]

Belirleyici öncelikli ardışık düzen alın

Bu daha karmaşık. Kolay ve tatmin edici bir çözüm yoktur.

  1. Olmadan ds.shuffle ve deterministik karıştırma ile, teorik olarak (bir fonksiyonu olarak örnek her kırıkta içinde okundu okumak ve anlamak edilmiş örnekler saymak mümkün olmalıdır cycle_length , block_length ve rastgele sırayla). Sonra skip , take her kırığın yoluyla enjekte edilebilir experimental_interleave_sort_fn .

  2. İle ds.shuffle tam eğitim boru hattını oynatırken olmadan olasılıkla imkansız. Bu tasarruf gerektirecektir ds.shuffle örnekler okunmuş anlamak için tampon devlet. Örnekler (ör kesintisiz-olmayan olabilir shard5_ex2 , shard5_ex4 okuma değil shard5_ex3 ).

  3. İle ds.shuffle , tek yönlü / example_ids (çıkarılabilir okuma tüm shards_ids kaydetmek olacaktır tfds_id o dosya talimatları çözmekten).

İçin en basit durum, 1. zorunda olduğu .skip(x).take(y) eşleme train[x:x+y] eşleme. Gerektirir:

  • Takım cycle_length=1 (kırıkları sırayla okunur, böylece)
  • Set shuffle_files=False
  • Kullanmayın ds.shuffle

Yalnızca eğitimin yalnızca 1 dönem olduğu büyük veri kümesinde kullanılmalıdır. Örnekler, varsayılan karıştırma sırasında okunacaktır.

read_config = tfds.ReadConfig(
    interleave_cycle_length=1,  # Read shards sequentially
)

print_ex_ids(imagenet, split='train', read_config=read_config, skip=40, take=22)
# If the job get pre-empted, using the subsplit API will skip at most `len(shard0)`
print_ex_ids(imagenet, split='train[40:]', read_config=read_config, take=22)
[40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61]
[40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61]

Belirli bir alt bölüm için hangi parçaların/örneklerin okunduğunu bulun

İle tfds.core.DatasetInfo , okundu talimatları doğrudan erişebilirsiniz.

imagenet.info.splits['train[44%:45%]'].file_instructions
[FileInstruction(filename='imagenet2012-train.tfrecord-00450-of-01024', skip=700, take=-1, num_examples=551),
 FileInstruction(filename='imagenet2012-train.tfrecord-00451-of-01024', skip=0, take=-1, num_examples=1251),
 FileInstruction(filename='imagenet2012-train.tfrecord-00452-of-01024', skip=0, take=-1, num_examples=1251),
 FileInstruction(filename='imagenet2012-train.tfrecord-00453-of-01024', skip=0, take=-1, num_examples=1251),
 FileInstruction(filename='imagenet2012-train.tfrecord-00454-of-01024', skip=0, take=-1, num_examples=1252),
 FileInstruction(filename='imagenet2012-train.tfrecord-00455-of-01024', skip=0, take=-1, num_examples=1251),
 FileInstruction(filename='imagenet2012-train.tfrecord-00456-of-01024', skip=0, take=-1, num_examples=1251),
 FileInstruction(filename='imagenet2012-train.tfrecord-00457-of-01024', skip=0, take=-1, num_examples=1251),
 FileInstruction(filename='imagenet2012-train.tfrecord-00458-of-01024', skip=0, take=-1, num_examples=1251),
 FileInstruction(filename='imagenet2012-train.tfrecord-00459-of-01024', skip=0, take=-1, num_examples=1251),
 FileInstruction(filename='imagenet2012-train.tfrecord-00460-of-01024', skip=0, take=1001, num_examples=1001)]