TensorFlow数据集API:使用填充批处理消耗NumPy数组

时间:2018-01-18 17:46:38

标签: tensorflow tensorflow-datasets

快速免责声明:这是我第一次在堆栈溢出时问一个问题。

现在问题本身。我使用相当新的tensorflow 1.4数据集API以及读取numpy数组和填充批处理的可变长度输入时会遇到一些问题。

根据官方文档(https://www.tensorflow.org/programmers_guide/datasets#consuming_numpy_arrays),使用数组作为输入既支持又简单。现在的关键是,在将数据集对象的padded_batch方法应用于数据之前,必须先将数据输入张量流占位符。然而,可变长度输入的numpy表示不是对称的,因此被解释为序列而不是数组。但是,提供padded_batch方法背后的全部原因并不是数据集可以处理一系列可变长度输入。长话短说,有没有人经历过类似的情况并找到了解决方案呢?非常感谢你的帮助!

以下是一些代码片段,可能有助于更好地理解问题。

输入结果如下:

array([array([65,  3, 96, 94], dtype=int32), array([88], dtype=int32),
       array([113,  52, 106,  57,   3,  86], dtype=int32),
       array([88,  3, 23, 91], dtype=int32), ... ])

在填充中定义数据集的实际代码段:


for fold, (train_idx, dev_idx) in enumerate(sss.split(X, y)):

    X_train = X[train_idx]
    y_train = y[train_idx]

    X_dev = X[dev_idx]
    y_dev = y[dev_idx]

    tf.reset_default_graph()
    with tf.Session() as sess:

       features_placeholder = tf.placeholder(tf.int32, [None, None], name='input_x')
       labels_placeholder = tf.placeholder(tf.int32, [None, num_classes], name='input_y')

       dataset = tf.data.Dataset.from_tensor_slices((features_placeholder, labels_placeholder))

       dataset = dataset.shuffle(buffer_size=len(train_idx))
       dataset = dataset.padded_batch(batch_size, padded_shapes=([None], [None]), padding_values=(1, 0))

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

       sess.run(iterator.initializer, feed_dict={features_placeholder: np.array(X_train),
                                                 labels_placeholder: np.array(y_train)})

最后,来自jupyter notebook的相应堆栈跟踪:

    X_train = X[train_idx]
    y_train = y[train_idx]

    X_dev = X[dev_idx]
    y_dev = y[dev_idx]

    tf.reset_default_graph()
    with tf.Session() as sess:

       features_placeholder = tf.placeholder(tf.int32, [None, None], name='input_x')
       labels_placeholder = tf.placeholder(tf.int32, [None, num_classes], name='input_y')

       dataset = tf.data.Dataset.from_tensor_slices((features_placeholder, labels_placeholder))

       dataset = dataset.shuffle(buffer_size=len(train_idx))
       dataset = dataset.padded_batch(batch_size, padded_shapes=([None], [None]), padding_values=(1, 0))

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

       sess.run(iterator.initializer, feed_dict={features_placeholder: np.array(X_train),
                                                 labels_placeholder: np.array(y_train)})

再次感谢您的支持。

1 个答案:

答案 0 :(得分:1)

我遇到了同样的问题,直到我偶然发现了来自tensorflow问题线程的这个link here。显然,根据链接,处理不同长度输入的解决方法是使用Dataset.from_generator。有问题的API是here。 由于我也有输入和标签矢量,我所做的是使用zip函数迭代输入和标签:

zipped = list(zip(x_train,y_train))
dataset = tf.data.Dataset.from_generator(lambda: zipped, (tf.int32, tf.int32))
dataset = dataset.padded_batch(batch_size, padded_shapes=([None], [None]), padding_values=(1, 0))
iterator = dataset.make_one_shot_iterator()
next_element = iterator.get_next()