مشاهده در TensorFlow.org | در Google Colab اجرا شود | در GitHub مشاهده کنید | دانلود دفترچه یادداشت |
این سند توضیح می دهد:
- TFDS در مورد جبرگرایی تضمین می کند
- TFDS نمونه ها را به چه ترتیبی می خواند
- هشدارها و اخطارهای مختلف
برپایی
مجموعه داده ها
برای درک اینکه TFDS چگونه داده ها را می خواند، زمینه ای لازم است.
در طول نسل، TFDS ارسال داده های اصلی به استاندارد .tfrecord
فایل های. برای مجموعه داده های بزرگ، چند .tfrecord
فایل ایجاد می کند، هر یک حاوی نمونه های متعدد. ما پاسخ هر .tfrecord
تکه های شکسته فایل.
این راهنما از imagenet استفاده می کند که دارای 1024 قطعه است:
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)
یافتن شناسه نمونه های مجموعه داده
اگر فقط می خواهید در مورد جبرگرایی بدانید، می توانید به بخش زیر بروید.
هر مثال مجموعه داده است منحصر به فرد شناسایی شده توسط id
(به عنوان مثال 'imagenet2012-train.tfrecord-01023-of-01024__32'
). شما می توانید این بازیابی id
با عبور read_config.add_tfds_id = True
که اضافه خواهد شد 'tfds_id'
کلیدی در بینی از tf.data.Dataset
.
در این آموزش، ما یک ابزار کوچک تعریف میکنیم که شناسههای نمونه مجموعه داده را چاپ میکند (تبدیل به عدد صحیح برای خواندن بیشتر برای انسان):
def load_dataset(builder, **as_dataset_kwargs):
"""Load the dataset with the tfds_id."""
read_config = as_dataset_kwargs.pop('read_config', tfds.ReadConfig())
read_config.add_tfds_id = True # Set `True` to return the 'tfds_id' key
return builder.as_dataset(read_config=read_config, **as_dataset_kwargs)
def print_ex_ids(
builder,
*,
take: int,
skip: int = None,
**as_dataset_kwargs,
) -> None:
"""Print the example ids from the given dataset split."""
ds = load_dataset(builder, **as_dataset_kwargs)
if skip:
ds = ds.skip(skip)
ds = ds.take(take)
exs = [ex['tfds_id'].numpy().decode('utf-8') for ex in ds]
exs = [id_to_int(tfds_id, builder=builder) for tfds_id in exs]
print(exs)
def id_to_int(tfds_id: str, builder) -> str:
"""Format the tfds_id in a more human-readable."""
match = re.match(r'\w+-(\w+).\w+-(\d+)-of-\d+__(\d+)', tfds_id)
split_name, shard_id, ex_id = match.groups()
split_info = builder.info.splits[split_name]
return sum(split_info.shard_lengths[:int(shard_id)]) + int(ex_id)
جبر هنگام خواندن
این بخش تضمین deterministim توضیح می دهد tfds.load
.
با shuffle_files=False
(پیش فرض)
توسط TFDS به طور پیش فرض مثال عملکرد قطعی ( 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]
برای عملکرد، TFDS خرده ریز های متعدد در همان زمان به عنوان خوانده با استفاده از tf.data.Dataset.interleave . ما در این مثال می بینیم که TFDS به سفال 2 تغییر دهید پس از خواندن 16 نمونه ( ..., 14, 15, 1251, 1252, ...
). اطلاعات بیشتر در مورد interleave زیر.
به طور مشابه، subsplit API نیز قطعی است:
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]
اگر شما آموزش هستید برای بیش از یک دوره، راه اندازی بالا توصیه نمی شود به عنوان تمام دوران را به ذرات در همان جهت به عنوان خوانده شده (بنابراین تصادفی به محدود ds = ds.shuffle(buffer)
بافر اندازه).
با shuffle_files=True
با shuffle_files=True
، خرده ریز برای هر دوره حوصلگی، به طوری که خواندن است دیگر قطعی نیست.
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]
دستور زیر را ببینید تا به هم زدن فایل قطعی برسید.
اخطار جبر: ارگ ها را در هم بریزند
تغییر read_config.interleave_cycle_length
، read_config.interleave_block_length
نظم مثال تغییر خواهد کرد.
TFDS متکی بر tf.data.Dataset.interleave به تنها بار چند تکه در یک بار، بهبود عملکرد و کاهش استفاده از حافظه.
ترتیب مثال فقط برای مقدار ثابتی از آرگهای interleave یکسان است. مشاهده توضیحات میان چیزی به درک آنچه cycle_length
و block_length
متناظر است.
-
cycle_length=16
،block_length=16
(به طور پیش فرض، همانند بالا):
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]
در مثال دوم، ما می بینیم که مجموعه داده 2 (خواندن block_length=2
) نمونه در یک سفال، و سپس به سفال های بعدی تغییر دهید. هر 2 * 3 ( cycle_length=3
) مثال ها، آن را به عقب می رود به سفال های اول ( shard0-ex0, shard0-ex1, shard1-ex0, shard1-ex1, shard2-ex0, shard2-ex1, shard0-ex2, shard0-ex3, shard1-ex2, shard1-ex3, shard2-ex2,...
).
تقسیم و سفارش نمونه
هر مثال دارای یک id 0, 1, ..., num_examples-1
. API subsplit را انتخاب کنید یک تکه از نمونه (به عنوان مثال train[:x]
را انتخاب کنید 0, 1, ..., x-1
).
با این حال، در زیر تقسیم، نمونه ها به ترتیب id افزایشی خوانده نمی شوند (به دلیل خرده ها و interleave).
بیشتر به طور خاص، ds.take(x)
و split='train[:x]'
معادل نیست!
این را می توان به راحتی در مثال میان لایه بالا که در آن نمونه ها از خرده های مختلف آمده اند، مشاهده کرد.
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) نمونه، .take(25)
سوئیچ را به سفال های بعدی در حالی که train[:25]
ادامه مطلب نمونه از سفال است.
دستور پخت
به هم زدن فایل قطعی برسید
2 راه برای داشتن درهم ریختگی قطعی وجود دارد:
- تنظیم
shuffle_seed
. توجه: این امر مستلزم تغییر دانه در هر دوره است، در غیر این صورت خرده ها به همان ترتیب بین دوره خوانده می شوند.
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]
- با استفاده از
experimental_interleave_sort_fn
: این را می دهد کنترل کامل بر که ذرات به عنوان خوانده شده و در آن سفارش، به جای تکیه برds.shuffle
سفارش.
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]
خط لوله قابل پیشگیری قطعی را دریافت کنید
این یکی پیچیده تر است. هیچ راه حل آسان و رضایت بخشی وجود ندارد.
بدون
ds.shuffle
و با زدن قطعی، در تئوری آن را باید ممکن باشد به تعداد نمونه هایی است که خوانده شده است و استنباط که نمونه هایی در داخل در هر ربان خوانده شده است (به عنوان تابعی ازcycle_length
،block_length
و سفارش سفال). سپسskip
،take
برای هر ربان می تواند از طریق تزریقexperimental_interleave_sort_fn
.با
ds.shuffle
این احتمال وجود دارد بدون دوباره پخش خط لوله آموزش کامل غیر ممکن است. این امر نیاز به صرفه جویی درds.shuffle
دولت حائل به استنباط که نمونه هایی خوانده شدهاند. مثالها می تواند غیر مداوم (به عنوان مثالshard5_ex2
،shard5_ex4
را بخوانند اماshard5_ex3
).با
ds.shuffle
، یکی از راه خواهد بود به ذخیره تمام shards_ids / example_ids عنوان خوانده شده (استنباط ازtfds_id
)، سپس استنتاج دستورالعمل فایل را از آن.
ساده ترین مورد برای 1.
را داشته است .skip(x).take(y)
بازی train[x:x+y]
بازی. مستلزم این است:
- مجموعه
cycle_length=1
(تا خرده ریز به ترتیب به عنوان خوانده شده) - مجموعه
shuffle_files=False
- استفاده نکنید
ds.shuffle
فقط باید در مجموعه داده های عظیمی که آموزش فقط 1 دوره است استفاده شود. نمونهها به ترتیب پیشفرض درهم خوانده میشوند.
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]
پیدا کنید کدام خرده/مثال برای یک زیرشاخه داده شده خوانده می شود
با tfds.core.DatasetInfo
، شما باید دسترسی مستقیم به دستورالعمل به عنوان خوانده شده.
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)]