我正在编写一些简单的代码来计算TFRecord文件中Examples的数量。以前我用的是这样的东西:
定义计数示例(路径):返回和(tf.python_io.tf_record_iterator(路径)中的_为1)定义计数总计示例(tfrecord_glob_pattern):example_count=0路径=glob.glob(tfrecord_glob_pattern)未来。ProcessPoolExecutor(max_workers=os.cpu_count())作为执行器:results=executor.map(_count_example,paths,chunksize=max(len(paths)//os.cpu_count(),1)对于结果:example_count+=结果返回example_count
我已经将测试TFRecord输入复制到RAM磁盘,以确保我们没有被I/O阻塞。我的测试TFRecort文件有635424个图像文件,有128个碎片。上述代码在13秒内完成。
我正在尝试将相同的代码更改为使用tf.数据
看看我能不能得到类似的结果。所以我正在做的事情是:
定义计数总计示例(tfrecord_glob_pattern):数据集=tf.data。数据集.list_files(tfrecord_glob_pattern,shuffle=False)数据集=tf.data。TFRecordDataset(数据集,num_parallel_reads=os.cpu_count())迭代器=数据集.make_one_shot_iterator()next_element=迭代器.get_next()tf.Session()作为sess:example_count=0对于_ in trange(635424):sess.run(next_element)example_count+=1返回example_count
此版本需要2分钟以上才能完成。我想这是因为我在打电话sess.run()
次数太多,这会带来非平凡的开销。为了验证这一说法,我将上述代码更改为:
定义计数总计示例(tfrecord_glob_pattern):数据集=tf.data。数据集.list_files(tfrecord_glob_pattern,shuffle=False)数据集=tf.data。TFRecordDataset(数据集,num_parallel_reads=os.cpu_count())数据集=数据集.map(lambda _:1,num_parallel_calls=os.cpu_count())dataset=数据集.batch(4096)迭代器=数据集.make_one_shot_iterator()next_element=迭代器.get_next()tf.Session()作为sess:example_count=0对于_ in trange(635424//4096):sess.run(下一个元素)example_count+=1返回example_count
这一次,代码在30秒内完成——这仍然不理想,但我想更好。基本上,根据我的上述观察,我有两个问题:
1) 解决这个问题的有效方法是什么?或者我应该继续使用tf.python_o.tf_record_iterator
?
2) 在TensorFlow图中是否有一种方法可以“循环整个数据集,然后返回最终结果”?我试过这样的tf.contrib.data。减速器
但似乎还是很慢(大约需要一分钟才能完成):
定义计数总计示例(tfrecord_glob_pattern):数据集=tf.data。数据集.list_files(tfrecord_glob_pattern,shuffle=False)数据集=tf.data。TFRecordDataset(数据集,num_parallel_reads=os.cpu_count()*2)减速器=tf.contrb.data。减速器(init_func=λ_:0,reduce_func=λ电流,_:电流+1,finalize_func=λ电流:电流)dataset=tf.contrib.data.reduce_dataset(数据集,减速机)tf.Session()作为sess:结果=sess.run(数据集)example_count=结果返回example_count