[TFRecord格式数据]利用TFRecords存储与读取带标签的图片
利用TFRecords存储与读取带标签的图片
觉得有用的话,欢迎一起讨论相互学习~




TFRecords其实是一种二进制文件,虽然它不如其他格式好理解,但是它能更好的利用内存,更方便复制和移动,并且不需要单独的标签文件
TFRecords文件包含了tf.train.Example 协议内存块(protocol buffer)(协议内存块包含了字段 Features)。我们可以写一段代码获取你的数据, 将数据填入到Example协议内存块(protocol buffer),将协议内存块序列化为一个字符串, 并且通过tf.python_io.TFRecordWriter 写入到TFRecords文件。
从TFRecords文件中读取数据, 可以使用tf.TFRecordReader的tf.parse_single_example解析器。这个操作可以将Example协议内存块(protocol buffer)解析为张量。
我们使用tf.train.Example来定义我们要填入的数据格式,然后使用tf.python_io.TFRecordWriter来写入。
基本的,一个Example中包含Features,Features里包含Feature(这里没s)的字典。最后,Feature里包含有一个 FloatList, 或者ByteList,或者Int64List
示例代码
# Reuse the image from earlier and give it a fake label
# 复用之前的图像,并赋予一个假标签
import tensorflow as tf
image_filename = "./images/chapter-05-object-recognition-and-classification/working-with-images/test-input-image.jpg"
# 获得文件名列表
filename_queue = tf.train.string_input_producer(tf.train.match_filenames_once(image_filename))
# 生成文件名队列
image_reader = tf.WholeFileReader()
_, image_file = image_reader.read(filename_queue)
# 通过阅读器返回一个键值对,其中value表示图像
image = tf.image.decode_jpeg(image_file)
# 通过tf.image.decode_jpeg解码函数对图片进行解码,得到图像.
sess = tf.Session()
init_op = tf.group(tf.global_variables_initializer(), tf.local_variables_initializer())
sess.run(init_op)
coord = tf.train.Coordinator()
threads = tf.train.start_queue_runners(coord=coord, sess=sess)
print('the image is:', sess.run(image))
filename_queue.close(cancel_pending_enqueues=True)
coord.request_stop()
coord.join(threads)
image_label = b'\x01'
# Assume the label data is in a one-hot representation (00000001)
# 假设标签数据位于一个独热的(one-hot)编码表示中,(00000001) 二进制8位'x01'
# Convert the tensor into bytes, notice that this will load the entire image file
# 将张量转换为字节型,注意这会加载整个图像文件。
image_loaded = sess.run(image)
image_bytes = image_loaded.tobytes() # 将张量转化为字节类型.
image_height, image_width, image_channels = image_loaded.shape
# Export TFRecord 导出TFRecord
writer = tf.python_io.TFRecordWriter("./output/training-image.tfrecord")
# Don't store the width, height or image channels in this Example file to save space but not required.
# 样本文件中不保存图像的宽度/高度和通道数,以便节省不要求分配的空间.
example = tf.train.Example(features=tf.train.Features(feature={
'label': tf.train.Feature(bytes_list=tf.train.BytesList(value=[image_label])),
'image': tf.train.Feature(bytes_list=tf.train.BytesList(value=[image_bytes]))
}))
# This will save the example to a text file tfrecord
writer.write(example.SerializeToString()) # 序列化为字符串
writer.close()
# image = example.features.feature['image_bytes'].bytes_list.value
# label = example.features.feature['image_label'].int64_list.value
# 这样的方式进行读取.
"""标签的格式被称为独热编码(one-hot encoding)这是一种用于多类分类的有标签数据的常见的表示方法.
Stanford Dogs 数据集之所以被视为多类分类数据,是因为狗会被分类为单一品种,而非多个品种的混合,
在现实世界中,当预测狗的品种是,多标签解决方案通常较为有效,因为他们能够同时匹配属于多个品种的狗"""
"""
这段代码中,图像被加载到内存中并被转换为字节数组
image_bytes = image_loaded.tobytes()
然后通过tf.train.Example函数将values和labels以value的方式加载到example中,
example = tf.train.Example(features=tf.train.Features(feature={
'label': tf.train.Feature(bytes_list=tf.train.BytesList(value=[image_label])),
'image': tf.train.Feature(bytes_list=tf.train.BytesList(value=[image_bytes]))
}))
example在写入保存到磁盘之前需要先通过SerializeToString()方法将其序列化为二进制字符串.
序列化是一种将内存对象转化为可安全传输到某种文件的格式.
上面序列化的样本现在被保存为一种可被加载的格式,并可被反序列化为这里的样本格式
由于图像被保存为TFRecord文件,可以被再次从TFRecord文件加载.这样比将图像及其标签分开加载会节省一些时间
"""
# Load TFRecord
# 加载TFRecord文件,获取文件名队列
tf_record_filename_queue = tf.train.string_input_producer(["./output/training-image.tfrecord"])
# Notice the different record reader, this one is designed to work with TFRecord files which may
# have more than one example in them.
# 注意这个不同的记录读取其,它的设计意图是能够使用可能会包含多个样本的TFRecord文件
tf_record_reader = tf.TFRecordReader()
_, tf_record_serialized = tf_record_reader.read(tf_record_filename_queue)
# 通过阅读器读取value值,并保存为tf_record_serialized
# The label and image are stored as bytes but could be stored as int64 or float64 values in a
# serialized tf.Example protobuf.
# 标签和图像都按字节存储,但也可按int64或float64类型存储于序列化的tf.Example protobuf文件中
tf_record_features = tf.parse_single_example( # 这是一个模板化的东西,大部分都是这么写的
tf_record_serialized,
features={
'label': tf.FixedLenFeature([], tf.string),
'image': tf.FixedLenFeature([], tf.string),
})
"""
class FixedLenFeature(collections.namedtuple(
"FixedLenFeature", ["shape", "dtype", "default_value"])):"""
"""Configuration for parsing a fixed-length input feature.
用于解析固定长度的输入特性的配置。
To treat sparse input as dense, provide a `default_value`; otherwise,
the parse functions will fail on any examples missing this feature.
把稀疏的输入看作是稠密的,提供一个默认值;否则,解析函数将缺少属性值的情况下报错。
Fields:
shape: Shape of input data.输入数据的形状
dtype: Data type of input.输入数据类型
default_value: Value to be used if an example is missing this feature. It
must be compatible with `dtype` and of the specified `shape`.
如果一个示例缺少属性值,那么将使用该默认值。它必须与dtype和指定的形状兼容。
"""
# 但是在实际使用的过程中这里的features的是根据原先的保存时的名字对应的,而数据类型可以自行选取.
# Using tf.uint8 because all of the channel information is between 0-255
# 使用tf.uint8类型,因为所有的通道信息都处于0~255的范围内
tf_record_image = tf.decode_raw(
tf_record_features['image'], tf.uint8)
# tf.decode_raw()函数将将字符串的字节重新解释为一个数字的向量。
# Reshape the image to look like the image saved, not required
# 调整图像的尺寸,使其与保存的图像类似,但这并不是必需的
tf_record_image = tf.reshape(
tf_record_image,
[image_height, image_width, image_channels])
# Use real values for the height, width and channels of the image because it's required
# 用是指表示图像的高度,宽度和通道,因为必须对输入的形状进行调整
# to reshape the input.
tf_record_label = tf.cast(tf_record_features['label'], tf.string)
sess.close()
sess = tf.InteractiveSession()
init_op = tf.group(tf.global_variables_initializer(), tf.local_variables_initializer())
sess.run(init_op)
coord = tf.train.Coordinator()
threads = tf.train.start_queue_runners(coord=coord, sess=sess)
print("equal the image before and now", sess.run(tf.equal(image, tf_record_image))) # 检查原始图像和加载后的图像是否一致
"""首先,按照与其他文件相同的方式加载该文件,主要区别在于该文件主要有TFRecordReaader对象读取.
tf.parse_single_example对TFRecord进行解析,然后图像按原始字节(tf.decode_raw)进行读取"""
print("The lable of the image:", sess.run(tf_record_label)) # 输出图像的标签
tf_record_filename_queue.close(cancel_pending_enqueues=True)
coord.request_stop()
coord.join(threads)
Notice
如果你想要复用这段代码,请将 image_filename, tf.python_io.TFRecordWriter, tf.train.string_input_producer 等处的文件保存参数修改成你自己的图片所在位置.
大图是这样的,运行请下载小图.

参考资料
面向机器智能的Tensorflow实践
[TFRecord格式数据]利用TFRecords存储与读取带标签的图片的更多相关文章
- java保存json格式数据,保存字符串和读取字符串
1.java保存json格式数据,保存字符串和读取字符串 import java.io.*; class RWJson { public void wiite(String s, String toS ...
- 更加清晰的TFRecord格式数据生成及读取
TFRecords 格式数据文件处理流程 TFRecords 文件包含了 tf.train.Example 协议缓冲区(protocol buffer),协议缓冲区包含了特征 Features.Ten ...
- tensorflow制作tfrecord格式数据
tf.Example msg tensorflow提供了一种统一的格式.tfrecord来存储图像数据.用的是自家的google protobuf.就是把图像数据序列化成自定义格式的二进制数据. To ...
- hive 压缩全解读(hive表存储格式以及外部表直接加载压缩格式数据);HADOOP存储数据压缩方案对比(LZO,gz,ORC)
数据做压缩和解压缩会增加CPU的开销,但可以最大程度的减少文件所需的磁盘空间和网络I/O的开销,所以最好对那些I/O密集型的作业使用数据压缩,cpu密集型,使用压缩反而会降低性能. 而hive中间结果 ...
- tensorflow学习笔记(10) mnist格式数据转换为TFrecords
本程序 (1)mnist的图片转换成TFrecords格式 (2) 读取TFrecords格式 # coding:utf-8 # 将MNIST输入数据转化为TFRecord的格式 # http://b ...
- (第二章第四部分)TensorFlow框架之TFRecords数据的存储与读取
系列博客链接: (第二章第一部分)TensorFlow框架之文件读取流程:https://www.cnblogs.com/kongweisi/p/11050302.html (第二章第二部分)Tens ...
- "笨方法"学习CNN图像识别(二)—— tfrecord格式高效读取数据
原文地址:https://finthon.com/learn-cnn-two-tfrecord-read-data/-- 全文阅读5分钟 -- 在本文中,你将学习到以下内容: 将图片数据制作成tfre ...
- 利用python进行数据分析之数据加载存储与文件格式
在开始学习之前,我们需要安装pandas模块.由于我安装的python的版本是2.7,故我们在https://pypi.python.org/pypi/pandas/0.16.2/#downloads ...
- python多种格式数据加载、处理与存储
多种格式数据加载.处理与存储 实际的场景中,我们会在不同的地方遇到各种不同的数据格式(比如大家熟悉的csv与txt,比如网页HTML格式,比如XML格式),我们来一起看看python如何和这些格式的数 ...
随机推荐
- ThinkPHP3.2中英文切换!
小伙伴们好久不见!!! 最近公司项目版本升级,小梦已经忙成了狗,无暇顾及文章,今天抽时间写一篇助助兴! 用Thinkphp这个国产框架已经2年多了,现在有一个小功能:网站中英文切换功能,当然这 ...
- RabbitMQ 学习开发笔记
基本概念 ConnectionFactory.Connection.Channel ConnectionFactory.Connection.Channel,这三个都是RabbitMQ对外提供的API ...
- Codeforces Round #410 (Div. 2)(A,字符串,水坑,B,暴力枚举,C,思维题,D,区间贪心)
A. Mike and palindrome time limit per test:2 seconds memory limit per test:256 megabytes input:stand ...
- [bzoj3953] [WF2013]Self-Assembly
将正方形视为连接字符间的边.比方说正方形上存在A+,B-,就从A-往B+连边,表示字符可以通过这个正方形进行变换. 如果能构成环的话就可以无穷大了...判环随便写个拓扑什么的... #include& ...
- Logger之Logger.getLogger(CLass)技巧代替system.out.print
---恢复内容开始--- 尊重原创:http://www.cnblogs.com/zxf330301/p/5876117.html 之前一直在使用System.out.println()来调试.但是用 ...
- Myeclipse2014 已有项目更换JDK
原先项目使用JDK是1.7,今天项目加入了一个新包,只支持JAVA8,让我们都升级一下本地的JDK,我突然发现我还没有在myeclipse上升级过JDK呢.捣鼓了一下,也不难,记录一下. 1.下载ja ...
- 小白的Python之路 day5 模块XML特点和用法
模块XML的特点和用法 一.简介 xml是实现不同语言或程序之间进行数据交换的协议,跟json差不多,但json使用起来更简单,不过,古时候,在json还没诞生的黑暗年代,大家只能选择用xml呀,至今 ...
- vueThink权限配置
vueThink中的 admin 默认是展示所有权限,其他的权限组用户就要自己去特定进行配置 http://vuedemo.cn:8181 这里我是默认本地配置了apache到 php\public ...
- 003_JS基础_面向对象基础
3.1 对象 引入:在js中表示一个人的信息(name, gender, age)通过var申明三个变量,但是这样使用基本数据类型的变量,他们是互相独立的,没有联系: 此时就需要使用对象,对象是 ...
- android 基础03 -- Intent
Android 中的 Intent 是将要执行的操作的一种抽象的描述,是一个用于Android 各个组件之间传递消息的对象. Intent 的基本用法 Intent 基本的使用方法主要有三种: 启动一 ...