Avec la récente mise à niveau vers la version 1.4, Tensorflow incluait tf.data
Dans le noyau de la bibliothèque. Une "nouvelle fonctionnalité majeure" décrite dans les notes de publication de la version 1.4 est tf.data.Dataset.apply()
, qui est une "méthode pour appliquer des fonctions de transformation personnalisées". En quoi est-ce différent de celui qui existe déjà tf.data.Dataset.map()
?
La différence est que map
exécutera une fonction sur chaque élément de Dataset
séparément, tandis que apply
exécutera une fonction sur l'ensemble Dataset
à la fois ( tel que group_by_window
donné comme exemple dans la documentation).
L'argument de apply
est une fonction qui prend un Dataset
et renvoie un Dataset
lorsque l'argument de map
est une fonction qui prend un élément et retourne un élément transformé.
réponse de Sunreef est absolument correct. Vous vous demandez peut-être encore pourquoi nous avons introduit Dataset.apply()
, et j'ai pensé offrir un peu de contexte.
L'API tf.data
Possède un ensemble de transformations de base , comme Dataset.map()
et Dataset.filter()
— qui sont généralement utiles dans un large éventail d'ensembles de données, peu susceptibles de changer et implémentées en tant que méthodes sur l'objet tf.data.Dataset
. En particulier, ils sont soumis aux mêmes garanties de compatibilité descendante que les autres API principales de TensorFlow.
Cependant, l'approche de base est un peu restrictive. Nous voulons également avoir la liberté d'expérimenter de nouvelles transformations avant de les ajouter au cœur et de permettre aux autres développeurs de bibliothèque de créer leurs propres transformations réutilisables. Par conséquent, dans TensorFlow 1.4, nous avons divisé un ensemble de transformations personnalisées qui vivent dans tf.contrib.data
. Les transformations personnalisées incluent certaines qui ont des fonctionnalités très spécifiques (comme tf.contrib.data.sloppy_interleave()
), et certaines où l'API est toujours en cours de transformation (comme tf.contrib.data.group_by_window()
). À l'origine, nous avons implémenté ces transformations personnalisées en tant que fonctions de Dataset
à Dataset
, ce qui a eu un effet malheureux sur le flux syntaxique d'un pipeline. Par exemple:
dataset = tf.data.TFRecordDataset(...).map(...)
# Method chaining breaks when we apply a custom transformation.
dataset = custom_transformation(dataset, x, y, z)
dataset = dataset.shuffle(...).repeat(...).batch(...)
Comme cela semblait être un modèle courant, nous avons ajouté Dataset.apply()
comme moyen de chaîner les transformations de base et personnalisées dans un seul pipeline:
dataset = (tf.data.TFRecordDataset(...)
.map(...)
.apply(custom_transformation(x, y, z))
.shuffle(...)
.repeat(...)
.batch(...))
C'est une fonctionnalité mineure dans le grand schéma des choses, mais j'espère que cela aidera à rendre les programmes tf.data
Plus faciles à lire et la bibliothèque plus facile à étendre.
Je n'ai pas assez de réputation pour commenter, mais je voulais juste souligner que vous pouvez réellement utiliser map pour appliquer à plusieurs éléments dans un ensemble de données contrairement aux commentaires de @ sunreef sur son propre post.
Selon la documentation, la carte prend comme argument
map_func: fonction mappant une structure imbriquée de tenseurs (dont les formes et les types sont définis par self.output_shapes et self.output_types) à une autre structure imbriquée de tenseurs.
les formes_sortie sont définies par l'ensemble de données et peuvent être modifiées à l'aide de fonctions api comme batch. Ainsi, par exemple, vous pouvez effectuer une normalisation par lots en utilisant uniquement dataset.batch et .map avec:
dataset = dataset ...
dataset.batch(batch_size)
dataset.map(normalize_fn)
Il semble que l'utilitaire principal de apply()
est lorsque vous voulez vraiment faire une transformation sur l'ensemble de données entier.