web-dev-qa-db-fra.com

Comment faire en sorte que tf.data.Dataset renvoie tous les éléments en un seul appel?

Existe-t-il un moyen simple d’obtenir l’ensemble des éléments dans un tf.data.Dataset? Je veux définir la taille de lot du jeu de données comme étant la taille de mon jeu de données sans lui transmettre spécifiquement le nombre d'éléments Cela serait utile pour un jeu de données de validation où je veux mesurer l’exactitude de l’ensemble du jeu de données en une fois. Je suis surpris qu'il n'y ait pas de méthode pour obtenir la taille d'un tf.data.Dataset

7
Milad

En bref, il n’ya pas de moyen d’obtenir la taille/longueur; tf.data.Dataset est construit pour les pipelines de données, a donc une structure d'itérateur (si je comprends bien et d'après ce que j'ai lu le code de jeu de données . Du guide du programmeur

Un tf.data.Iterator fournit le moyen principal d'extraire des éléments d'un jeu de données. L'opération renvoyée par Iterator.get_next() renvoie l'élément suivant d'un jeu de données lors de son exécution et sert généralement d'interface entre le code de pipeline d'entrée et votre modèle.

Et, de par leur nature, les itérateurs n’ont pas de notion commode de taille/longueur; voir ici: Obtention du nombre d'éléments dans un itérateur en Python

Plus généralement, pourquoi ce problème se pose-t-il? Si vous appelez batch, vous obtenez également un tf.data.Dataset. Ainsi, quel que soit le traitement que vous exécutez sur un lot, vous devriez pouvoir l'exécuter sur l'ensemble du jeu de données; il parcourra tous les éléments et calculera la précision de la validation. Autrement dit, je ne pense pas que vous ayez réellement besoin de la taille/longueur pour faire ce que vous voulez faire.

2
muskrat

tf.data API crée un tenseur appelé 'tensors/component' avec le préfixe/suffixe approprié, le cas échéant). après avoir créé l'instance. Vous pouvez évaluer le tenseur par son nom et l'utiliser comme taille de lot.

#Ignore the warnings
import warnings
warnings.filterwarnings("ignore")

import pandas as pd
import tensorflow as tf
import numpy as np

import matplotlib.pyplot as plt
plt.rcParams['figure.figsize'] = (8,7)
%matplotlib inline


from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets("MNIST_data/")

Xtrain = mnist.train.images[mnist.train.labels < 2]
ytrain = mnist.train.labels[mnist.train.labels < 2]

print(Xtrain.shape)
#(11623, 784)
print(ytrain.shape)
#(11623,)  

#Data parameters
num_inputs = 28
num_classes = 2
num_steps=28

# create the training dataset
Xtrain = tf.data.Dataset.from_tensor_slices(Xtrain).map(lambda x: tf.reshape(x,(num_steps, num_inputs)))
# apply a one-hot transformation to each label for use in the neural network
ytrain = tf.data.Dataset.from_tensor_slices(ytrain).map(lambda z: tf.one_hot(z, num_classes))
# Zip the x and y training data together and batch and Prefetch data for faster consumption
train_dataset = tf.data.Dataset.Zip((Xtrain, ytrain)).batch(128).prefetch(128)

iterator = tf.data.Iterator.from_structure(train_dataset.output_types,train_dataset.output_shapes)
X, y = iterator.get_next()

training_init_op = iterator.make_initializer(train_dataset)

def get_tensors(graph=tf.get_default_graph()):
    return [t for op in graph.get_operations() for t in op.values()]

get_tensors()
#<tf.Tensor 'tensors_1/component_0:0' shape=(11623,) dtype=uint8>,
#<tf.Tensor 'batch_size:0' shape=() dtype=int64>,
#<tf.Tensor 'drop_remainder:0' shape=() dtype=bool>,
#<tf.Tensor 'buffer_size:0' shape=() dtype=int64>,
#<tf.Tensor 'IteratorV2:0' shape=() dtype=resource>,
#<tf.Tensor 'IteratorToStringHandle:0' shape=() dtype=string>,
#<tf.Tensor 'IteratorGetNext:0' shape=(?, 28, 28) dtype=float32>,
#<tf.Tensor 'IteratorGetNext:1' shape=(?, 2) dtype=float32>,
#<tf.Tensor 'TensorSliceDataset:0' shape=() dtype=variant>,
#<tf.Tensor 'MapDataset:0' shape=() dtype=variant>,
#<tf.Tensor 'TensorSliceDataset_1:0' shape=() dtype=variant>,
#<tf.Tensor 'MapDataset_1:0' shape=() dtype=variant>,
#<tf.Tensor 'ZipDataset:0' shape=() dtype=variant>,
#<tf.Tensor 'BatchDatasetV2:0' shape=() dtype=variant>,
#<tf.Tensor 'PrefetchDataset:0' shape=() dtype=variant>]

sess = tf.InteractiveSession()
print('Size of Xtrain: %d' % tf.get_default_graph().get_tensor_by_name('tensors/component_0:0').eval().shape[0])
#Size of Xtrain: 11623
1
ARAT

Vous ne savez pas si cela fonctionne toujours dans les dernières versions de TensorFlow, mais si cela est absolument nécessaire, une solution de hacky consiste à créer un lot d'une taille supérieure à celle de l'ensemble de données. Vous n'avez pas besoin de connaître la taille de l'ensemble de données, il vous suffit de demander une taille de lot plus grande.

0
Milad