Tensorflow中批量读取数据的案列分析及TFRecord文件的打包与读取


Posted in Python onJune 30, 2020

单一数据读取方式:

第一种:slice_input_producer()

# 返回值可以直接通过 Session.run([images, labels])查看,且第一个参数必须放在列表中,如[...]
[images, labels] = tf.train.slice_input_producer([images, labels], num_epochs=None, shuffle=True)

第二种:string_input_producer()

# 需要定义文件读取器,然后通过读取器中的 read()方法来获取数据(返回值类型 key,value),再通过 Session.run(value)查看
file_queue = tf.train.string_input_producer(filename, num_epochs=None, shuffle=True)

reader = tf.WholeFileReader()      # 定义文件读取器
key, value = reader.read(file_queue)  # key:文件名;value:文件中的内容

!!!num_epochs=None,不指定迭代次数,这样文件队列中元素个数也不限定(None*数据集大小)。

!!!如果它不是None,则此函数创建本地计数器 epochs,需要使用local_variables_initializer()初始化局部变量

!!!以上两种方法都可以生成文件名队列。

(随机)批量数据读取方式:

batchsize=2# 每次读取的样本数量
tf.train.batch(tensors, batch_size=batchsize)
tf.train.shuffle_batch(tensors, batch_size=batchsize, capacity=batchsize*10, min_after_dequeue=batchsize*5) # capacity > min_after_dequeue

!!!以上所有读取数据的方法,在Session.run()之前必须开启文件队列线程 tf.train.start_queue_runners()

 TFRecord文件的打包与读取

 一、单一数据读取方式

第一种:slice_input_producer()

def slice_input_producer(tensor_list, num_epochs=None, shuffle=True, seed=None, capacity=32, shared_name=None, name=None)

案例1:

import tensorflow as tf

images = ['image1.jpg', 'image2.jpg', 'image3.jpg', 'image4.jpg']
labels = [1, 2, 3, 4]

# [images, labels] = tf.train.slice_input_producer([images, labels], num_epochs=None, shuffle=True)

# 当num_epochs=2时,此时文件队列中只有 2*4=8个样本,所有在取第9个样本时会出错
# [images, labels] = tf.train.slice_input_producer([images, labels], num_epochs=2, shuffle=True)

data = tf.train.slice_input_producer([images, labels], num_epochs=None, shuffle=True)
print(type(data))  # <class 'list'>

with tf.Session() as sess:
  # sess.run(tf.local_variables_initializer())
  sess.run(tf.local_variables_initializer())
  coord = tf.train.Coordinator() # 线程的协调器
  threads = tf.train.start_queue_runners(sess, coord) # 开始在图表中收集队列运行器

  for i in range(10):
    print(sess.run(data))

  coord.request_stop()
  coord.join(threads)

"""

运行结果:

[b'image2.jpg', 2]
[b'image1.jpg', 1]
[b'image3.jpg', 3]
[b'image4.jpg', 4]
[b'image2.jpg', 2]
[b'image1.jpg', 1]
[b'image3.jpg', 3]
[b'image4.jpg', 4]
[b'image2.jpg', 2]
[b'image3.jpg', 3]
"""

!!!slice_input_producer() 中的第一个参数需要放在一个列表中,列表中的每个元素可以是 List 或 Tensor,如 [images,labels],

!!!num_epochs设置

 第二种:string_input_producer()

def string_input_producer(string_tensor, num_epochs=None, shuffle=True, seed=None, capacity=32, shared_name=None, name=None, cancel_op=None)

文件读取器

不同类型的文件对应不同的文件读取器,我们称为 reader对象;

该对象的 read 方法自动读取文件,并创建数据队列,输出key/文件名,value/文件内容;

reader = tf.TextLineReader()   ### 一行一行读取,适用于所有文本文件

reader = tf.TFRecordReader()   ### A Reader that outputs the records from a TFRecords file

reader = tf.WholeFileReader()   ### 一次读取整个文件,适用图片

案例2:读取csv文件

import tensorflow as tf

filename = ['data/A.csv', 'data/B.csv', 'data/C.csv']

file_queue = tf.train.string_input_producer(filename, shuffle=True, num_epochs=2)  # 生成文件名队列
reader = tf.WholeFileReader()      # 定义文件读取器(一次读取整个文件)
# reader = tf.TextLineReader()      # 定义文件读取器(一行一行的读)
key, value = reader.read(file_queue)  # key:文件名;value:文件中的内容
print(type(file_queue))

init = [tf.global_variables_initializer(), tf.local_variables_initializer()]
with tf.Session() as sess:
  sess.run(init)
  coord = tf.train.Coordinator()
  threads = tf.train.start_queue_runners(sess=sess, coord=coord)
  try:
    while not coord.should_stop():
      for i in range(6):
        print(sess.run([key, value]))
      break
  except tf.errors.OutOfRangeError:
    print('read done')
  finally:
    coord.request_stop()
  coord.join(threads)

"""
reader = tf.WholeFileReader()      # 定义文件读取器(一次读取整个文件)
运行结果:
[b'data/C.csv', b'7.jpg,7\n8.jpg,8\n9.jpg,9\n']
[b'data/B.csv', b'4.jpg,4\n5.jpg,5\n6.jpg,6\n']
[b'data/A.csv', b'1.jpg,1\n2.jpg,2\n3.jpg,3\n']
[b'data/A.csv', b'1.jpg,1\n2.jpg,2\n3.jpg,3\n']
[b'data/B.csv', b'4.jpg,4\n5.jpg,5\n6.jpg,6\n']
[b'data/C.csv', b'7.jpg,7\n8.jpg,8\n9.jpg,9\n']
"""
"""
reader = tf.TextLineReader()      # 定义文件读取器(一行一行的读)
运行结果:
[b'data/B.csv:1', b'4.jpg,4']
[b'data/B.csv:2', b'5.jpg,5']
[b'data/B.csv:3', b'6.jpg,6']
[b'data/C.csv:1', b'7.jpg,7']
[b'data/C.csv:2', b'8.jpg,8']
[b'data/C.csv:3', b'9.jpg,9']
"""

案例3:读取图片(每次读取全部图片内容,不是一行一行)

import tensorflow as tf

filename = ['1.jpg', '2.jpg']
filename_queue = tf.train.string_input_producer(filename, shuffle=False, num_epochs=1)
reader = tf.WholeFileReader()       # 文件读取器
key, value = reader.read(filename_queue)  # 读取文件 key:文件名;value:图片数据,bytes

with tf.Session() as sess:
  tf.local_variables_initializer().run()
  coord = tf.train.Coordinator()   # 线程的协调器
  threads = tf.train.start_queue_runners(sess, coord)

  for i in range(filename.__len__()):
    image_data = sess.run(value)
    with open('img_%d.jpg' % i, 'wb') as f:
      f.write(image_data)
  coord.request_stop()
  coord.join(threads)

 二、(随机)批量数据读取方式:

功能:shuffle_batch() 和 batch() 这两个API都是从文件队列中批量获取数据,使用方式类似;

案例4:slice_input_producer() 与 batch()

import tensorflow as tf
import numpy as np

images = np.arange(20).reshape([10, 2])
label = np.asarray(range(0, 10))
images = tf.cast(images, tf.float32)# 可以注释掉,不影响运行结果
label = tf.cast(label, tf.int32)

 # 可以注释掉,不影响运行结果

batchsize = 6  # 每次获取元素的数量
input_queue = tf.train.slice_input_producer([images, label], num_epochs=None, shuffle=False)
image_batch, label_batch = tf.train.batch(input_queue, batch_size=batchsize)

# 随机获取 batchsize个元素,其中,capacity:队列容量,这个参数一定要比 min_after_dequeue 大
# image_batch, label_batch = tf.train.shuffle_batch(input_queue, batch_size=batchsize, capacity=64, min_after_dequeue=10)

with tf.Session() as sess:
  coord = tf.train.Coordinator()   # 线程的协调器
  threads = tf.train.start_queue_runners(sess, coord)   # 开始在图表中收集队列运行器
  for cnt in range(2):
    print("第{}次获取数据,每次batch={}...".format(cnt+1, batchsize))
    image_batch_v, label_batch_v = sess.run([image_batch, label_batch])
    print(image_batch_v, label_batch_v, label_batch_v.__len__())

  coord.request_stop()
  coord.join(threads)

"""

运行结果:
第1次获取数据,每次batch=6...
[[ 0.  1.]
 [ 2.  3.]
 [ 4.  5.]
 [ 6.  7.]
 [ 8.  9.]
 [10. 11.]] [0 1 2 3 4 5] 6
第2次获取数据,每次batch=6...
[[12. 13.]
 [14. 15.]
 [16. 17.]
 [18. 19.]
 [ 0.  1.]
 [ 2.  3.]] [6 7 8 9 0 1] 6
"""

 案例5:从本地批量的读取图片 --- string_input_producer() 与 batch()

import tensorflow as tf
 import glob
 import cv2 as cv
 
 def read_imgs(filename, picture_format, input_image_shape, batch_size=):
   """
   从本地批量的读取图片
   :param filename: 图片路径(包括图片的文件名),[]
   :param picture_format: 图片的格式,如 bmp,jpg,png等; string
   :param input_image_shape: 输入图像的大小; (h,w,c)或[]
   :param batch_size: 每次从文件队列中加载图片的数量; int
   :return: batch_size张图片数据, Tensor
   """
   global new_img
   # 创建文件队列
   file_queue = tf.train.string_input_producer(filename, num_epochs=1, shuffle=True)
   # 创建文件读取器
   reader = tf.WholeFileReader()
   # 读取文件队列中的文件
   _, img_bytes = reader.read(file_queue)
   # print(img_bytes)  # Tensor("ReaderReadV2_19:1", shape=(), dtype=string)
   # 对图片进行解码
   if picture_format == ".bmp":
     new_img = tf.image.decode_bmp(img_bytes, channels=1)
   elif picture_format == ".jpg":
     new_img = tf.image.decode_jpeg(img_bytes, channels=3)
   else:
     pass
   # 重新设置图片的大小
   # new_img = tf.image.resize_images(new_img, input_image_shape)
   new_img = tf.reshape(new_img, input_image_shape)
   # 设置图片的数据类型
   new_img = tf.image.convert_image_dtype(new_img, tf.uint)
 
   # return new_img
   return tf.train.batch([new_img], batch_size)
 
 
 def main():
   image_path = glob.glob(r'F:\demo\FaceRecognition\人脸库\ORL\*.bmp')
   image_batch = read_imgs(image_path, ".bmp", (112, 92, 1), 5)
   print(type(image_batch))
   # image_path = glob.glob(r'.\*.jpg')
   # image_batch = read_imgs(image_path, ".jpg", (313, 500, 3), 1)
 
   sess = tf.Session()
   sess.run(tf.local_variables_initializer())
   tf.train.start_queue_runners(sess=sess)
 
   image_batch = sess.run(image_batch)
   print(type(image_batch))  # <class 'numpy.ndarray'>
 
   for i in range(image_batch.__len__()):
     cv.imshow("win_"+str(i), image_batch[i])
   cv.waitKey()
   cv.destroyAllWindows()
 
 def start():
   image_path = glob.glob(r'F:\demo\FaceRecognition\人脸库\ORL\*.bmp')
   image_batch = read_imgs(image_path, ".bmp", (112, 92, 1), 5)
   print(type(image_batch))  # <class 'tensorflow.python.framework.ops.Tensor'>
 
 
   with tf.Session() as sess:
     sess.run(tf.local_variables_initializer())
     coord = tf.train.Coordinator()   # 线程的协调器
     threads = tf.train.start_queue_runners(sess, coord)   # 开始在图表中收集队列运行器
     image_batch = sess.run(image_batch)
     print(type(image_batch))  # <class 'numpy.ndarray'>
 
     for i in range(image_batch.__len__()):
       cv.imshow("win_"+str(i), image_batch[i])
     cv.waitKey()
     cv.destroyAllWindows()
 
     # 若使用 with 方式打开 Session,且没加如下行语句,则会出错
     # ERROR:tensorflow:Exception in QueueRunner: Enqueue operation was cancelled;
     # 原因:文件队列线程还处于工作状态(队列中还有图片数据),而加载完batch_size张图片会话就会自动关闭,同时关闭文件队列线程
     coord.request_stop()
     coord.join(threads)
 
 
 if __name__ == "__main__":
   # main()
   start()

案列6:TFRecord文件打包与读取

 TFRecord文件打包案列

def write_TFRecord(filename, data, labels, is_shuffler=True):
   """
   将数据打包成TFRecord格式
   :param filename: 打包后路径名,默认在工程目录下创建该文件;String
   :param data: 需要打包的文件路径名;list
   :param labels: 对应文件的标签;list
   :param is_shuffler:是否随机初始化打包后的数据,默认:True;Bool
   :return: None
   """
   im_data = list(data)
   im_labels = list(labels)
 
   index = [i for i in range(im_data.__len__())]
   if is_shuffler:
     np.random.shuffle(index)
 
   # 创建写入器,然后使用该对象写入样本example
   writer = tf.python_io.TFRecordWriter(filename)
   for i in range(im_data.__len__()):
     im_d = im_data[index[i]]  # im_d:存放着第index[i]张图片的路径信息
     im_l = im_labels[index[i]] # im_l:存放着对应图片的标签信息
 
     # # 获取当前的图片数据 方式一:
     # data = cv2.imread(im_d)
     # # 创建样本
     # ex = tf.train.Example(
     #   features=tf.train.Features(
     #     feature={
     #       "image": tf.train.Feature(
     #         bytes_list=tf.train.BytesList(
     #           value=[data.tobytes()])), # 需要打包成bytes类型
     #       "label": tf.train.Feature(
     #         int64_list=tf.train.Int64List(
     #           value=[im_l])),
     #     }
     #   )
     # )
     # 获取当前的图片数据 方式二:相对于方式一,打包文件占用空间小了一半多
     data = tf.gfile.FastGFile(im_d, "rb").read()
     ex = tf.train.Example(
       features=tf.train.Features(
         feature={
           "image": tf.train.Feature(
             bytes_list=tf.train.BytesList(
               value=[data])), # 此时的data已经是bytes类型
           "label": tf.train.Feature(
             int_list=tf.train.IntList(
               value=[im_l])),
         }
       )
     )
 
     # 写入将序列化之后的样本
     writer.write(ex.SerializeToString())
   # 关闭写入器
   writer.close()

TFReord文件的读取案列

import tensorflow as tf
 import cv2
 
 def read_TFRecord(file_list, batch_size=):
   """
   读取TFRecord文件
   :param file_list: 存放TFRecord的文件名,List
   :param batch_size: 每次读取图片的数量
   :return: 解析后图片及对应的标签
   """
   file_queue = tf.train.string_input_producer(file_list, num_epochs=None, shuffle=True)
   reader = tf.TFRecordReader()
   _, ex = reader.read(file_queue)
   batch = tf.train.shuffle_batch([ex], batch_size, capacity=batch_size * 10, min_after_dequeue=batch_size * 5)
 
   feature = {
     'image': tf.FixedLenFeature([], tf.string),
     'label': tf.FixedLenFeature([], tf.int64)
   }
   example = tf.parse_example(batch, features=feature)
 
   images = tf.decode_raw(example['image'], tf.uint)
   images = tf.reshape(images, [-1, 32, 32, 3])
 
   return images, example['label']
 
 
 
 def main():
   # filelist = ['data/train.tfrecord']
   filelist = ['data/test.tfrecord']
   images, labels = read_TFRecord(filelist, 2)
   with tf.Session() as sess:
     sess.run(tf.local_variables_initializer())
     coord = tf.train.Coordinator()
     threads = tf.train.start_queue_runners(sess=sess, coord=coord)
 
     try:
       while not coord.should_stop():
         for i in range():
           image_bth, _ = sess.run([images, labels])
           print(_)
 
           cv2.imshow("image_0", image_bth[0])
           cv2.imshow("image_1", image_bth[1])
         break
     except tf.errors.OutOfRangeError:
       print('read done')
     finally:
       coord.request_stop()
     coord.join(threads)
     cv2.waitKey(0)
     cv2.destroyAllWindows()
 
 if __name__ == "__main__":
   main()

到此这篇关于Tensorflow中批量读取数据的案列分析及TFRecord文件的打包与读取的文章就介绍到这了,更多相关Tensorflow TFRecord打包与读取内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
Python 中的with关键字使用详解
Sep 11 Python
python fabric实现远程部署
Jan 05 Python
Python执行时间的计算方法小结
Mar 17 Python
Python 类的继承实例详解
Mar 25 Python
python使用正则表达式替换匹配成功的组并输出替换的次数
Nov 22 Python
python 中的列表生成式、生成器表达式、模块导入
Jun 19 Python
PyQt5创建一个新窗口的实例
Jun 20 Python
Python爬虫图片懒加载技术 selenium和PhantomJS解析
Sep 18 Python
Django 博客实现简单的全文搜索的示例代码
Feb 17 Python
关于PyCharm安装后修改路径名称使其可重新打开的问题
Oct 20 Python
Python类class参数self原理解析
Nov 19 Python
Python实现Telnet自动连接检测密码的示例
Apr 16 Python
使用Tensorflow-GPU禁用GPU设置(CPU与GPU速度对比)
Jun 30 #Python
keras的backend 设置 tensorflow,theano操作
Jun 30 #Python
浅谈TensorFlow中读取图像数据的三种方式
Jun 30 #Python
python中 _、__、__xx__()区别及使用场景
Jun 30 #Python
Django实现内容缓存实例方法
Jun 30 #Python
Pytorch 卷积中的 Input Shape用法
Jun 29 #Python
Python闭包装饰器使用方法汇总
Jun 29 #Python
You might like
PHP中的日期及时间
2006/11/23 PHP
用php实现像JSP,ASP里Application那样的全局变量
2007/01/12 PHP
浅析PHP递归函数返回值使用方法
2013/02/18 PHP
PHP基于新浪IP库获取IP详细地址的方法
2017/05/04 PHP
php进行md5加密简单实例方法
2019/09/19 PHP
最新28个很棒的jQuery 教程
2011/05/28 Javascript
JS命名空间的另一种实现
2013/08/09 Javascript
js中settimeout方法加参数的使用实例
2014/02/27 Javascript
[将免费进行到底]在Amazon的一年免费服务器上安装Node.JS, NPM和OurJS博客
2014/08/18 Javascript
jquery插件EasyUI中form表单提交实例分享
2016/01/11 Javascript
js基础之DOM中document对象的常用属性方法详解
2016/10/28 Javascript
几种tab切换详解
2017/02/03 Javascript
js学习总结_基于数据类型检测的四种方式(必看)
2017/07/04 Javascript
JavaScript输出所选择起始与结束日期的方法
2017/07/12 Javascript
jquery实现左右轮播图效果
2017/09/28 jQuery
详解如何为你的angular app构建一个第三方库
2018/12/07 Javascript
浅谈Node框架接入ELK实践总结
2019/02/22 Javascript
React传值 组件传值 之间的关系详解
2019/08/26 Javascript
JavaScript实现英语单词题库
2019/12/24 Javascript
vue路由缓存的几种实现方式小结
2020/02/02 Javascript
[59:00]DOTA2-DPC中国联赛 正赛 Ehome vs PSG.LGD BO3 第一场 3月7日
2021/03/11 DOTA
基于python实现微信模板消息
2015/12/21 Python
Python基础学习之常见的内建函数整理
2017/09/06 Python
Python3 利用requests 库进行post携带账号密码请求数据的方法
2018/10/26 Python
Python简单I/O操作示例
2019/03/18 Python
pytorch 实现tensor与numpy数组转换
2019/12/27 Python
浅谈Python中threading join和setDaemon用法及区别说明
2020/05/02 Python
python中os包的用法
2020/06/01 Python
python不同版本的_new_不同点总结
2020/12/09 Python
h5实现获取用户地理定位的实例代码
2017/07/17 HTML / CSS
英国快时尚女装购物网站:PrettyLittleThing
2018/08/15 全球购物
德国足球商店:OUTFITTER
2019/05/06 全球购物
安踏官方商城:anta.cn
2019/12/16 全球购物
zooplus德国:便宜地订购动物用品、动物饲料、动物食品
2020/05/06 全球购物
《最佳路径》教学反思
2014/04/13 职场文书
Li list-style-image 图片垂直居中实现方法
2023/05/21 HTML / CSS