TensorFlow高效读取数据的方法示例


Posted in Python onFebruary 06, 2018

概述

最新上传的mcnn中有完整的数据读写示例,可以参考。

关于Tensorflow读取数据,官网给出了三种方法:

  1. 供给数据(Feeding): 在TensorFlow程序运行的每一步, 让Python代码来供给数据。
  2. 从文件读取数据: 在TensorFlow图的起始, 让一个输入管线从文件中读取数据。
  3. 预加载数据: 在TensorFlow图中定义常量或变量来保存所有数据(仅适用于数据量比较小的情况)。

对于数据量较小而言,可能一般选择直接将数据加载进内存,然后再分batch输入网络进行训练(tip:使用这种方法时,结合yield 使用更为简洁,大家自己尝试一下吧,我就不赘述了)。但是,如果数据量较大,这样的方法就不适用了,因为太耗内存,所以这时最好使用tensorflow提供的队列queue,也就是第二种方法 从文件读取数据。对于一些特定的读取,比如csv文件格式,官网有相关的描述,在这儿我介绍一种比较通用,高效的读取方法(官网介绍的少),即使用tensorflow内定标准格式——TFRecords

太长不看,直接看源码请猛戳我的github,记得加星哦。

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)解析为张量。

接下来,让我们开始读取数据之旅吧~

生成TFRecords文件

我们使用tf.train.Example来定义我们要填入的数据格式,然后使用tf.python_io.TFRecordWriter来写入。

import os
import tensorflow as tf 
from PIL import Image

cwd = os.getcwd()

'''
此处我加载的数据目录如下:
0 -- img1.jpg
   img2.jpg
   img3.jpg
   ...
1 -- img1.jpg
   img2.jpg
   ...
2 -- ...
 这里的0, 1, 2...就是类别,也就是下文中的classes
 classes是我根据自己数据类型定义的一个列表,大家可以根据自己的数据情况灵活运用
...
'''
writer = tf.python_io.TFRecordWriter("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((224, 224))
    img_raw = img.tobytes()       #将图片转化为原生bytes
    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]))
    }))
    writer.write(example.SerializeToString()) #序列化为字符串
writer.close()

关于Example Feature的相关定义和详细内容,我推荐去官网查看相关API。

基本的,一个Example中包含Features,Features里包含Feature(这里没s)的字典。最后,Feature里包含有一个 FloatList, 或者ByteList,或者Int64List

就这样,我们把相关的信息都存到了一个文件中,所以前面才说不用单独的label文件。而且读取也很方便。

接下来是一个简单的读取小例子:

for serialized_example in tf.python_io.tf_record_iterator("train.tfrecords"):
  example = tf.train.Example()
  example.ParseFromString(serialized_example)

  image = example.features.feature['image'].bytes_list.value
  label = example.features.feature['label'].int64_list.value
  # 可以做一些预处理之类的
  print image, label

使用队列读取

一旦生成了TFRecords文件,为了高效地读取数据,TF中使用队列(queue)读取数据。

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])
  img = tf.cast(img, tf.float32) * (1. / 255) - 0.5
  label = tf.cast(features['label'], tf.int32)

  return img, label

之后我们可以在训练的时候这样使用

img, label = read_and_decode("train.tfrecords")

#使用shuffle_batch可以随机打乱输入
img_batch, label_batch = tf.train.shuffle_batch([img, label],
                        batch_size=30, capacity=2000,
                        min_after_dequeue=1000)
init = tf.initialize_all_variables()

with tf.Session() as sess:
  sess.run(init)
  threads = tf.train.start_queue_runners(sess=sess)
  for i in range(3):
    val, l= sess.run([img_batch, label_batch])
    #我们也可以根据需要对val, l进行处理
    #l = to_categorical(l, 12) 
    print(val.shape, l)

至此,tensorflow高效从文件读取数据差不多完结了。

恩?等等…什么叫差不多?对了,还有几个注意事项:

第一,tensorflow里的graph能够记住状态(state),这使得TFRecordReader能够记住tfrecord的位置,并且始终能返回下一个。而这就要求我们在使用之前,必须初始化整个graph,这里我们使用了函数tf.initialize_all_variables()来进行初始化。

第二,tensorflow中的队列和普通的队列差不多,不过它里面的operation和tensor都是符号型的(symbolic),在调用sess.run()时才执行。

第三, TFRecordReader会一直弹出队列中文件的名字,直到队列为空。

总结

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

例子代码请戳我的github,如果觉得对你有帮助的话可以加个星哦。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python简单实现基于SSL的IRC bot实例
Jun 15 Python
Python中的模块导入和读取键盘输入的方法
Oct 16 Python
python学习教程之Numpy和Pandas的使用
Sep 11 Python
Tensorflow 利用tf.contrib.learn建立输入函数的方法
Feb 08 Python
Python实现的个人所得税计算器示例
Jun 01 Python
详解python的sorted函数对字典按key排序和按value排序
Aug 10 Python
Python定义函数功能与用法实例详解
Apr 08 Python
pycharm 2019 最新激活方式(pycharm破解、激活)
Sep 22 Python
python模拟实现分发扑克牌
Apr 22 Python
Pymysql实现往表中插入数据过程解析
Jun 02 Python
python 如何区分return和yield
Sep 22 Python
python 日志模块logging的使用场景及示例
Jan 04 Python
django使用xlwt导出excel文件实例代码
Feb 06 #Python
Python使用装饰器进行django开发实例代码
Feb 06 #Python
Python yield与实现方法代码分析
Feb 06 #Python
Django中间件工作流程及写法实例代码
Feb 06 #Python
Django数据库表反向生成实例解析
Feb 06 #Python
Python使用functools实现注解同步方法
Feb 06 #Python
django中send_mail功能实现详解
Feb 06 #Python
You might like
MySql中正则表达式的使用方法描述
2008/07/30 PHP
PHP中文处理 中文字符串截取(mb_substr)和获取中文字符串字数
2011/11/10 PHP
解析phpstorm + xdebug 远程断点调试
2013/06/20 PHP
discuz目录文件资料汇总
2014/12/30 PHP
Jquery EasyUI的添加,修改,删除,查询等基本操作介绍
2013/10/11 Javascript
javascript 中that的含义示例介绍
2014/05/14 Javascript
jQuery中ajax的post()方法用法实例
2014/12/26 Javascript
纯javascript判断查询日期是否为有效日期
2015/08/24 Javascript
js实现图片放大和拖拽特效代码分享
2015/09/05 Javascript
jQuery使用$.ajax进行异步刷新的方法(附demo下载)
2015/12/04 Javascript
举例讲解jQuery中可见性过滤选择器的使用
2016/04/18 Javascript
JavaScript判断用户名和密码不能为空的实现代码
2016/05/16 Javascript
js 声明数组和向数组中添加对象变量的简单实例
2016/07/28 Javascript
D3.js实现雷达图的方法详解
2016/09/22 Javascript
Vue-cli 使用json server在本地模拟请求数据的示例代码
2017/11/02 Javascript
vue日历/日程提醒/html5本地缓存功能
2019/09/02 Javascript
基于jQuery实现可编辑的表格
2019/12/11 jQuery
JS实现表单中点击小眼睛显示隐藏密码框中的密码
2020/04/13 Javascript
[47:53]DOTA2上海特级锦标赛主赛事日 - 1 败者组第一轮#2COL VS Spirit
2016/03/02 DOTA
Python re模块介绍
2014/11/30 Python
python爬虫实战之最简单的网页爬虫教程
2017/08/13 Python
python中获得当前目录和上级目录的实现方法
2017/10/12 Python
PyQt5实现下载进度条效果
2018/04/19 Python
解决Django数据库makemigrations有变化但是migrate时未变动问题
2018/05/30 Python
Python Selenium 之关闭窗口close与quit的方法
2019/02/13 Python
python分布式计算dispy的使用详解
2019/12/22 Python
python中怎么表示空值
2020/06/19 Python
使用Django的JsonResponse返回数据的实现
2021/01/15 Python
eDreams澳大利亚:预订机票、酒店和度假产品
2017/04/19 全球购物
爱尔兰电脑、家电和家具购物网站:Buy It Direct
2019/07/09 全球购物
初中考试作弊检讨书
2014/02/01 职场文书
单位承诺书格式
2014/05/21 职场文书
专业技术人员年度考核评语
2014/12/31 职场文书
高一数学教学反思
2016/02/18 职场文书
干货:如何写好工作总结报告!
2019/05/10 职场文书
Sql-Server数据库单表查询 4.3实验课
2021/04/05 SQL Server