Jeśli masz proto tf.train.Example
(wewnątrz .tfrecord
, .riegeli
,...), które zostało wygenerowane przez narzędzia stron trzecich i chcesz je bezpośrednio załadować za pomocą API tfds, to ta strona jest dla Ciebie.
Aby załadować pliki .tfrecord
, wystarczy:
- Postępuj zgodnie z konwencją nazewnictwa TFDS.
- Dodaj pliki metadanych (
dataset_info.json
,features.json
) do plików tfrecord.
Ograniczenia:
-
tf.train.SequenceExample
nie jest obsługiwany, tylkotf.train.Example
. - Musisz umieć wyrazić
tf.train.Example
w terminachtfds.features
(patrz sekcja poniżej).
Konwencja nazewnictwa plików
TFDS obsługuje definiowanie szablonów nazw plików, co zapewnia elastyczność w stosowaniu różnych schematów nazewnictwa plików. Szablon jest reprezentowany przez tfds.core.ShardedFileTemplate
i obsługuje następujące zmienne: {DATASET}
, {SPLIT}
, {FILEFORMAT}
, {SHARD_INDEX}
, {NUM_SHARDS}
i {SHARD_X_OF_Y}
. Na przykład domyślny schemat nazewnictwa plików TFDS to: {DATASET}-{SPLIT}.{FILEFORMAT}-{SHARD_X_OF_Y}
. W przypadku MNIST oznacza to, że nazwy plików wyglądają następująco:
-
mnist-test.tfrecord-00000-of-00001
-
mnist-train.tfrecord-00000-of-00001
Dodaj metadane
Podaj strukturę funkcji
Aby TFDS mógł zdekodować proto tf.train.Example
, musisz podać strukturę tfds.features
odpowiadającą Twoim specyfikacjom. Na przykład:
features = tfds.features.FeaturesDict({
'image':
tfds.features.Image(
shape=(256, 256, 3),
doc='Picture taken by smartphone, downscaled.'),
'label':
tfds.features.ClassLabel(names=['dog', 'cat']),
'objects':
tfds.features.Sequence({
'camera/K': tfds.features.Tensor(shape=(3,), dtype=tf.float32),
}),
})
Odpowiada następującym specyfikacjom tf.train.Example
:
{
'image': tf.io.FixedLenFeature(shape=(), dtype=tf.string),
'label': tf.io.FixedLenFeature(shape=(), dtype=tf.int64),
'objects/camera/K': tf.io.FixedLenSequenceFeature(shape=(3,), dtype=tf.int64),
}
Określenie funkcji umożliwia TFDS automatyczne dekodowanie obrazów, wideo,... Podobnie jak w przypadku innych zbiorów danych TFDS, metadane funkcji (np. nazwy etykiet,...) będą widoczne dla użytkownika (np. info.features['label'].names
).
Jeśli kontrolujesz potok generowania
Jeśli generujesz zestawy danych poza TFDS, ale nadal kontrolujesz potok generowania, możesz użyć tfds.features.FeatureConnector.serialize_example
aby zakodować dane z dict[np.ndarray]
do tf.train.Example
proto bytes
:
with tf.io.TFRecordWriter('path/to/file.tfrecord') as writer:
for ex in all_exs:
ex_bytes = features.serialize_example(data)
writer.write(ex_bytes)
Zapewni to zgodność funkcji z TFDS.
Podobnie istnieje feature.deserialize_example
do dekodowania proto ( przykład )
Jeśli nie kontrolujesz potoku generowania
Jeśli chcesz zobaczyć, jak tfds.features
są reprezentowane w tf.train.Example
, możesz sprawdzić to w Colab:
- Aby przetłumaczyć
tfds.features
na czytelną dla człowieka strukturę plikutf.train.Example
, możesz wywołać funkcjęfeatures.get_serialized_info()
. - Aby uzyskać dokładną
FixedLenFeature
,... specyfikację przekazaną dotf.io.parse_single_example
, możesz użyćspec = features.tf_example_spec
Uzyskaj statystyki dotyczące podziałów
TFDS wymaga znajomości dokładnej liczby przykładów w każdym fragmencie. Jest to wymagane w przypadku funkcji takich jak len(ds)
lub API subplit : split='train[75%:]'
.
Jeśli posiadasz te informacje, możesz jawnie utworzyć listę
tfds.core.SplitInfo
i przejść do następnej sekcji:split_infos = [ tfds.core.SplitInfo( name='train', shard_lengths=[1024, ...], # Num of examples in shard0, shard1,... num_bytes=0, # Total size of your dataset (if unknown, set to 0) ), tfds.core.SplitInfo(name='test', ...), ]
Jeśli nie znasz tych informacji, możesz je obliczyć za pomocą skryptu
compute_split_info.py
(lub własnego skryptu za pomocątfds.folder_dataset.compute_split_info
). Uruchomi potok wiązki, który odczyta wszystkie fragmenty w podanym katalogu i obliczy informacje.
Dodaj pliki metadanych
Aby automatycznie dodać odpowiednie pliki metadanych do zbioru danych, użyj tfds.folder_dataset.write_metadata
:
tfds.folder_dataset.write_metadata(
data_dir='/path/to/my/dataset/1.0.0/',
features=features,
# Pass the `out_dir` argument of compute_split_info (see section above)
# You can also explicitly pass a list of `tfds.core.SplitInfo`.
split_infos='/path/to/my/dataset/1.0.0/',
# Pass a custom file name template or use None for the default TFDS
# file name template.
filename_template='{SPLIT}-{SHARD_X_OF_Y}.{FILEFORMAT}',
# Optionally, additional DatasetInfo metadata can be provided
# See:
# https://www.tensorflow.org/datasets/api_docs/python/tfds/core/DatasetInfo
description="""Multi-line description."""
homepage='http://my-project.org',
supervised_keys=('image', 'label'),
citation="""BibTex citation.""",
)
Po jednorazowym wywołaniu funkcji w katalogu zestawu danych pliki metadanych ( dataset_info.json
,...) zostały dodane i zbiory danych są gotowe do załadowania za pomocą TFDS (patrz następna sekcja).
Załaduj zestaw danych za pomocą TFDS
Bezpośrednio z folderu
Po wygenerowaniu metadanych zestawy danych można załadować za pomocą tfds.builder_from_directory
, który zwraca tfds.core.DatasetBuilder
ze standardowym API TFDS (np. tfds.builder
):
builder = tfds.builder_from_directory('~/path/to/my_dataset/3.0.0/')
# Metadata are available as usual
builder.info.splits['train'].num_examples
# Construct the tf.data.Dataset pipeline
ds = builder.as_dataset(split='train[75%:]')
for ex in ds:
...
Bezpośrednio z wielu folderów
Możliwe jest także ładowanie danych z wielu folderów. Może się to zdarzyć na przykład podczas uczenia się przez wzmacnianie, gdy wielu agentów generuje oddzielny zestaw danych i chcesz załadować je wszystkie razem. Inne przypadki użycia mają miejsce, gdy regularnie tworzony jest nowy zbiór danych, np. nowy zbiór danych dziennie, a użytkownik chce załadować dane z zakresu dat.
Aby załadować dane z wielu folderów, użyj tfds.builder_from_directories
, który zwraca tfds.core.DatasetBuilder
ze standardowym API TFDS (jak tfds.builder
):
builder = tfds.builder_from_directories(builder_dirs=[
'~/path/my_dataset/agent1/1.0.0/',
'~/path/my_dataset/agent2/1.0.0/',
'~/path/my_dataset/agent3/1.0.0/',
])
# Metadata are available as usual
builder.info.splits['train'].num_examples
# Construct the tf.data.Dataset pipeline
ds = builder.as_dataset(split='train[75%:]')
for ex in ds:
...
Struktura folderów (opcjonalnie)
Aby uzyskać lepszą kompatybilność z TFDS, możesz uporządkować swoje dane jako <data_dir>/<dataset_name>[/<dataset_config>]/<dataset_version>
. Na przykład:
data_dir/
dataset0/
1.0.0/
1.0.1/
dataset1/
config0/
2.0.0/
config1/
2.0.0/
Dzięki temu Twoje zbiory danych będą kompatybilne z interfejsem API tfds.load
/ tfds.builder
, po prostu podając data_dir/
:
ds0 = tfds.load('dataset0', data_dir='data_dir/')
ds1 = tfds.load('dataset1/config0', data_dir='data_dir/')