关于TFRecord的制作已经有很多博客啦,本文就不再赘述了。
很多博客关于TFRecord只讲了如何制作和取出送入训练,但事实上在将数据送入训练前先验证一下是否制作正确这一点很必要,否则后面的训练可能都白搭。。。
本文重点讲一下当我们将图片制作成TFRecord后如何验证自己制作的是正确的。由于本人是新手,验证过程中出了一些错,这里也总结一下分享给大家。
这里我先放一段自己将图片制作TFRecord的代码,以便后面对照。
example = tf.train.Example(features=tf.train.Features(feature={
'label': tf.train.Feature(int64_list=tf.train.Int64List(value=[int(class_name)])),
'img_raw': tf.train.Feature(bytes_list=tf.train.BytesList(value=[img_raw]))
}))
接着我们取出,并将其reshape成224*224
filename_queue = tf.train.string_input_producer([path])
reader = tf.TFRecordReader()
_, serialized_example = reader.read(filename_queue) # 返回文件名和文件
features = tf.parse_single_example(serialized_example,
features={
'label': tf.FixedLenFeature([], tf.int64),
'img_raw': tf.FixedLenFeature([], tf.string),
})
img = tf.decode_raw(features['img_raw'], tf.uint8)
img_reshape = tf.reshape(img, [224, 224, 3])
label = tf.cast(features['label'], tf.int64)
如果我们想查看一下图片,可以在后面开启会话。查了半天资料“如何将数组打印成图片显示出来”。终于发现可以使用 Image.fromarray(array, ‘RGB’)函数,把一个数组转化成一个图像对象,这样后面就可以调用对象封装的方法image.show()查看图片了
with tf.Session() as sess:
coord = tf.train.Coordinator()
threads = tf.train.start_queue_runners(sess=sess, coord=coord)
image = Image.fromarray(img_reshape, 'RGB')
image.show()
coord.request_stop()
coord.join(threads)
但是报错:
发现是我忘记run一下img_reshape了,否则这里的img_reshape始终是一个tensor而非一个arrary类型,自然就没有arrary的内置属性方法
于是我这修改了一下,加了一个.eval():
image = Image.fromarray(img_reshape.eval(), 'RGB')
现在不会报错了,但是图像却显示不出来
这里我也还没找到是啥原因,大佬们帮我想想给我留言。查阅资料看到别人的写法TensorFlow 制作自己的TFRecord数据集 读取、显示及代码详解
然后就改成了这样:先run一下,返回的example就是array类型。
example, label = sess.run([img_reshape, label])
image = Image.fromarray(example, 'RGB')
image.show()
本以为可以欢欢喜喜,但是又报了一个错(小白的内心是绝望的……)
百度解决方法:接收返回值的变量要 label 换一个名字,不能与 sess.run() 中参数 fetches 接收的名字相同,后改为如下:
example, lb = sess.run([img_reshape, label])
image = Image.fromarray(example, 'RGB')
image.show()
现在就可了,弹出来图片,尺寸也的确是224*224:
这样一来,能确保自己制作的TFRecord是正确的,后面训练心里就有底了。
总结一下:
1.前面用filename_queue文件队列的话,一定要start_queue_runners开启线程!我刚开始就忘了,然后程序一直没有停下来但却一直没出结果。实际上就是没有子线程去读取文件,所以样本一直为空,而主线程拿不到样本,就一直在那耗着emm。我刚开始还以为是我电脑慢,还等了半天哈哈哈。
2.使用 img = Image.fromarray(array, ‘RGB’) 可以将数组转化成一个图像对象,便于进行图像的处理。同样,用 array = np.asarray(img) 可以将一个图片对象转化成数组,用于计算处理之类的。
3.要得到某个张量的值一定要去run它,否则它永远是一个张量……
我们可以run完之后用一个变量去接收张量的值,这样后面就可以直接用它处理。
事实证明,小白的路还有很远很远……
一些参考连接
TensorFlow 制作自己的TFRecord数据集 读取、显示及代码详解
图像处理之PIL.Image与numpy.array之间的相互转换 (Python-OpenCV)
numpy中np.array()与np.asarray的区别以及.tolist