从多个文件读取TensorFlow数据集时,将flat_map和zip结合使用:是否正在第二次从磁盘读取文件?

时间:2019-01-19 02:35:57

标签: python tensorflow tensorflow-datasets

a previous question之后,我正在使用tf.data.Dataset.zip(dataset, dataset.skip(1))生成连续项目的数据集。之所以这样做,是因为我希望让model_fn一次获得两个连续的帧,以便从中计算出差异。

当从磁盘上的多个tfrecords文件中读取时,我遇到了一个问题,即在当前的实现中有时无法保持数据集中记录的正确顺序。简化的问题可以复制为:

file1.txt (file2.txt与f2_i01,1等相同)

f1_i01,1
f1_i02,2
f1_i03,3
f1_i04,4
f1_i05,5

我的代码

import tensorflow as tf

COLUMNS = ['image', 'label']
FIELD_DEFAULTS = [['empty'], [0]]

def _line_parser(line):
    fields = tf.decode_csv(line, FIELD_DEFAULTS)
    data = dict(zip(COLUMNS, fields))
    label = data.pop('label')
    return data, label

filenames = ['file1.txt', 'file2.txt']
files = tf.data.Dataset.list_files(filenames)
dataset = files.flat_map(
    lambda filename:
        tf.data.TextLineDataset(filename)
        .map(_line_parser))
dataset = tf.data.Dataset.zip((dataset, dataset.skip(1)))

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

with tf.Session() as sess:
    sess.run(init_op)
    for i in range(5):
        print(sess.run(next_element))

如果执行此代码,可能会随机获得以下结果之一:

选项1.1:维护订单(首先读取file1.txt)

(({'image': b'f1_i01'}, 1), ({'image': b'f1_i02'}, 2))
(({'image': b'f1_i02'}, 2), ({'image': b'f1_i03'}, 3))
(({'image': b'f1_i03'}, 3), ({'image': b'f1_i04'}, 4))
(({'image': b'f1_i04'}, 4), ({'image': b'f1_i05'}, 5))
(({'image': b'f1_i05'}, 5), ({'image': b'f2_i01'}, 1))

选项1.2:维护订单(首先读取file2.txt)

(({'image': b'f2_i01'}, 1), ({'image': b'f2_i02'}, 2))
(({'image': b'f2_i02'}, 2), ({'image': b'f2_i03'}, 3))
(({'image': b'f2_i03'}, 3), ({'image': b'f2_i04'}, 4))
(({'image': b'f2_i04'}, 4), ({'image': b'f2_i05'}, 5))
(({'image': b'f2_i05'}, 5), ({'image': b'f1_i01'}, 1))

选项2.1:订单未维护(首先读取file1.txt)

(({'image': b'f1_i01'}, 1), ({'image': b'f2_i02'}, 2))
(({'image': b'f1_i02'}, 2), ({'image': b'f2_i03'}, 3))
(({'image': b'f1_i03'}, 3), ({'image': b'f2_i04'}, 4))
(({'image': b'f1_i04'}, 4), ({'image': b'f2_i05'}, 5))
(({'image': b'f1_i05'}, 5), ({'image': b'f1_i01'}, 1))

选项2.2:订单未维护(首先读取file2.txt)

(({'image': b'f2_i01'}, 1), ({'image': b'f1_i02'}, 2))
(({'image': b'f2_i02'}, 2), ({'image': b'f1_i03'}, 3))
(({'image': b'f2_i03'}, 3), ({'image': b'f1_i04'}, 4))
(({'image': b'f2_i04'}, 4), ({'image': b'f1_i05'}, 5))
(({'image': b'f2_i05'}, 5), ({'image': b'f2_i01'}, 1))

在我看来,zip函数使数据集独立于第二次从磁盘读取。有什么方法可以使我始终如一地实现选择1?

1 个答案:

答案 0 :(得分:0)

我仍然认为这令人困惑,因为我不希望zip导致文件被第二次读取。

但是,就我而言,事实证明,我要做的就是向shuffle=False添加tf.data.Dataset.list_files参数,以始终如一地实现选项1。