数据读取方式大概分3种:
1.我们看tf文档里面介绍的,把mnist或者cifar10图片数据集转为特殊的二进制数据,然后通过placeholder占位符,
读取数据。但是怎么把图片转为特殊的二进制数据?不清楚,怎么特殊?自己去看mnist官网有介绍格式。
2.通过队列读取数据,为什么要用队列方式?因为比如你读取图片要m秒,gpu计算要n秒。每次完成要你n+m秒,gpu
每次要等n秒,浪费资源,所以用2队列并行线程,从而解决了io问题。一个负责读取图片,一个队列负责计算。
讲到这里其实又涉及到多线程。
队列不仅是一种数据结构,还可以用多线程同时处理一个队列里的元素,比如读写操作。tf也提供了多线程来处理队列。
tensorflow提供了tf.Coordinator和tf.QueueRunner2个类来完成多线程对队列的协同功能。
先将tf.Coordinator用于协同多个线程一起停止。提供了3个方法:tf.Coordinator.should_stop,tf.Coordinator.request_stop,tf.Coordinator.join
首先,在启动多线程之前(包括单线程,就是只有当前的主程序的时候),需要先声明一个tf.Coordinator类,
并且将这个类传入每一个创建的线程中(包括单线程,就是只有当前的主程序的时候)。只有一个队列一般就是一个线程。
所以一般我们多个队列对应多个线程。
然后,启动的线程会一直查询tf.Coordinator类中的should_stop函数,为什么可以查询?你开始每个线程都引入了
tf.Coordinator类嘛。should_stop函数有何用?当should_stop函数返回值为True,当前线程要结束,
而且所有的线程同时也结束终止。
当然,每一个启动的线程也可以通过调用tf.Coordinator类中request_stop函数来通知其他线程终止,
为什么每一线程都可以调用?你开始每个线程都引入了tf.Coordinator类嘛。为什么request_stop函数
会通知其他线程终止?本质上还是因为使得上面提到的should_stop函数返回值为True.上面说了返回true,
则其他线程退出,这样其他线程就同时终止了。
接着我们说说tf.QueueRunner类,它用于多个线程来操作同一个队列。通过和tf.Coordinator类统一管理多个线程。
一般一个队列一个线程,即使主代码里调用了tf.Coordinator.request_stop,也就意味着当前代码的队列停止,
这时候还会用tf.Coordinator.join一起终止。
等下,tensorflow官方推荐的数据存储方式是tfrecord格式,队列也可以读取tfrecord数据,图片数据等。
直接读取图片多好?为什么这么麻烦?因为每次读取图片要从文件头读到尾,当你有很多图片时候,光读取就很费时间,
所以建议先把图片转为tfrecord格式,再给队列处理。更省时间。
3.现在tf1.4以后,官方又开始主推用dataset方式读取数据,不用以前的队列方式了。貌似dataset更简洁,也功能强大,
还在研究中。dataset也可以读取图片,等其他数据。
未完待续。。。。