转自:https://www.cnblogs.com/hellcat/p/8146748.html#_label0_3
目录
程序介绍
包导入
1 2 3 4 5 6 7 8 9 10 11 12 |
|
TFRecord录入格式转换
TFRecord的录入格式是确定的,整数或者二进制,在train函数中能查看所有可以接受类型
1 2 3 4 5 6 7 8 |
|
TFRecord文件写入测试
将mnist数据以每张图片为单位写入同一个TFR文件,
实际上就是每次把一个图片相关信息都写入,注意文件类型,二级制数据需要以string的格式保存
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
|
调用,
1 2 |
|
输出如下,
TFRecord文件读取测试
实际的读取基本单位和存入的基本单位是一一对应的,当然也可以复数读取,但是由于tf后续有batch拼接的函数,所以意义不大
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
|
输出,
拼接batch尺寸为2,每次读取10个数据
可以看到,这里batch尺寸指定的实际上是读取次数
(2, 10, 784)
[[7 3 4 6 1 8 1 0 9 8]
[0 3 1 2 7 0 2 9 6 0]][[784 784 784 784 784 784 784 784 784 784]
[784 784 784 784 784 784 784 784 784 784]]
……
注意读取数目和解析数目选择的函数是要对应的,
1 2 3 4 5 6 7 8 9 10 11 12 |
|
值得注意的是这句,
1 |
|
虽然后续未必会调用(coord实际上还是会调用用于协调停止),但实际上控制着队列的数据读取部分的启动,注释掉后会导致队列有出无进进而挂起。
TFRecord文件批量生成
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
|
输出如下,
TFRecord文件读取测试
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
|
注意下面介绍,
1 2 3 |
|
batch生成的两个函数如下,
1 2 3 4 5 6 7 8 9 10 11 |
|
- 单一文件多线程,那么选用tf.train.batch(需要打乱样本,有对应的tf.train.shuffle_batch)
- 多线程多文件的情况,一般选用tf.train.batch_join来获取样本(打乱样本同样也有对应的tf.train.shuffle_batch_join使用)
batch和batch_join的说明
文件准备
1 2 3 4 5 6 7 |
|
单个Reader,单个样本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
|
单个Reader,多个样本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
|
多Reader,多个样本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
|
tf.train.batch
与tf.train.shuffle_batch'
数是单个Reader读取,但是可以多线程。tf.train.batch_join'
和tf.train.shuffle_batch_join
可设置多Reader读取,每个Reader使用一个线程。至于两种方法的效率,单Reader时,2个线程就达到了速度的极限。多Reader时,2个Reader就达到了极限。所以并不是线程越多越快,甚至更多的线程反而会使效率下降。
在这个例子中, 虽然只使用了一个文件名队列, 但是TensorFlow依然能保证多个文件阅读器从同一次迭代(epoch)的不同文件中读取数据,知道这次迭代的所有文件都被开始读取为止。(通常来说一个线程来对文件名队列进行填充的效率是足够的)
另一种替代方案是: 使用tf.train.shuffle_batch
函数,设置num_threads
的值大于1。 这种方案可以保证同一时刻只在一个文件中进行读取操作(但是读取速度依然优于单线程),而不是之前的同时读取多个文件。这种方案的优点是:
- 避免了两个不同的线程从同一个文件中读取同一个样本。
- 避免了过多的磁盘搜索操作。
简单来说,
单一文件多线程,那么选用tf.train.batch(需要打乱样本,有对应的tf.train.shuffle_batch)
多线程多文件的情况,一般选用tf.train.batch_join来获取样本(打乱样本同样也有tf.train.shuffle_batch_join)