tf.data.Dataset
内の要素のセット全体を取得する簡単な方法はありますか?つまり、データセットのバッチサイズを、要素数を明示的に渡さずにデータセットのサイズに設定したいと考えています。これは、データセット全体の精度を一度に測定したい検証データセットに役立ちます。 tf.data.Dataset
のサイズを取得する方法がないことに驚いています
tf.data
APIは、適切な接頭辞/接尾辞(該当する場合)を使用して、'tensors/component'
というテンソルを作成します。インスタンスを作成した後。名前でテンソルを評価し、バッチサイズとして使用できます。
#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
つまり、サイズ/長さを取得する良い方法はありません。 _tf.data.Dataset
_はデータのパイプライン用に構築されているため、イテレーター構造を持っています(私の理解では、私の読んだ Dataset opsコード に従います。 プログラマーズガイド から) :
_
tf.data.Iterator
_は、データセットから要素を抽出する主な方法を提供します。Iterator.get_next()
によって返される操作は、実行時にデータセットの次の要素を生成し、通常、入力パイプラインコードとモデル間のインターフェースとして機能します。
そして、その性質上、反復子にはサイズ/長さという便利な概念がありません。ここを参照してください: Pythonのイテレータの要素数を取得する
より一般的には、なぜこの問題が発生するのですか? batch
を呼び出すと、_tf.data.Dataset
_も取得されるため、バッチで実行しているものはすべて、データセット全体で実行できるはずです。すべての要素を反復処理し、検証精度を計算します。言い換えれば、あなたがやりたいことをするのに実際にサイズ/長さが必要だとは思わない。
Tensorflow 2.0で
as_numpy_iterator を使用してデータセットを列挙できます
for element in Xtrain.as_numpy_iterator():
print(element)
TensorFlowの最新バージョンでこれがまだ機能するかどうかはわかりませんが、これが絶対に必要な場合は、データセットのサイズよりも大きいバッチを作成するというハックなソリューションがあります。データセットの大きさを知る必要はありません。より大きなバッチサイズをリクエストするだけです。