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

时间:2017-11-30 18:55:39

标签: 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 wanted [2, 2].

有办法做到这一点吗?

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

4 个答案:

答案 0 :(得分:11)

您可以使用tf.data.Dataset.from_generator()将任何可迭代的Python对象(如列表列表)转换为Dataset

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

答案 1 :(得分:0)

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

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

t = [[4,2], [3,4,5]]
max_length = max(len(lst) for lst in t)
t_pad = [lst + [0] * (max_length - len(lst)) for lst in t]
print(t_pad)
dataset = tf.data.Dataset.from_tensor_slices(t_pad)
print(dataset)

输出:

[[4, 2, 0], [3, 4, 5]]
<TensorSliceDataset shapes: (3,), types: tf.int32>

对于模型来说,零不应该是一个大问题:在语义上,它们只是在每个实际句子列表的末尾加上大小为零的额外句子。

答案 2 :(得分:0)

除了@ mrry的答案之外,如果您想创建(图片,标签)对,也可以使用以下代码:

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]

答案 3 :(得分:0)

适用于使用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.RaggedTensor [[4, 2]]>
<tf.RaggedTensor [[3, 4, 5]]>

由于某些原因,在单个数组上至少有2个维非常重要。