Wszystkie zbiory danych TFDS udostępniają różne podziały danych (np. 'train'
, 'test'
), które można przeglądać w katalogu . Jako nazwa podziału może zostać użyty dowolny ciąg alfabetyczny, z wyjątkiem all
(jest to termin zastrzeżony, który odpowiada sumie wszystkich podziałów, patrz poniżej).
Oprócz „oficjalnych” podziałów zbiorów danych, TFDS umożliwia wybór wycinków podziału i różnych kombinacji.
API krojenia
Instrukcje dzielenia są określone w tfds.load
lub tfds.DatasetBuilder.as_dataset
poprzez split=
kwarg.
ds = tfds.load('my_dataset', split='train[:75%]')
builder = tfds.builder('my_dataset')
ds = builder.as_dataset(split='test+train[:75%]')
Podział może być:
- Zwykłe nazwy podziału (ciąg taki jak
'train'
,'test'
...): Wszystkie przykłady w wybranym podziale. - Plasterki : Plasterki mają taką samą semantykę jak notacja plasterków w Pythonie . Plasterki mogą być:
- Absolute (
'train[123:450]'
,train[:4000]
): (zobacz uwagę poniżej, aby zapoznać się z zastrzeżeniem dotyczącym kolejności odczytu) - Procent (
'train[:75%]'
,'train[25%:75%]'
): Podziel pełne dane na równe części. Jeśli danych nie można równomiernie podzielić, niektóre procenty mogą zawierać dodatkowe przykłady. Obsługiwane są ułamki procentowe. - Shard (
train[:4shard]
,train[4shard]
): Wybierz wszystkie przykłady w żądanym fragmencie. (zobaczinfo.splits['train'].num_shards
aby uzyskać liczbę fragmentów podziału)
- Absolute (
- Suma podziałów (
'train+test'
,'train[:25%]+test'
): Podziały będą ze sobą przeplatane. - Pełny zbiór danych (
'all'
):'all'
to specjalna nazwa podziału odpowiadająca sumie wszystkich podziałów (równoważna z'train+test+...'
). - Lista podziałów (
['train', 'test']
): Wieletf.data.Dataset
jest zwracanych osobno:
# Returns both train and test split separately
train_ds, test_ds = tfds.load('mnist', split=['train', 'test[:50%]'])
tfds.even_splits
i szkolenie z wieloma hostami
tfds.even_splits
generuje listę nienakładających się na siebie podpodziałów o tym samym rozmiarze.
# 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)
Może to być szczególnie przydatne podczas uczenia w środowisku rozproszonym, gdzie każdy host powinien otrzymać wycinek oryginalnych danych.
W Jax
można to jeszcze bardziej uprościć, używając 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
to prosty alias dla:
# 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
akceptuje dowolną podzieloną wartość jako dane wejściowe (np 'train[75%:]+test'
)
Krojenie i metadane
Możliwe jest uzyskanie dodatkowych informacji na temat podziałów/podpodziałów ( num_examples
, file_instructions
,...) przy użyciu informacji o zestawie danych :
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']
Walidacja krzyżowa
Przykłady 10-krotnej walidacji krzyżowej przy użyciu interfejsu API 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)
])
Każdy zestaw danych walidacyjnych będzie wynosił 10%: [0%:10%]
, [10%:20%]
, ..., [90%:100%]
. Każdy zestaw danych szkoleniowych będzie komplementarnym 90%: [10%:100%]
(dla odpowiedniego zestawu walidacyjnego wynoszącego [0%:10%]
), `[0%:10%]
- [20%:100%]
(for a validation set of
[10%:20%]`),...
tfds.core.ReadInstruction
i zaokrąglanie
Zamiast str
można przekazać podziały w formie tfds.core.ReadInstruction
:
Na przykład split = 'train[50%:75%] + test'
jest równoważny:
split = (
tfds.core.ReadInstruction(
'train',
from_=50,
to=75,
unit='%',
)
+ tfds.core.ReadInstruction('test')
)
ds = tfds.load('my_dataset', split=split)
unit
może być:
-
abs
: Absolutne krojenie -
%
: Procent krojenia -
shard
: Krojenie odłamka
tfds.ReadInstruction
ma również argument zaokrąglania. Jeśli liczba przykładów w zbiorze danych nie jest podzielona równo:
-
rounding='closest'
(domyślnie): pozostałe przykłady są rozdzielane pomiędzy procenty, więc niektóre procenty mogą zawierać dodatkowe przykłady. -
rounding='pct1_dropremainder'
: Pozostałe przykłady są pomijane, ale gwarantuje to, że wszystkie procenty zawierają dokładnie tę samą liczbę przykładów (np.:len(5%) == 5 * len(1%)
).
Powtarzalność i determinizm
Podczas generowania, dla danej wersji zbioru danych, TFDS gwarantuje, że przykłady zostaną deterministycznie przetasowane na dysku. Zatem dwukrotne wygenerowanie zestawu danych (na 2 różnych komputerach) nie zmieni przykładowej kolejności.
Podobnie subsplit API zawsze wybierze ten sam set
przykładów, niezależnie od platformy, architektury itp. Oznacza to set('train[:20%]') == set('train[:10%]') + set('train[10%:20%]')
.
Jednakże kolejność odczytywania przykładów może nie być deterministyczna. Zależy to od innych parametrów (np. czy shuffle_files=True
).