官网的mnist和cifar10数据之后,笔者尝试着制作自己的数据集,并保存,读入,显示。 TensorFlow可以支持cifar10的数据格式, 也提供了标准的TFRecord 格式,而关于 tensorflow 读取数据, 官网提供了3中方法 
1 Feeding: 在tensorflow程序运行的每一步, 用Python代码在线提供数据 
2 Reader : 在一个计算图(tf.graph)的开始前,将文件读入到流(queue)中 
3 在声明tf.variable变量或numpy数组时保存数据。受限于内存大小,适用于数据较小的情况

在本文,主要介绍第二种方法,利用tf.record标准接口来读入文件

准备图片数据

笔者找了2类狗的图片, 哈士奇和吉娃娃, 全部 resize成128 * 128大小 
如下图, 保存地址为/home/molys/Python/data/dog 
 
每类中有10张图片 
 

现在利用这2 类 20张图片制作TFRecord文件

制作TFRECORD文件

1 先聊一下tfrecord, 这是一种将图像数据和标签放在一起的二进制文件,能更好的利用内存,在tensorflow中快速的复制,移动,读取,存储 等等..

这里注意,tfrecord会根据你选择输入文件的类,自动给每一类打上同样的标签 
如在本例中,只有0,1 两类

2 先上“制作TFRecord文件”的代码,注释附详解


import os
import tensorflow as tf
from PIL import Image #注意Image,后面会用到
import matplotlib.pyplot as plt
import numpy as np cwd='/home/molys/Python/data/'
classes={'husky','chihuahua'} #人为 设定 2 类
writer= tf.python_io.TFRecordWriter("dog_train.tfrecords") #要生成的文件 for index,name in enumerate(classes):
class_path=cwd+name+'/'
for img_name in os.listdir(class_path):
img_path=class_path+img_name #每一个图片的地址 img=Image.open(img_path)
img= img.resize((128,128))
img_raw=img.tobytes()#将图片转化为二进制格式
example = tf.train.Example(features=tf.train.Features(feature={
"label": tf.train.Feature(int64_list=tf.train.Int64List(value=[index])),
'img_raw': tf.train.Feature(bytes_list=tf.train.BytesList(value=[img_raw]))
})) #example对象对label和image数据进行封装
writer.write(example.SerializeToString()) #序列化为字符串 writer.close()

运行完这段代码后,会生成dog_train.tfrecords 文件,如下图 

tf.train.Example 协议内存块包含了Features字段,通过feature将图片的二进制数据和label进行统一封装, 然后将example协议内存块转化为字符串, tf.python_io.TFRecordWriter 写入到TFRecords文件中。

读取TFRECORD文件

在制作完tfrecord文件后, 将该文件读入到数据流中。 
代码如下


def read_and_decode(filename): # 读入dog_train.tfrecords
filename_queue = tf.train.string_input_producer([filename])#生成一个queue队列 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),
})#将image数据和label取出来 img = tf.decode_raw(features['img_raw'], tf.uint8)
img = tf.reshape(img, [128, 128, 3]) #reshape为128*128的3通道图片
img = tf.cast(img, tf.float32) * (1. / 255) - 0.5 #在流中抛出img张量
label = tf.cast(features['label'], tf.int32) #在流中抛出label张量
return img, label

注意,feature的属性“label”和“img_raw”名称要和制作时统一 ,返回的img数据和label数据一一对应。返回的img和label是2个 tf 张量,print出来 如下图 

显示tfrecord格式的图片

有些时候我们希望检查分类是否有误,或者在之后的网络训练过程中可以监视,输出图片,来观察分类等操作的结果,那么我们就可以session回话中,将tfrecord的图片从流中读取出来,再保存。 紧跟着一开始的代码写:


filename_queue = tf.train.string_input_producer(["dog_train.tfrecords"]) #读入流中
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),
}) #取出包含image和label的feature对象
image = tf.decode_raw(features['img_raw'], tf.uint8)
image = tf.reshape(image, [128, 128, 3])
label = tf.cast(features['label'], tf.int32)
with tf.Session() as sess: #开始一个会话
init_op = tf.initialize_all_variables()
sess.run(init_op)
coord=tf.train.Coordinator()
threads= tf.train.start_queue_runners(coord=coord)
for i in range(20):
example, l = sess.run([image,label])#在会话中取出image和label
img=Image.fromarray(example, 'RGB')#这里Image是之前提到的
img.save(cwd+str(i)+'_''Label_'+str(l)+'.jpg')#存下图片
print(example, l)
coord.request_stop()
coord.join(threads)

代码运行完后, 从tfrecord中取出的文件被保存了。如下图: 

在这里我们可以看到,图片文件名的第一个数字表示在流中的顺序(笔者这里没有用shuffle), 第二个数字则是 每个图片的label,吉娃娃都为0,哈士奇都为1。 由此可见,我们一开始制作tfrecord文件时,图片分类正确。

最新文章

  1. Java中Vector和ArrayList的区别
  2. Clock rate
  3. JAVA--网络编程(UDP)
  4. SQL Server - 把星期一(周一)当作每个星期的开始在一年中求取周数
  5. IDEA 编译时报错 “未结束的字符串文字” “解析时已经达到文件结尾”
  6. love your life
  7. 关于Android6.0之后的权限问题
  8. FLASH CC 2015 CANVAS 导出音频问题
  9. 关于bochs用X11启动的说明
  10. iOS创建界面方法的讨论
  11. (简单) POJ 2253 Frogger,Dijkstra。
  12. 第一次在gitHub上传项目到git.oschina的方法
  13. 再谈AbstractQueuedSynchronizer:独占模式
  14. 从GO内存模型与调用协议理解defer closure的坑
  15. Unity 点乘&叉乘 应用实例
  16. 坚持:学习Java后台的第一阶段,我学习了那些知识
  17. oracle-data-mining
  18. Hadoop 系列文章(一) Hadoop 的安装,以及 Standalone Operation 的启动模式测试
  19. nxlog 日志采集
  20. IntelliJ IDEA 编译代码报错 找不到符号 符号: 找不到符号包 包

热门文章

  1. bzoj3931【CQOI2015】网络吞吐量
  2. C++派生类中如何初始化基类对象(五段代码)
  3. 常用框架(一):spring+springMvc+mybatis+maven
  4. linux 在线实验
  5. 使用python进行re拆分网页内容
  6. 一个 passive 引发的bug
  7. guice基本使用,guice整合guice-servlet,web开发(五)
  8. VCRuntime静默安装
  9. week2 notebook2
  10. 找不到dll原因