Todos os conjuntos de dados TFDS expõem várias divisões de dados (por exemplo, 'train'
, 'test'
) que podem ser exploradas no catálogo . Qualquer string alfabética pode ser usada como nome do split, exceto all
(que é um termo reservado que corresponde à união de todos os splits, veja abaixo).
Além das divisões "oficiais" do conjunto de dados, o TFDS permite selecionar fatia(s) de divisão(ões) e várias combinações.
API de fatiamento
As instruções de fatiamento são especificadas em tfds.load
ou tfds.DatasetBuilder.as_dataset
por meio de split=
kwarg.
ds = tfds.load('my_dataset', split='train[:75%]')
builder = tfds.builder('my_dataset')
ds = builder.as_dataset(split='test+train[:75%]')
A divisão pode ser:
- Nomes de divisão simples (uma string como
'train'
,'test'
, ...): Todos os exemplos dentro da divisão selecionada. - Fatias : As fatias têm a mesma semântica que a notação de fatia python . As fatias podem ser:
- Absoluto (
'train[123:450]'
,train[:4000]
): (veja a nota abaixo para advertência sobre a ordem de leitura) - Porcentagem (
'train[:75%]'
,'train[25%:75%]'
): Divida os dados completos em fatias pares. Se os dados não forem divisíveis igualmente, alguma porcentagem poderá conter exemplos adicionais. Porcentagens fracionárias são suportadas. - Shard (
train[:4shard]
,train[4shard]
): Selecione todos os exemplos no shard solicitado. (vejainfo.splits['train'].num_shards
para obter o número de fragmentos da divisão)
- Absoluto (
- União de divisões (
'train+test'
,'train[:25%]+test'
): As divisões serão intercaladas. - Conjunto de dados completo (
'all'
):'all'
é um nome de divisão especial correspondente à união de todas as divisões (equivalente a'train+test+...'
). - Lista de divisões (
['train', 'test']
): Váriostf.data.Dataset
são retornados separadamente:
# Returns both train and test split separately
train_ds, test_ds = tfds.load('mnist', split=['train', 'test[:50%]'])
tfds.even_splits
e treinamento multi-host
tfds.even_splits
gera uma lista de subdivisões não sobrepostas do mesmo tamanho.
# 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)
Isto pode ser particularmente útil ao treinar em um ambiente distribuído, onde cada host deve receber uma fatia dos dados originais.
Com Jax
, isso pode ser simplificado ainda mais usando 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
é um alias simples para:
# 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
aceita qualquer valor de divisão como entrada (por exemplo 'train[75%:]+test'
)
Fatiamento e metadados
É possível obter informações adicionais sobre as divisões/subdivisões ( num_examples
, file_instructions
,...) usando o dataset info :
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']
Validação cruzada
Exemplos de validação cruzada de 10 vezes usando a API de string:
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)
])
Cada conjunto de dados de validação será 10%: [0%:10%]
, [10%:20%]
, ..., [90%:100%]
. E cada conjunto de dados de treinamento será 90% complementar: [10%:100%]
(para um conjunto de validação correspondente de [0%:10%]
), `[0%:10%]
- [20%:100%]
(for a validation set of
[10%:20%]`),...
tfds.core.ReadInstruction
e arredondamento
Em vez de str
, é possível passar divisões como tfds.core.ReadInstruction
:
Por exemplo, split = 'train[50%:75%] + test'
é equivalente a:
split = (
tfds.core.ReadInstruction(
'train',
from_=50,
to=75,
unit='%',
)
+ tfds.core.ReadInstruction('test')
)
ds = tfds.load('my_dataset', split=split)
unit
pode ser:
-
abs
: corte absoluto -
%
: porcentagem de fatiamento -
shard
: fatiamento de fragmento
tfds.ReadInstruction
também possui um argumento de arredondamento. Se o número de exemplos no conjunto de dados não for dividido igualmente:
-
rounding='closest'
(padrão): Os exemplos restantes são distribuídos entre a porcentagem, portanto, alguma porcentagem pode conter exemplos adicionais. -
rounding='pct1_dropremainder'
: Os exemplos restantes são eliminados, mas isso garante que todas as porcentagens contenham exatamente o mesmo número de exemplos (por exemplo:len(5%) == 5 * len(1%)
).
Reprodutibilidade e determinismo
Durante a geração, para uma determinada versão do conjunto de dados, o TFDS garante que os exemplos sejam embaralhados deterministicamente no disco. Portanto, gerar o conjunto de dados duas vezes (em 2 computadores diferentes) não alterará a ordem dos exemplos.
Da mesma forma, a API subsplit sempre selecionará o mesmo set
de exemplos, independentemente da plataforma, arquitetura, etc. Isso significa set('train[:20%]') == set('train[:10%]') + set('train[10%:20%]')
.
No entanto, a ordem em que os exemplos são lidos pode não ser determinística. Isso depende de outros parâmetros (por exemplo, se shuffle_files=True
).