TensorFlow中预加载数据分割及张量版FixedLengthRecordReader实现咨询
问题1:如何将预加载的数据沿0维按固定长度分割,配合TensorFlow的QueueRunner使用?
给你个直接适配现有流程的方案:用tf.train.slice_input_producer来逐个取出预加载张量里的单样本,它会自动帮你处理数据遍历(包括循环打乱),完美衔接后续的batch打包和QueueRunner机制。
结合你的代码场景,第4步可以这么写:
class DATABASERecord(object): pass result = DATABASERecord() database = get_pre_load_data() # 用slice_input_producer逐个提取单样本,训练时建议开启shuffle single_image, single_label = tf.train.slice_input_producer( [database.images, database.labels], shuffle=True, num_epochs=None # 设置为None表示无限循环遍历数据,也可以指定具体轮数 ) result.image = single_image result.label = single_label return result
这样后面的图像增强、tf.train.batch打包步骤就能直接对接,QueueRunner也能正常启动工作——因为slice_input_producer本身就基于TensorFlow的队列机制实现。
问题2:是否存在与tf.FixedLengthRecordReader类似,但从张量而非文件加载数据的工具?
TensorFlow原生没有和tf.FixedLengthRecordReader完全对等的张量版工具,但可以用上面提到的tf.train.slice_input_producer或者tf.data.Dataset(如果用的是较新版本TensorFlow)来实现类似“按固定长度(单样本)读取”的效果。
如果想更贴近Reader的思路,也可以手动维护一个读取指针(用tf.Variable配合tf.assign_add),逐个从预加载张量中切片,但这种方式不如slice_input_producer简洁高效。
另外你自己找到的“转存为二进制文件再用FixedLengthRecordReader加载”的方案也完全可行,适合数据量超大、内存存不下的场景,但如果数据已经在内存里,直接用张量级别的操作会节省IO开销,效率更高。
多GPU环境的小提示
因为你是在多GPU系统运行,后续用tf.contrib.slim.prefetch_queue预取批次数据的思路很对,能有效避免数据加载拖慢GPU计算,这部分保持你的现有实现就行。
内容的提问来源于stack exchange,提问作者Milan

