如何将Tensorflow数据集转换为2D numpy数组

6

我有一个 TensorFlow 数据集,其中包含近 15000 张分辨率为 168*84 的彩色图片和每张图片的标签。它的类型和形状如下:

< ConcatenateDataset shapes: ((168, 84, 3), ()), types: (tf.float32, tf.int32)>

我需要使用它来训练我的神经网络,这就是为什么我需要将其作为参数传递给我构建层的函数:

def cnn_model_fn(features, labels, mode):

  input_layer = tf.reshape(features["x"], [-1, 168, 84, 3])
  # Convolutional Layer #1
  conv1 = tf.layers.conv2d(
     inputs=input_layer,
     filters=32,
     kernel_size=[5, 5],
     padding="same",
     activation=tf.nn.relu)
.
.
.

我尝试使用tf.eval()和np.ravel()将每个张量转换为np.array(我猜这是上述函数的适当类型),但我失败了。
那么,我该如何将这个数据集转换为适当的类型以传递给函数呢?
此外
我是Python和TensorFlow的新手,我不认为我理解为什么有数据集,如果我们不能直接使用它们来构建层(顺便说一下,我正在按照TensorFlow网站上的教程进行)。
谢谢。
5个回答

5
你可以尝试使用急切执行(eager execution),之前我用session run给出了一个答案(如下所示)。
在急切执行中,对张量(tensor)使用.numpy()会将其转换为numpy数组。
示例代码(来自我的用例):

    #enable eager execution
    from __future__ import absolute_import, division, print_function, unicode_literals
    import tensorflow as tf
    tf.enable_eager_execution()
    print('Is executing eagerly?',tf.executing_eagerly())      

    #load datasets
    import tensorflow_datasets as tfds
    dataset, metadata = tfds.load('cycle_gan/horse2zebra',
                                  with_info=True, as_supervised=True)
    train_horses, train_zebras = dataset['trainA'], dataset['trainB']

    #load dataset in to numpy array 
    train_A=train_horses.batch(1000).make_one_shot_iterator().get_next()[0].numpy()
    print(train_A.shape)

    #preview one of the images
    import matplotlib.pyplot as plt
    %matplotlib inline
    import numpy as np
    print(train_A.shape)
    plt.imshow(train_A[1])
    plt.show()

旧的会话运行时,答案如下:

最近我遇到了这个问题,我是这样解决的:


    #load datasets
    import tf
    import tensorflow_datasets as tfds
    dataset, metadata = tfds.load('cycle_gan/horse2zebra',
                                  with_info=True, as_supervised=True)
    train_horses, train_zebras = dataset['trainA'], dataset['trainB']

    #load dataset in to numpy array
    sess = tf.compat.v1.Session()
    tra=train_horses.batch(1000).make_one_shot_iterator().get_next()
    train_A=np.array(sess.run(tra)[0])
    print(train_A.shape)
    sess.close()

    #preview one of the images
    import matplotlib.pyplot as plt
    %matplotlib inline
    import numpy as np
    print(train_A.shape)
    plt.imshow(train_A[1])
    plt.show()


3
这对于我来说是解决带有 (X, y) 作为监督问题的最简单方法。
def dataset_to_numpy(ds):
    """
    Convert tensorflow dataset to numpy arrays
    """
    images = []
    labels = []

    # Iterate over a dataset
    for i, (image, label) in enumerate(tfds.as_numpy(ds)):
        images.append(image)
        labels.append(label)

    for i, img in enumerate(images):
        if i < 3:
            print(img.shape, labels[i])

    return images, labels

用法:

    ds = tfds.load('mnist', split='train', as_supervised=True)

3
看起来你没有使用Tensorflow数据集管道来设置东西,这里是操作指南:https://www.tensorflow.org/programmers_guide/datasets。你可以遵循这个指南(这是正确的方法,但需要一些学习曲线),或者你可以将numpy数组作为feed_dict参数的一部分传递给sess.run。如果你选择后者,那么你应该创建一个tf.placeholder,它将由feed_dict中的值填充。这里有许多基本教程示例都采用这种方法:https://github.com/aymericdamien/TensorFlow-Examples

3

我也需要完成这个任务(将数据集转换为数组),但不想开启急切模式。我设法想出了以下方法:

dataset = tf.data.Dataset.from_tensor_slices([[1,2],[3,4]])

tensor_array = tf.TensorArray(dtype=dataset.element_spec.dtype,
                              size=0,
                              dynamic_size=True,
                              element_shape=dataset.element_spec.shape)
tensor_array = dataset.reduce(tensor_array, lambda a, t: a.write(a.size(), t))
tensor = tf.reshape(tensor_array.concat(), (-1,)+tuple(dataset.element_spec.shape))
array = tf.Session().run(tensor)

print(type(array))
# <class 'numpy.ndarray'>

print(array)
# [[1 2]
#  [3 4]]

这段代码的作用是:

我们有一个形状为(2,)的张量数据集。

由于eager模式已关闭,因此我们需要通过Tensorflow会话运行数据集。并且由于会话需要张量,因此我们必须将数据集转换为张量。

为了实现这一目标,我们使用Dataset.reduce()将所有元素放入TensorArray中(符号化)。

然后我们使用TensorArray.concat()将整个数组转换为单个张量。但是当我们执行此操作时,整个数据集被压缩成1-D数组。因此,我们需要使用tf.reshape()将其恢复为原始张量的形状,并增加一个额外的维度来堆叠它们所有。

最后,我们取出张量并通过会话运行它。这将给我们numpy ndarray。


1
你可以使用以下方法获取图像及其相应的标题:
def separate_dataset(dataset):
    images, labels = tf.compat.v1.data.make_one_shot_iterator(dataset.batch(len(dataset))).get_next()
    return images, labels

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接