TensorFlow.Data.Dataset 和 DatasetV1Adapter 一样吗?

the*_*Ngo 7 python tensorflow google-colaboratory

当我使用:

training_ds = tf.data.Dataset.from_generator(SomeTrainingDirectoryIterator, (tf.float32, tf.float32))
Run Code Online (Sandbox Code Playgroud)

我希望它返回一个 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()))
Run Code Online (Sandbox Code Playgroud)

使用 training_ds 作为我的数据集,我抛出了这个错误:

AttributeError: 'tensorflow.python.framework.ops.EagerTensor' 对象没有属性 'items'

更新:我将我的 TensorFlow 版本从 1.14 升级到 2.0。现在数据集是一个 FlatMapDataset。但这仍然不是我预期的返回对象,为什么我没有返回常规的 tf.data.Dataset?

小智 6

如果您使用 Tensorflow 2.0(或更低版本)from_generator将为您提供DatasetV1Adapter. 对于大于 2.0 的 Tensorflow 版本from_generator将为您提供FlatMapDataset.

您遇到的错误与数据集返回的类型无关from_generator,而是与打印数据集的方式有关。batch.items()如果from_generator正在生成类型的数据,则有效<class 'dict'>

示例 1 -这里我使用它from_generator来创建<class 'tuple'>类型数据。因此,如果我使用 进行打印batch.items(),那么它会抛出您面临的错误。您可以简单地使用list(dataset.as_numpy_iterator())打印数据集或dataset.take(1).as_numpy_iterator()打印所需数量的记录,这里take(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))
Run Code Online (Sandbox Code Playgroud)

输出 -

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'
Run Code Online (Sandbox Code Playgroud)

示例 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))
Run Code Online (Sandbox Code Playgroud)

输出 -

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.]]
Run Code Online (Sandbox Code Playgroud)

希望这能回答您的问题。快乐学习。