Si tiene un tf.train.Example
(dentro de .tfrecord
, .riegeli
,...), que ha sido generado por herramientas de terceros, que le gustaría cargar directamente con la API de tfds, entonces esta página es para usted.
Para cargar sus archivos .tfrecord
, solo necesita:
- Siga la convención de nomenclatura de TFDS.
- Agregue archivos de metadatos (
dataset_info.json
,features.json
) junto con sus archivos tfrecord.
Limitaciones:
-
tf.train.SequenceExample
no es compatible, solotf.train.Example
. - Debe poder expresar
tf.train.Example
en términos detfds.features
(consulte la sección a continuación).
Convención de nomenclatura de archivos
TFDS admite la definición de una plantilla para nombres de archivos, lo que brinda flexibilidad para usar diferentes esquemas de nombres de archivos. La plantilla está representada por tfds.core.ShardedFileTemplate
y admite las siguientes variables: {DATASET}
, {SPLIT}
, {FILEFORMAT}
, {SHARD_INDEX}
, {NUM_SHARDS}
y {SHARD_X_OF_Y}
. Por ejemplo, el esquema de nombres de archivo predeterminado de TFDS es: {DATASET}-{SPLIT}.{FILEFORMAT}-{SHARD_X_OF_Y}
. Para MNIST, esto significa que los nombres de archivo tienen el siguiente aspecto:
-
mnist-test.tfrecord-00000-of-00001
-
mnist-train.tfrecord-00000-of-00001
Agregar metadatos
Proporcione la estructura de características
Para que TFDS pueda descodificar el tf.train.Example
, debe proporcionar la estructura tfds.features
que coincida con sus especificaciones. Por ejemplo:
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),
}),
})
Corresponde a las siguientes especificaciones de 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),
}
Especificar las funciones permite que TFDS decodifique automáticamente imágenes, videos,... Como cualquier otro conjunto de datos de TFDS, los metadatos de las funciones (p. ej., nombres de etiquetas,...) estarán expuestos al usuario (p. ej info.features['label'].names
).
Si controlas el gasoducto de generación
Si genera conjuntos de datos fuera de TFDS pero aún controla la canalización de generación, puede usar tfds.features.FeatureConnector.serialize_example
para codificar sus datos de dict[np.ndarray]
a 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)
Esto garantizará la compatibilidad de funciones con TFDS.
Del mismo modo, existe un feature.deserialize_example
para decodificar el prototipo ( ejemplo )
Si no controlas el pipeline de generación
Si desea ver cómo se representan tfds.features
en un tf.train.Example
, puede examinar esto en colab:
- Para traducir
tfds.features
a la estructura legible por humanos detf.train.Example
, puede llamar a functions.get_serialized_infofeatures.get_serialized_info()
. - Para obtener la especificación
FixedLenFeature
exacta,... pasada atf.io.parse_single_example
, puede usarspec = features.tf_example_spec
Obtener estadísticas sobre divisiones
TFDS requiere saber el número exacto de ejemplos dentro de cada fragmento. Esto es necesario para funciones como len(ds)
o la API subdividida : split='train[75%:]'
.
Si tiene esta información, puede crear explícitamente una lista de
tfds.core.SplitInfo
y pasar a la siguiente sección: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', ...), ]
Si no conoce esta información, puede calcularla utilizando el script
compute_split_info.py
(o en su propio script contfds.folder_dataset.compute_split_info
). Lanzará una tubería de haz que leerá todos los fragmentos en el directorio dado y calculará la información.
Agregar archivos de metadatos
Para agregar automáticamente los archivos de metadatos adecuados a lo largo de su conjunto de datos, use 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.""",
)
Una vez que se haya llamado a la función una vez en el directorio de su conjunto de datos, se agregarán los archivos de metadatos ( dataset_info.json
,...) y sus conjuntos de datos estarán listos para cargarse con TFDS (consulte la siguiente sección).
Cargar conjunto de datos con TFDS
Directamente desde la carpeta
Una vez que se han generado los metadatos, los conjuntos de datos se pueden cargar mediante tfds.builder_from_directory
que devuelve un tfds.core.DatasetBuilder
con la API de TFDS estándar (como 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:
...
Directamente desde varias carpetas
También es posible cargar datos de varias carpetas. Esto puede suceder, por ejemplo, en el aprendizaje por refuerzo cuando varios agentes generan cada uno un conjunto de datos independiente y desea cargarlos todos juntos. Otros casos de uso son cuando se produce un nuevo conjunto de datos de forma regular, por ejemplo, un nuevo conjunto de datos por día, y desea cargar datos de un rango de fechas.
Para cargar datos de varias carpetas, utilice tfds.builder_from_directories
, que devuelve un tfds.core.DatasetBuilder
con la API de TFDS estándar (como 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:
...
Estructura de carpetas (opcional)
Para una mejor compatibilidad con TFDS, puede organizar sus datos como <data_dir>/<dataset_name>[/<dataset_config>]/<dataset_version>
. Por ejemplo:
data_dir/
dataset0/
1.0.0/
1.0.1/
dataset1/
config0/
2.0.0/
config1/
2.0.0/
Esto hará que sus conjuntos de datos sean compatibles con la API tfds.load
/ tfds.builder
, simplemente proporcionando data_dir/
:
ds0 = tfds.load('dataset0', data_dir='data_dir/')
ds1 = tfds.load('dataset1/config0', data_dir='data_dir/')