Bu belge, TensorFlow Veri Kümelerine (TFDS) özel performans ipuçları sağlar. TFDS'nin veri kümelerini tf.data.Dataset
nesneleri olarak sağladığını, dolayısıyla tf.data
kılavuzundaki tavsiyelerin hala geçerli olduğunu unutmayın.
Karşılaştırma veri kümeleri
Herhangi bir tf.data.Dataset
nesnesini kıyaslamak için tfds.benchmark(ds)
öğesini kullanın.
Sonuçları normalleştirmek için batch_size=
değerini belirttiğinizden emin olun (örn. 100 iter/sn -> 3200 ex/sn). Bu, yinelenebilir herhangi bir şeyle çalışır (örn. 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)
Küçük veri kümeleri (1 GB'tan az)
Tüm TFDS veri kümeleri verileri diskte TFRecord
formatında saklar. Küçük veri kümeleri için (örn. MNIST, CIFAR-10/-100), .tfrecord
okumak önemli miktarda ek yük getirebilir.
Bu veri kümeleri belleğe sığdığından, veri kümesini önbelleğe alarak veya önceden yükleyerek performansı önemli ölçüde artırmak mümkündür. TFDS'nin küçük veri kümelerini otomatik olarak önbelleğe aldığını unutmayın (aşağıdaki bölümde ayrıntılar bulunmaktadır).
Veri kümesini önbelleğe alma
Burada, görüntüleri normalleştirdikten sonra veri kümesini açıkça önbelleğe alan bir veri hattı örneği verilmiştir.
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)
Bu veri kümesi üzerinde yineleme yapılırken önbellekleme sayesinde ikinci yineleme birinciye göre çok daha hızlı olacaktır.
Otomatik önbelleğe alma
Varsayılan olarak, TFDS aşağıdaki kısıtlamaları karşılayan veri kümelerini ( ds.cache()
ile) otomatik olarak önbelleğe alır:
- Toplam veri kümesi boyutu (tüm bölümler) tanımlıdır ve < 250 MiB
-
shuffle_files
devre dışı bırakıldı veya yalnızca tek bir parça okundu
tfds.load
dosyasındaki tfds.ReadConfig
dosyasına try_autocaching=False
ileterek otomatik önbelleğe almayı devre dışı bırakmak mümkündür. Belirli bir veri kümesinin otomatik önbellek kullanıp kullanmayacağını görmek için veri kümesi kataloğu belgelerine bakın.
Tüm verileri tek bir Tensör olarak yükleme
Veri kümeniz belleğe sığıyorsa veri kümesinin tamamını tek bir Tensor veya NumPy dizisi olarak da yükleyebilirsiniz. Tüm örnekleri tek bir tf.Tensor
gruplamak için batch_size=-1
ayarını yaparak bunu yapmak mümkündür. Daha sonra tf.Tensor
np.array
dönüşüm için tfds.as_numpy
kullanın.
(img_train, label_train), (img_test, label_test) = tfds.as_numpy(tfds.load(
'mnist',
split=['train', 'test'],
batch_size=-1,
as_supervised=True,
))
Büyük veri kümeleri
Büyük veri kümeleri parçalanır (birden fazla dosyaya bölünür) ve genellikle belleğe sığmaz, dolayısıyla önbelleğe alınmamaları gerekir.
Karışıklık ve antrenman
Eğitim sırasında verileri iyi bir şekilde karıştırmak önemlidir; kötü şekilde karıştırılmış veriler, eğitim doğruluğunun düşmesine neden olabilir.
Kayıtları karıştırmak için ds.shuffle
kullanmanın yanı sıra, birden fazla dosyaya bölünmüş daha büyük veri kümeleri için iyi karıştırma davranışı elde etmek amacıyla shuffle_files=True
de ayarlamanız gerekir. Aksi takdirde dönemler, parçaları aynı sırayla okuyacaktır ve dolayısıyla veriler gerçek anlamda rastgele hale getirilmeyecektir.
ds = tfds.load('imagenet2012', split='train', shuffle_files=True)
Ek olarak, shuffle_files=True
olduğunda TFDS, options.deterministic
devre dışı bırakır ve bu da hafif bir performans artışı sağlayabilir. Belirleyici karıştırma elde etmek için, tfds.ReadConfig
ile bu özelliği devre dışı bırakmak mümkündür: ya read_config.shuffle_seed
ayarını yaparak ya da read_config.options.deterministic
üzerine yazarak.
Verilerinizi çalışanlar arasında otomatik olarak parçalayın (TF)
Birden çok çalışan üzerinde eğitim verirken tfds.ReadConfig
öğesinin input_context
bağımsız değişkenini kullanabilirsiniz, böylece her çalışan verilerin bir alt kümesini okuyacaktır.
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)
Bu, alt bölme API'sini tamamlayıcı niteliktedir. İlk olarak alt bölme API'si uygulanır: train[:50%]
okunacak dosyaların listesine dönüştürülür. Daha sonra bu dosyalara bir ds.shard()
işlemi uygulanır. Örneğin, train[:50%]
num_input_pipelines=2
ile kullanıldığında, 2 çalışanın her biri verinin 1/4'ünü okuyacaktır.
shuffle_files=True
olduğunda, dosyalar bir çalışan içinde karıştırılır ancak çalışanlar arasında karıştırılmaz. Her çalışan dönemler arasında aynı dosya alt kümesini okuyacaktır.
Verilerinizi çalışanlar arasında otomatik olarak parçalayın (Jax)
Jax ile verilerinizi çalışanlar arasında dağıtmak için tfds.split_for_jax_process
veya tfds.even_splits
API'sini kullanabilirsiniz. Bölünmüş API kılavuzuna bakın.
split = tfds.split_for_jax_process('train', drop_remainder=True)
ds = tfds.load('my_dataset', split=split)
tfds.split_for_jax_process
aşağıdakiler için basit bir takma addır:
# 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()]
Daha hızlı görüntü kod çözme
Varsayılan olarak TFDS görüntülerin kodunu otomatik olarak çözer. Ancak, tfds.decode.SkipDecoding
ile görüntü kod çözme işlemini atlayıp tf.io.decode_image
işlemini manuel olarak uygulamanın daha performanslı olabileceği durumlar vardır:
- Örnekleri filtrelerken (
tf.data.Dataset.filter
ile), örnekler filtrelendikten sonra görüntülerin kodunu çözmek için. - Görüntüleri kırparken, birleştirilmiş
tf.image.decode_and_crop_jpeg
op'yi kullanmak için.
Her iki örneğin kodu kod çözme kılavuzunda mevcuttur.
Kullanılmayan özellikleri atla
Özelliklerin yalnızca bir alt kümesini kullanıyorsanız bazı özellikleri tamamen atlamak mümkündür. Veri kümenizde kullanılmayan birçok özellik varsa bunların kodunu çözmemek performansı önemli ölçüde artırabilir. Bkz. https://www.tensorflow.org/datasets/decode#only_decode_a_sub-set_of_the_features
tf.data tüm RAM'imi kullanıyor!
RAM'iniz sınırlıysa veya tf.data
kullanırken çok sayıda veri kümesini paralel olarak yüklüyorsanız, size yardımcı olabilecek birkaç seçenek aşağıda verilmiştir:
Arabellek boyutunu geçersiz kıl
builder.as_dataset(
read_config=tfds.ReadConfig(
...
override_buffer_size=1024, # Save quite a bit of RAM.
),
...
)
Bu, TFRecordDataset
(veya eşdeğerine) iletilen buffer_size
geçersiz kılar: https://www.tensorflow.org/api_docs/python/tf/data/TFRecordDataset#args
Sihirli davranışları durdurmak için tf.data.Dataset.with_options kullanın
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)