web-dev-qa-db-ja.com

TensorFlow.Data.DatasetはDatasetV1Adapterと同じですか?

私が使うとき:

training_ds = tf.data.Dataset.from_generator(SomeTrainingDirectoryIterator, (tf.float32, tf.float32))

Tensorflowデータセットが返されることを期待していますが、代わりに、training_dsはDatasetV1Adapterオブジェクトです。それらは本質的に同じものですか?できない場合、DatasetV1AdapterをTf.Data.Datasetオブジェクトに変換できますか?

また、ループオーバーを表示してデータセットを表示する最良の方法は何ですか?私が電話した場合:

def show_batch(dataset):
    for batch, head in dataset.take(1):
        for labels, value in batch.items():
            print("{:20s}: {}".format(labels, value.numpy()))

データセットとしてtraining_dsを使用すると、次のエラーがスローされます。

AttributeError: 'tensorflow.python.framework.ops.EagerTensor'オブジェクトに属性 'items'がありません

更新:TensorFlowのバージョンを1.14から2.0にアップグレードしました。そして今、データセットはFlatMapDatasetのものです。しかし、これはまだ期待される戻りオブジェクトではありません。なぜ通常のtf.data.Datasetが返されないのですか?

5
theMoreYouNgo

Tensorflow 2.0(またはそれ以下)を使用している場合、_from_generator_は_DatasetV1Adapter_を提供します。 Tensorflowのバージョンが2.0よりも大きい場合、_from_generator_はFlatMapDatasetを返します。

発生しているエラーは、データセット_from_generator_が返すタイプとは関係ありませんが、データセットの印刷方法には関係します。 batch.items()は、_from_generator_が_<class 'dict'>_タイプのデータを生成している場合に機能します。

例1-ここでは_from_generator_を使用して_<class 'Tuple'>_タイプのデータを作成しています。したがって、batch.items()を使用して印刷すると、直面しているエラーがスローされます。単にlist(dataset.as_numpy_iterator())を使用してデータセットを印刷するOR dataset.take(1).as_numpy_iterator()を使用して、必要な数のレコードを印刷できます。ここではtake(1) 、1つのレコードだけを印刷します。コードに印刷ステートメントを追加して説明を追加しました。詳細は出力で確認できます。

_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))
_

出力-

_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'
_

例2-ここでは_from_generator_を使用して_<class 'dict'>_タイプのデータを作成しています。したがって、batch.items()を使用して印刷すると、問題なく動作します。とはいえ、単にlist(dataset.as_numpy_iterator())を使用してデータセットを印刷できます。説明をわかりやすくするために、コードに印刷ステートメントを追加しました。詳細は出力で確認できます。

_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))
_

出力-

_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.]]
_

これがあなたの質問に答えることを願っています。ハッピーラーニング。

4