直接采用矩阵方式建立数据集见:https://www.cnblogs.com/WSX1994/p/10128338.html

制作自己的数据集(使用tfrecords)

为什么采用这个格式?

TFRecords文件格式在图像识别中有很好的使用,其可以将二进制数据和标签数据(训练的类别标签)数据存储在同一个文件中,它可以在模型进行训练之前通过预处理步骤将图像转换为TFRecords格式,此格式最大的优点实践每幅输入图像和与之关联的标签放在同一个文件中.TFRecords文件是一种二进制文件,其不对数据进行压缩,所以可以被快速加载到内存中.格式不支持随机访问,因此它适合于大量的数据流,但不适用于快速分片或其他非连续存取。

前戏:

tf.train.Feature
tf.train.Feature有三个属性为tf.train.bytes_list    tf.train.float_list    tf.train.int64_list,显然我们只需要根据上一步得到的值来设置tf.train.Feature的属性就可以了,如下所示:

 tf.train.Feature(int64_list=data_id)
tf.train.Feature(bytes_list=data)

tf.train.Features
从名字来看,我们应该能猜出tf.train.Features是tf.train.Feature的复数,事实上tf.train.Features有属性为feature,这个属性的一般设置方法是传入一个字典,字典的key是字符串(feature名),而值是tf.train.Feature对象。因此,我们可以这样得到tf.train.Features对象:

 feature_dict = {
"data_id": tf.train.Feature(int64_list=data_id),
"data": tf.train.Feature(bytes_list=data)
}
features = tf.train.Features(feature=feature_dict)

tf.train.Example
终于到我们的主角了。tf.train.Example有一个属性为features,我们只需要将上一步得到的结果再次当做参数传进来即可。
另外,tf.train.Example还有一个方法SerializeToString()需要说一下,这个方法的作用是把tf.train.Example对象序列化为字符串,因为我们写入文件的时候不能直接处理对象,需要将其转化为字符串才能处理。
当然,既然有对象序列化为字符串的方法,那么肯定有从字符串反序列化到对象的方法,该方法是FromString(),需要传递一个tf.train.Example对象序列化后的字符串进去做为参数才能得到反序列化的对象。
在我们这里,只需要构建tf.train.Example对象并序列化就可以了,这一步的代码为:

 example = tf.train.Example(features=features)
example_str = example.SerializeToString()

实例(高潮部分):

首先看一下我们的文件夹路径:

create_tfrecords.py中写我们的函数

生成数据文件阶段代码如下:

 def creat_tf(imgpath):
cwd = os.getcwd() #获取当前路径
classes = os.listdir(cwd + imgpath) #获取到[1, 2]文件夹
# 此处定义tfrecords文件存放
writer = tf.python_io.TFRecordWriter("train.tfrecords")
for index, name in enumerate(classes): #循环获取俩文件夹(俩类别)
class_path = cwd + imgpath + name + "/"
if os.path.isdir(class_path):
for img_name in os.listdir(class_path):
img_path = class_path + img_name
img = Image.open(img_path)
img = img.resize((224, 224))
img_raw = img.tobytes()
example = tf.train.Example(features=tf.train.Features(feature={
'label': tf.train.Feature(int64_list=tf.train.Int64List(value=[int(name)])),
'img_raw': tf.train.Feature(bytes_list=tf.train.BytesList(value=[img_raw]))
}))
writer.write(example.SerializeToString())
print(img_name)
writer.close()

这段代码主要生成  train.tfrecords 文件。

读取数据阶段代码如下:

 def read_and_decode(filename):
# 根据文件名生成一个队列
filename_queue = tf.train.string_input_producer([filename]) 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 = tf.reshape(img, [224, 224, 3])
# 转换为float32类型,并做归一化处理
img = tf.cast(img, tf.float32) # * (1. / 255)
label = tf.cast(features['label'], tf.int64)
return img, label

训练阶段我们获取数据的代码:

 images, labels = read_and_decode('./train.tfrecords')
img_batch, label_batch = tf.train.shuffle_batch([images, labels],
batch_size=5,
capacity=392,
min_after_dequeue=200)
init = tf.global_variables_initializer()
with tf.Session() as sess:
sess.run(init)
coord = tf.train.Coordinator() #线程协调器
threads = tf.train.start_queue_runners(sess=sess,coord=coord)
# 训练部分代码--------------------------------
IMG, LAB = sess.run([img_batch, label_batch])
print(IMG.shape) #----------------------------------------------
coord.request_stop() # 协调器coord发出所有线程终止信号
coord.join(threads) #把开启的线程加入主线程,等待threads结束

总结(流程):

  1. 生成tfrecord文件
  2. 定义record reader解析tfrecord文件
  3. 构造一个批生成器(batcher
  4. 构建其他的操作
  5. 初始化所有的操作
  6. 启动QueueRunner

备注:关于tf.train.Coordinator 详见:

https://blog.csdn.net/dcrmg/article/details/79780331

TensorFlow的Session对象是支持多线程的,可以在同一个会话(Session)中创建多个线程,并行执行。在Session中的所有线程都必须能被同步终止,异常必须能被正确捕获并报告,会话终止的时候, 队列必须能被正确地关闭。

  1. 调用 tf.train.slice_input_producer,从 本地文件里抽取tensor,准备放入Filename Queue(文件名队列)中;
  2. 调用 tf.train.batch,从文件名队列中提取tensor,使用单个或多个线程,准备放入文件队列;
  3. 调用 tf.train.Coordinator() 来创建一个线程协调器,用来管理之后在Session中启动的所有线程;
  4. 调用tf.train.start_queue_runners, 启动入队线程,由多个或单个线程,按照设定规则,把文件读入Filename Queue中。函数返回线程ID的列表,一般情况下,系统有多少个核,就会启动多少个入队线程(入队具体使用多少个线程在tf.train.batch中定义);
  5. 文件从 Filename Queue中读入内存队列的操作不用手动执行,由tf自动完成;
  6. 调用sess.run 来启动数据出列和执行计算;
  7. 使用 coord.should_stop()来查询是否应该终止所有线程,当文件队列(queue)中的所有文件都已经读取出列的时候,会抛出一个 OutofRangeError 的异常,这时候就应该停止Sesson中的所有线程了;
  8. 使用coord.request_stop()来发出终止所有线程的命令,使用coord.join(threads)把线程加入主线程,等待threads结束。

tensorflow 使用tfrecords创建自己数据集的更多相关文章

  1. 在C#下使用TensorFlow.NET训练自己的数据集

    在C#下使用TensorFlow.NET训练自己的数据集 今天,我结合代码来详细介绍如何使用 SciSharp STACK 的 TensorFlow.NET 来训练CNN模型,该模型主要实现 图像的分 ...

  2. TensorFlow从0到1之TensorFlow逻辑回归处理MNIST数据集(17)

    本节基于回归学习对 MNIST 数据集进行处理,但将添加一些 TensorBoard 总结以便更好地理解 MNIST 数据集. MNIST由https://www.tensorflow.org/get ...

  3. Arcengine实现创建网络数据集札记(三)

    后记 下面给出项目中用到的自定义的封装类. AE许可初始化封装类: public class AELicenseChecker { private static volatile AELicenseC ...

  4. Arcengine实现创建网络数据集札记(二)

    四 ArcEngine实现创建网络数据集 ArcEngine创建网络数据集的过程,与ArcMap设置的过程类似,主要通过六个步骤即可以实现. 1 定义网络数据集对象,并设置基本属性,包括网络数据集名称 ...

  5. Arcengine实现创建网络数据集札记(一)

    一 引子 网络数据集,GIS空间分析基础的理论和知识,是最短路径分析.连通性分析等其他空间分析技术的数据基础. 以往,网络数据集的研究很少,此次项目开发过程中,对网络数据集以及arcengine创建网 ...

  6. ArcGIS 网络分析[2] 利用自定义基础数据创建网络数据集

    前言 似乎除了官方介绍的例子,我还没有在网上见过一篇介绍如何"使用自己的数据"创建"网络数据集"的文章. 有介绍几何网络的,有介绍如何用官方SanFrancis ...

  7. ArcGIS 网络分析[1.5] 使用点线数据一起创建网络数据集(如何避免孤立点/点与线的连通性组合结果表)

    ArcGIS中最基本的三种矢量数据是什么?点线面. 网络中除了路网之外,还会有地物点. 如上图,我们在建立网络数据集的时候,作为实验,当然可以只是公路网.但是在大型的决策任务中,网络数据集就不只是公路 ...

  8. ArcGIS 网络分析[8.3] 设置IDENetworkDataset的属性及INetworkDataset的对比/创建网络数据集

    创建网络数据集就得有各种数据和参数,这篇文章很长,慎入. 网络分析依赖于网络数据集的质量,这句话就在这里得到了验证:复杂.精确定义. 本节目录如下: 1. INetworkDataset与IDENet ...

  9. ArcGIS 网络分析[8.2] 资料2 使用IDatasetContainer2接口的CreateDataset方法创建网络数据集

    上节提及如何使用IDatasetContainer2接口访问到网络数据集,上例可以封装为一个方法. 这节就使用IDatasetContainer2接口(Geodatabase类库)的CreateDat ...

随机推荐

  1. JavaWeb_(Hibernate框架)Hibernate中事务

    Hibernate中事务 事务的性质 事物的隔离级别 配置事务的隔离级别 事务的性质 原子性:原子,不可再分,一个操作不能分为更小的操作,要么全都执行,要么全不执行. 一致性:事务在完成时,必须使得所 ...

  2. Django 详解

    Django是一个开源的Web应用框架,由Python写成.采用MVC的软件设计模式,主要目标是使得开发复杂的.数据库驱动的网站变得简单.Django注重组件的重用性和“可插拔性”,敏捷开发和DRY法 ...

  3. 使用vlc 或 ffmpeg发布RTP/UDP视频服务

    一.FFmpeg 测试环境Centos 发布端: ffmpeg -re -stream_loop -1 -i test.ts -vcodec copy -acodec copy -f rtp_mpeg ...

  4. 三、Reids(高性能)key-value服务器知识整合

    一.Redis 是完全开源免费的,遵守BSD协议,是一个高性能的key-value数据库. 知识链接:https://www.runoob.com/redis/redis-backup.html ht ...

  5. flask第三篇 request

    每个框架中都有处理请求的机制(request),但是每个框架的处理方式和机制是不同的 为了了解Flask的request中都有什么东西,首先我们要写一个前后端的交互 基于HTML + Flask 写一 ...

  6. (九)C语言之scanf

  7. 20175215 2018-2019-2 第十周java课程学习总结

    第十二章 Java多线程机制 12.1 进程与线程 12.1.1 操作系统与进程 程序是一段静态的代码,它是应用软件执行的蓝本. 进程是程序的一次动态执行过程,它对应了从代码加载.执行至执行完毕的一个 ...

  8. SRS之SrsRtmpConn::service_cycle详解

    1. SrsRtmpConn::service_cycle 当服务器在 conn 线程的开始调用 connect_app 函数接收并解析客户端发送的 connect 消息后,调用该 service_c ...

  9. EBI架构 VS. MVC

    和 MVC 模式中的 Model 代表着整个后端(包括所有实体.服务和它们之间的关系在内的一切)一样,EBI 模式将边界看作是和外部世界的完整连接,而不仅仅是一个视图.一个控制器或是一个接口(这里指的 ...

  10. Springboot获取resource的路径

    1.获取resource目录下的template路径 String path = Thread.currentThread().getContextClassLoader().getResource( ...