Quand j'utilise:
training_ds = tf.data.Dataset.from_generator(SomeTrainingDirectoryIterator, (tf.float32, tf.float32))
Je m'attends à ce qu'il renvoie un ensemble de données Tensorflow, mais à la place, training_ds est un objet DatasetV1Adapter. Sont-ils essentiellement la même chose? Sinon, pourrais-je convertir le DatasetV1Adapter en un objet Tf.Data.Dataset?
De plus, quelle est la meilleure façon de visualiser la boucle et de visualiser mon ensemble de données? Si je devais appeler:
def show_batch(dataset):
for batch, head in dataset.take(1):
for labels, value in batch.items():
print("{:20s}: {}".format(labels, value.numpy()))
Avec training_ds comme ensemble de données, je reçois cette erreur:
AttributeError: l'objet 'tensorflow.python.framework.ops.EagerTensor' n'a pas d'attribut 'items'
MISE À JOUR: J'ai mis à jour ma version de TensorFlow de 1.14 à 2.0. et maintenant l'ensemble de données est d'un FlatMapDataset. Mais ce n'est toujours pas mon objet de retour attendu, pourquoi ne suis-je pas retourné un tf.data.Dataset normal?
Si vous utilisez Tensorflow 2.0 (ou inférieur), from_generator
Vous donnera DatasetV1Adapter
. Pour la version de Tensorflow supérieure à 2.0, from_generator
Vous donnera FlatMapDataset
.
L'erreur à laquelle vous faites face n'est pas liée au type de jeu de données from_generator
Renvoie, mais à la façon dont vous imprimez le jeu de données. batch.items()
fonctionne si le from_generator
génère les données de type <class 'dict'>
.
Exemple 1 - Ici, j'utilise from_generator
Pour créer des données de type <class 'Tuple'>
. Donc, si j'imprime en utilisant batch.items()
, cela renvoie l'erreur à laquelle vous faites face. Vous pouvez simplement utiliser list(dataset.as_numpy_iterator())
pour imprimer l'ensemble de données OR dataset.take(1).as_numpy_iterator()
pour imprimer le nombre d'enregistrements requis, ici tel quel take(1)
, il imprime un seul enregistrement. Ont ajouté des instructions d'impression dans le code pour mieux expliquer. Vous pouvez trouver des détails dans la sortie.
import tensorflow as tf
print(tf.__version__)
import itertools
def gen():
for i in itertools.count(1):
yield (i, [1] * i)
dataset = tf.data.Dataset.from_generator(
gen,
(tf.int64, tf.int64),
(tf.TensorShape([]), tf.TensorShape([None])))
print("tf.data.Dataset type is:",dataset,"\n")
for batch in dataset.take(1):
print("My type is of:",type(batch),"\n")
# This Works
print("Lets print just the first row in dataset :","\n",list(dataset.take(1).as_numpy_iterator()),"\n")
# This won't work because we have not created dict
print("Lets print using the batch.items() :")
for batch in dataset.take(1):
for m1,m2 in batch.items():
print("{:20s}: {}".format(m1, m2))
Sortie -
2.2.0
tf.data.Dataset type is: <FlatMapDataset shapes: ((), (None,)), types: (tf.int64, tf.int64)>
My type is of: <class 'Tuple'>
Lets print just the first row in dataset :
[(1, array([1]))]
Lets print using the batch.items() :
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-11-27bbc2c21d24> in <module>()
24 print("Lets print using the batch.items() :")
25 for batch in dataset.take(1):
---> 26 for m1,m2 in batch.items():
27 print("{:20s}: {}".format(m1, m2))
AttributeError: 'Tuple' object has no attribute 'items'
Exemple 2 - Ici, j'utilise from_generator
Pour créer des données de type <class 'dict'>
. Donc, si j'imprime en utilisant batch.items()
, cela fonctionne sans aucun problème. Cela dit, vous pouvez simplement utiliser list(dataset.as_numpy_iterator())
pour imprimer le jeu de données. Ont ajouté des instructions d'impression dans le code pour mieux expliquer. Vous pouvez trouver des détails dans la sortie.
import tensorflow as tf
N = 100
# dictionary of arrays:
metadata = {'m1': tf.zeros(shape=(N,2)), 'm2': tf.ones(shape=(N,3,5))}
num_samples = N
def meta_dict_gen():
for i in range(num_samples):
ls = {}
for key, val in metadata.items():
ls[key] = val[i]
yield ls
dataset = tf.data.Dataset.from_generator(
meta_dict_gen,
output_types={k: tf.float32 for k in metadata},
output_shapes={'m1': (2,), 'm2': (3, 5)})
print("tf.data.Dataset type is:",dataset,"\n")
for batch in dataset.take(1):
print("My type is of:",type(batch),"\n")
print("Lets print just the first row in dataset :","\n",list(dataset.take(1).as_numpy_iterator()),"\n")
print("Lets print using the batch.items() :")
for batch in dataset.take(1):
for m1, m2 in batch.items():
print("{:2s}: {}".format(m1, m2))
Sortie -
tf.data.Dataset type is: <FlatMapDataset shapes: {m1: (2,), m2: (3, 5)}, types: {m1: tf.float32, m2: tf.float32}>
My type is of: <class 'dict'>
Lets print just the first row in dataset :
[{'m1': array([0., 0.], dtype=float32), 'm2': array([[1., 1., 1., 1., 1.],
[1., 1., 1., 1., 1.],
[1., 1., 1., 1., 1.]], dtype=float32)}]
Lets print using the batch.items() :
m1: [0. 0.]
m2: [[1. 1. 1. 1. 1.]
[1. 1. 1. 1. 1.]
[1. 1. 1. 1. 1.]]
J'espère que ça répond à ta question. Bon apprentissage.