Si tiene un protocolo 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 tus archivos .tfrecord
, sólo necesitas:
- Siga la convención de nomenclatura 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 proporciona flexibilidad para utilizar 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 nomenclatura de archivos predeterminado de TFDS es: {DATASET}-{SPLIT}.{FILEFORMAT}-{SHARD_X_OF_Y}
. Para MNIST, esto significa que los nombres de los archivos tienen el siguiente aspecto:
-
mnist-test.tfrecord-00000-of-00001
-
mnist-train.tfrecord-00000-of-00001
Agregar metadatos
Proporcionar la estructura de características.
Para que TFDS pueda decodificar el protocolo 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 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),
}
La especificación de las características permite a TFDS decodificar automáticamente imágenes, videos,... Como cualquier otro conjunto de datos TFDS, los metadatos de las características (por ejemplo, nombres de etiquetas,...) estarán expuestos al usuario (por ejemplo, info.features['label'].names
).
Si controlas el oleoducto 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 desde 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.
De manera similar, existe un feature.deserialize_example
para decodificar el proto ( ejemplo )
Si no controlas el gasoducto 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 llamarfeatures.get_serialized_info()
. - Para obtener la especificación
FixedLenFeature
exacta,... pasada atf.io.parse_single_example
, puede usarspec = features.tf_example_spec
Obtenga estadísticas sobre divisiones
TFDS requiere conocer la cantidad exacta de ejemplos dentro de cada fragmento. Esto es necesario para funciones como len(ds)
o la API subplit : 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 usando el script
compute_split_info.py
(o en su propio script contfds.folder_dataset.compute_split_info
). Lanzará una canalización de rayos 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 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 su directorio de 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 usando tfds.builder_from_directory
, que devuelve un tfds.core.DatasetBuilder
con la API 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 múltiples 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 separado y usted 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, use tfds.builder_from_directories
, que devuelve un tfds.core.DatasetBuilder
con la API 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/')