【问题标题】:Converting a list of unequally shaped arrays to Tensorflow 2 Dataset: ValueError: Can't convert non-rectangular Python sequence to Tensor将形状不等的数组列表转换为 Tensorflow 2 数据集:ValueError:无法将非矩形 Python 序列转换为张量
【发布时间】:2020-08-03 15:22:40
【问题描述】:

我以形状不等数组列表的形式对数据进行了标记:

array([array([1179,    6,  208,    2, 1625,   92,    9, 3870,    3, 2136,  435,
          5, 2453, 2180,   44,    1,  226,  166,    3, 4409,   49, 6728,
         ...
         10,   17, 1396,  106, 8002, 7968,  111,   33, 1130,   60,  181,
       7988, 7974, 7970])], dtype=object)

各自的目标:

Out[74]: array([0, 0, 0, ..., 0, 0, 1], dtype=object)

我正在尝试将它们转换为填充的tf.data.Dataset(),但它不会让我将不相等的形状转换为张量。我会收到这个错误:

ValueError: Can't convert non-rectangular Python sequence to Tensor.

完整的代码在这里。假设我的起点在y = ...之后:

import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3'
import tensorflow as tf
import tensorflow_datasets as tfds
import numpy as np

(train_data, test_data) = tfds.load('imdb_reviews/subwords8k',
                                    split=(tfds.Split.TRAIN, tfds.Split.TEST),
                                    as_supervised=True)

x = np.array(list(train_data.as_numpy_iterator()))[:, 0]
y = np.array(list(train_data.as_numpy_iterator()))[:, 1]


train_tensor = tf.data.Dataset.from_tensor_slices((x.tolist(), y))\
    .padded_batch(batch_size=8, padded_shapes=([None], ()))

我有什么办法可以把它变成一个填充批次张量?

【问题讨论】:

标签: python tensorflow keras tensorflow2.0 tensorflow-datasets


【解决方案1】:

如果您的数据存储在 Numpy 数组或 Python 列表中,那么您可以使用 tf.data.Dataset.from_generator 方法创建数据集,然后填充批次:

train_batches = tf.data.Dataset.from_generator(
    lambda: iter(zip(x, y)), 
    output_types=(tf.int64, tf.int64)
).padded_batch(
    batch_size=32,
    padded_shapes=([None], ())
)

但是,如果您使用tensorflow_datasets.load 函数,则无需使用as_numpy_iterator 将数据和标签分开,然后将它们重新组合到数据集中!这是多余和低效的。 tensorflow_datasets.load 返回的对象已经是tf.data.Dataset 的一个实例。所以,你只需要在他们身上使用padded_batch

train_batches = train_data.padded_batch(batch_size=32, padded_shapes=([None], []))
test_batches = test_data.padded_batch(batch_size=32, padded_shapes=([None], []))

请注意,在 TensorFlow 2.2 及更高版本中,如果您只想将所有轴填充到批处理中最长的值(即默认行为),则不再需要提供 padded_shapes 参数。

【讨论】:

  • 这样做的原因是当我做一个真正的任务时,我不会有一个方便的 TFDS 对象。我更有可能拥有一个列表/数组列表,以及单独的目标。这就是为什么我说“假设我的起点在 y = ... 之后”。感谢您通知我此更新。
  • @NicolasGervais 哦,对不起!我对此没有给予足够的重视。请查看我的更新答案,以了解您的数据存储在 Numpy 数组/Python 列表中的情况。
  • @NicolasGervais Numpy 数组的解决方案不适合你吗?
  • 项目暂停,我会在它恢复后尝试一下,然后我会回复你。
  • @NicolasGervais 好吧,一个原因是我身边没有足够的时间,另一个原因是这里没有提出有趣的问题。自然,随着 ML 和 TF/Keras 变得流行,越来越多的人在使用它,因此新手、重复、糟糕或请为我调试的问题的百分比增加了。这两个原因都降低了我在 Keras 标签中回答问题的动力,我已经停止监视这个标签。尽管有时人们会通过电子邮件向我提出他们的问题,我会尽我所能帮助他们。
猜你喜欢
  • 2019-10-11
  • 1970-01-01
  • 1970-01-01
  • 2020-12-08
  • 2019-02-04
  • 2022-11-26
  • 1970-01-01
  • 2020-11-19
  • 1970-01-01
相关资源
最近更新 更多