Разделение и нарезка

Все наборы данных TFDS содержат различные разбиения данных (например 'train' , 'test' ), которые можно изучить в каталоге .

Помимо «официальных» разбиений набора данных, TFDS позволяет выбирать срез(ы) разбиения(ий) и различные комбинации.

API нарезки

Инструкции по нарезке указываются в tfds.load или tfds.DatasetBuilder.as_dataset через split= kwarg.

ds = tfds.load('my_dataset', split='train[:75%]')
builder = tfds.builder('my_dataset')
ds = builder.as_dataset(split='test+train[:75%]')

Сплит может быть:

  • Простое разделение ( 'train' , 'test' ): выбраны все примеры в разделении.
  • Срезы : Срезы имеют ту же семантику, что и нотация слайсов Python . Срезы могут быть:
    • Абсолютный ( 'train[123:450]' , train[:4000] ): (см. примечание ниже о порядке чтения)
    • Percent ( 'train[:75%]' , 'train[25%:75%]' ): разделите полные данные на 100 равных частей. Если данные не делятся на 100, некоторые проценты могут содержать дополнительные примеры.
    • Shard ( train[:4shard] , train[4shard] ): выберите все примеры в запрошенном сегменте. (см. info.splits['train'].num_shards , чтобы получить количество осколков разделения)
  • Объединение сплитов ( 'train+test' , 'train[:25%]+test' ): сплиты будут чередоваться вместе.
  • Полный набор данных ( 'all' ): 'all' — это специальное имя разделения, соответствующее объединению всех разделений (эквивалент 'train+test+...' ).
  • Список разбиений ( ['train', 'test'] ): несколько tf.data.Dataset возвращаются отдельно:
# Returns both train and test split separately
train_ds, test_ds = tfds.load('mnist', split=['train', 'test[:50%]'])

tfds.even_splits и обучение на нескольких хостах

tfds.even_splits генерирует список непересекающихся частей одинакового размера.

# Divide the dataset into 3 even parts, each containing 1/3 of the data
split0, split1, split2 = tfds.even_splits('train', n=3)

ds = tfds.load('my_dataset', split=split2)

Это может быть особенно полезно при обучении в распределенной среде, где каждый хост должен получать фрагмент исходных данных.

С Jax это можно упростить еще больше, используя tfds.split_for_jax_process :

split = tfds.split_for_jax_process('train', drop_remainder=True)
ds = tfds.load('my_dataset', split=split)

tfds.split_for_jax_process — это простой псевдоним для:

# 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()]

tfds.even_splits , tfds.split_for_jax_process принимает любое значение разделения в качестве входных данных (например 'train[75%:]+test' )

Нарезка и метаданные

Можно получить дополнительную информацию о разбиениях/подразбиениях ( num_examples , file_instructions ,...), используя информацию о наборе данных :

builder = tfds.builder('my_dataset')
builder.info.splits['train'].num_examples  # 10_000
builder.info.splits['train[:75%]'].num_examples  # 7_500 (also works with slices)
builder.info.splits.keys()  # ['train', 'test']

Перекрестная проверка

Примеры 10-кратной перекрестной проверки с использованием строкового API:

vals_ds = tfds.load('mnist', split=[
    f'train[{k}%:{k+10}%]' for k in range(0, 100, 10)
])
trains_ds = tfds.load('mnist', split=[
    f'train[:{k}%]+train[{k+10}%:]' for k in range(0, 100, 10)
])

Каждый набор данных проверки будет равен 10%: [0%:10%] , [10%:20%] , ..., [90%:100%] . И каждый набор обучающих данных будет дополнительным 90%: [10%:100%] (для соответствующего проверочного набора [0%:10%] ), `[0%:10%]

  • [20%:100%] (for a validation set of [10%:20%]`),...

tfds.core.ReadInstruction и округление

Вместо str можно передать разделение как tfds.core.ReadInstruction :

Например, split = 'train[50%:75%] + test' эквивалентно:

split = (
    tfds.core.ReadInstruction(
        'train',
        from_=50,
        to=75,
        unit='%',
    )
    + tfds.core.ReadInstruction('test')
)
ds = tfds.load('my_dataset', split=split)

unit может быть:

  • abs : Абсолютная нарезка
  • % : Процентная нарезка
  • shard : нарезка осколка

tfds.ReadInstruction также имеет аргумент округления. Если количество примеров в наборе данных не делится на 100 без остатка:

  • rounding='closest' (по умолчанию): остальные примеры распределяются по процентам, поэтому некоторые проценты могут содержать дополнительные примеры.
  • rounding='pct1_dropremainder' : остальные примеры отбрасываются, но это гарантирует, что все проценты содержат одинаковое количество примеров (например: len(5%) == 5 * len(1%) ).

Воспроизводимость и детерминизм

Во время генерации для заданной версии набора данных TFDS гарантирует, что примеры детерминировано перемешаны на диске. Таким образом, создание набора данных дважды (на 2 разных компьютерах) не изменит порядок примера.

Точно так же API-интерфейс subsplit всегда будет выбирать один и тот же set примеров, независимо от платформы, архитектуры и т. д. Это означает set('train[:20%]') == set('train[:10%]') + set('train[10%:20%]') .

Однако порядок, в котором читаются примеры, может быть не детерминированным. Это зависит от других параметров (например, shuffle_files=True ).