Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/323.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何在tf.data.Dataset中输入不同大小的列表列表_Python_Tensorflow_Tensorflow Datasets - Fatal编程技术网

Python 如何在tf.data.Dataset中输入不同大小的列表列表

Python 如何在tf.data.Dataset中输入不同大小的列表列表,python,tensorflow,tensorflow-datasets,Python,Tensorflow,Tensorflow Datasets,我有一个很长的整数列表(表示句子,每个句子的大小不同),我想使用tf.data库提供这些整数。每个列表(列表的列表)有不同的长度,我得到一个错误,我可以在这里重现: t = [[4,2], [3,4,5]] dataset = tf.data.Dataset.from_tensor_slices(t) 我得到的错误是: ValueError: Argument must be a dense tensor: [[4, 2], [3, 4, 5]] - got shape [2], but wa

我有一个很长的整数列表(表示句子,每个句子的大小不同),我想使用tf.data库提供这些整数。每个列表(列表的列表)有不同的长度,我得到一个错误,我可以在这里重现:

t = [[4,2], [3,4,5]]
dataset = tf.data.Dataset.from_tensor_slices(t)
我得到的错误是:

ValueError: Argument must be a dense tensor: [[4, 2], [3, 4, 5]] - got shape [2], but wanted [2, 2].
有办法做到这一点吗


编辑1:为了清楚起见,我不想填充列表的输入列表(这是一个包含超过一百万个元素的句子列表,长度不同),我想使用tf.data库以适当的方式输入,具有不同长度的列表列表。

我认为tensorflow不支持在给定维度上具有不同数量元素的张量

但是,一个简单的解决方案是用尾随零填充嵌套列表(如有必要):

产出:

[[4, 2, 0], [3, 4, 5]]
<TensorSliceDataset shapes: (3,), types: tf.int32>
[[4,2,0],[3,4,5]]
对于模型来说,零不应该是一个大问题:从语义上讲,它们只是每个实际句子列表末尾大小为零的额外句子。

您可以使用它将任何iterable Python对象(如列表列表)转换为
数据集

t = [[4, 2], [3, 4, 5]]

dataset = tf.data.Dataset.from_generator(lambda: t, tf.int32, output_shapes=[None])

iterator = dataset.make_one_shot_iterator()
next_element = iterator.get_next()

with tf.Session() as sess:
  print(sess.run(next_element))  # ==> '[4, 2]'
  print(sess.run(next_element))  # ==> '[3, 4, 5]'

除了@mrry的答案外,如果要创建(图像、标签)对,还可以使用以下代码:


对于那些使用TensorFlow 2并寻找答案的人 我发现以下内容可以直接用于不规则张量。 只要整个数据集都放在内存中,它应该比生成器快得多

t = [[[4,2]],
     [[3,4,5]]]

rt=tf.ragged.constant(t)
dataset = tf.data.Dataset.from_tensor_slices(rt)

for x in dataset:
  print(x)
产生



出于某种原因,在单个数组上至少有两个维度是非常特别的。

嗨,谢谢你的回答,因为我不能填充整个列表,因为它太大了。我将为每个批次进行填充,但不是为由数百万个句子组成的整个数据集进行填充。如果您将句子列表(字符串列表)传递到
tf.data.dataset.from_tensor_slices
,它应该可以工作,然后您应该能够使用
dataset.map(您的函数)
将每个句子转换为整数列表。然后,您可以使用
dataset.padded\u batch
自动添加填充。这个示例非常有用:Hi@OlivierMoindrot,我已经看到了这个示例。我关心的是:在训练时运行图形时(即每次向模型提供新数据时),还是在训练前在整个数据集上执行,然后提供结果时,会执行映射函数?在我看来,与第二个相比,第一个训练要慢得多,这就是我想要避免的。这就是
tf.data
的全部要点,它在后台使用队列,只在需要时处理数据。您可以“预取”数据,以确保您的GPU从不等待数据,并以100%的速度工作。由于数据在一端消耗(用于培训),因此之前的队列将被数据填满。您甚至可以使用
num\u parallel\u调用
.dataset拥有多个worker。prefetch@mrry,我的想法是一样的,来自生成器的数据集可以成批处理,我的意思是使其成为一个小批量?+1但供参考,tf 2.1不再需要额外的括号
import itertools
data = tf.data.Dataset.from_generator(lambda: itertools.izip_longest(images, labels),
                                      output_types=(tf.float32, tf.float32),
                                      output_shapes=(tf.TensorShape([None, None, 3]), 
                                                     tf.TensorShape([None])))

iterator = dataset.make_one_shot_iterator()
next_element = iterator.get_next()

with tf.Session() as sess:
    image, label = sess.run(next_element)  # ==> shape: [320, 420, 3], [20]
    image, label = sess.run(next_element)  # ==> shape: [1280, 720, 3], [40]
t = [[[4,2]],
     [[3,4,5]]]

rt=tf.ragged.constant(t)
dataset = tf.data.Dataset.from_tensor_slices(rt)

for x in dataset:
  print(x)
<tf.RaggedTensor [[4, 2]]>
<tf.RaggedTensor [[3, 4, 5]]>