侯体宗的博客
  • 首页
  • Hyperf版
  • beego仿版
  • 人生(杂谈)
  • 技术
  • 关于我
  • 更多分类
    • 文件下载
    • 文字修仙
    • 中国象棋ai
    • 群聊
    • 九宫格抽奖
    • 拼图
    • 消消乐
    • 相册

TFRecord格式存储数据与队列读取实例

技术  /  管理员 发布于 7年前   234

Tensor Flow官方网站上提供三种读取数据的方法

1. 预加载数据:在Tensor Flow图中定义常量或变量来保存所有数据,将数据直接嵌到数据图中,当训练数据较大时,很消耗内存。

如

x1=tf.constant([0,1])x2=tf.constant([1,0])y=tf.add(x1,x2)

2.填充数据:使用sess.run()的feed_dict参数,将Python产生的数据填充到后端,之前的MNIST数据集就是通过这种方法。也有消耗内存,数据类型转换耗时的缺点。

3. 从文件读取数据:从文件中直接读取,让队列管理器从文件中读取数据。分为两步

先把样本数据写入TFRecords二进制文件

再从队列中读取

TFRecord是TensorFlow提供的一种统一存储数据的二进制文件,能更好的利用内存,更方便的复制和移动,并且不需要单独的标记文件。下面通过代码来将MNIST转换成TFRecord的数据格式,其他数据集也类似。

#生成整数型的属性def _int64_feature(value): return tf.train.Feature(int64_list=tf.train.Int64List(value=[value]))#生成字符串型的属性def _bytes_feature(value): return tf.train.Feature(bytes_list=tf.train.BytesList(value=[value]))def convert_to(data_set,name): ''' 将数据填入到tf.train.Example的协议缓冲区(protocol buffer)中,将协议缓冲区序列 化为一个字符串,通过tf.python_io.TFRecordWriter写入TFRecords文件  ''' images=data_set.images labels=data_set.labels num_examples=data_set.num_examples if images.shape[0]!=num_examples:  raise ValueError ('Imagessize %d does not match label size %d.'\       %(images.shape[0],num_examples)) rows=images.shape[1] #28 cols=images.shape[2] #28 depth=images.shape[3] #1 是黑白图像 filename = os.path.join(FLAGS.directory, name + '.tfrecords') #使用下面语句就会将三个文件存储为一个TFRecord文件,当数据量较大时,最好将数据写入多个文件 #filename="C:/Users/dbsdz/Desktop/TF练习/TFRecord" print('Writing',filename) writer=tf.python_io.TFRecordWriter(filename) for index in range(num_examples):  image_raw=images[index].tostring() #将图像矩阵化为一个字符串  #写入协议缓冲区,height、width、depth、label编码成int 64类型,image――raw编码成二进制  example=tf.train.Example(features=tf.train.Features(feature={    'height':_int64_feature(rows),    'width':_int64_feature(cols),    'depth':_int64_feature(depth),    'label':_int64_feature(int(labels[index])),    'image_raw':_bytes_feature(image_raw)}))  writer.write(example.SerializeToString())  #序列化字符串 writer.close()

上面程序可以将MNIST数据集中所有的训练数据存储到三个TFRecord文件中。结果如下图

从队列中TFRecord文件,过程分三步

1. 创建张量,从二进制文件中读取一个样本

2. 创建张量,从二进制文件中随机读取一个mini-batch

3. 把每一批张量传入网络作为输入节点

具体代码如下

def read_and_decode(filename_queue):  #输入文件名队列 reader=tf.TFRecordReader() _,serialized_example=reader.read(filename_queue) #解析一个example,如果需要解析多个样例,使用parse_example函数 features=tf.parse_single_example(    serialized_example,   #必须写明feature里面的key的名称   features={   #TensorFlow提供两种不同的属性解析方法,一种方法是tf.FixedLenFeature,     #这种方法解析的结果为一个Tensor。另一个方法是tf.VarLenFeature,   #这种方法得到的解析结果为SparseTensor,用于处理稀疏数据。   #这里解析数据的格式需要和上面程序写入数据的格式一致     'image_raw':tf.FixedLenFeature([],tf.string),#图片是string类型      'label':tf.FixedLenFeature([],tf.int64), #标记是int64类型      }) #对于BytesList,要重新进行编码,把string类型的0维Tensor变成uint8类型的一维Tensor image = tf.decode_raw(features['image_raw'], tf.uint8) image.set_shape([IMAGE_PIXELS]) #tensor("input/DecodeRaw:0",shape=(784,),dtype=uint8) #image张量的形状为:tensor("input/sub:0",shape=(784,),dtype=float32) image = tf.cast(image, tf.float32) * (1. / 255) - 0.5 #把标记从uint8类型转换为int32类性 #label张量的形状为tensor(“input/cast_1:0",shape=(),dtype=int32) label = tf.cast(features['label'], tf.int32) return image,labeldef inputs(train,batch_size,num_epochs): #输入参数: #train:选择输入训练数据/验证数据 #batch_size:训练的每一批有多少个样本 #num_epochs:过几遍数据,设置为0/None表示永远训练下去 ''' 返回结果: A tuple (images,labels) *images:类型为float,形状为【batch_size,mnist.IMAGE_PIXELS],范围【-0.5,0.5】。 *label:类型为int32,形状为【batch_size],范围【0,mnist.NUM_CLASSES] 注意tf.train.QueueRunner必须用tf.train.start_queue_runners()来启动线程 ''' if not num_epochs:num_epochs=None #获取文件路径,即./MNIST_data/train.tfrecords,./MNIST_data/validation.records filename=os.path.join(FLAGS.train_dir,TRAIN_FILE if train else VALIDATION_FILE) with tf.name_scope('input'):  #tf.train.string_input_producer返回一个QueueRunner,里面有一个FIFOQueue  filename_queue=tf.train.string_input_producer(#如果样本量很大,可以分成若干文件,把文件名列表传入    [filename],num_epochs=num_epochs)    image,label=read_and_decode(filename_queue)  #随机化example,并把它们整合成batch_size大小  #tf.train.shuffle_batch生成了RandomShuffleQueue,并开启两个线程  images,sparse_labels=tf.train.shuffle_batch(    [image,label],batch_size=batch_size,num_threads=2,    capacity=1000+3*batch_size,    min_after_dequeue=1000) #留下一部分队列,来保证每次有足够的数据做随机打乱  return images,sparse_labels

最后,构建一个三层的神经网络,包含两层卷积层以及一层使用SoftMax层,附上完整代码如下

# -*- coding: utf-8 -*-"""Created on Sun Apr 8 11:06:16 2018@author: dbsdzhttps://blog.csdn.net/xy2953396112/article/details/54929073"""import tensorflow as tfimport osimport timeimport mathfrom tensorflow.examples.tutorials.mnist import input_datamnist = input_data.read_data_sets("MNIST_data/", one_hot=True)# Basic model parameters as external flags. flags = tf.app.flags flags.DEFINE_float('learning_rate', 0.01, 'Initial learning rate.') flags.DEFINE_integer('hidden1', 128, 'Number of units in hidden layer 1.') flags.DEFINE_integer('hidden2', 32, 'Number of units in hidden layer 2.') flags.DEFINE_integer('batch_size', 100, 'Batch size. '       'Must divide evenly into the dataset sizes.') flags.DEFINE_string('train_dir', 'Mnist_data/', 'Directory to put the training data.') flags.DEFINE_string('directory', './MNIST_data',       'Directory to download data files and write the '       'converted result')flags.DEFINE_integer('validation_size', 5000,       'Number of examples to separate from the training '       'data for the validation set.')flags.DEFINE_integer('num_epochs',10,'num_epochs set')FLAGS = tf.app.flags.FLAGSIMAGE_SIZE = 28IMAGE_PIXELS = IMAGE_SIZE * IMAGE_SIZE  #图片像素728TRAIN_FILE = "train.tfrecords"VALIDATION_FILE="validation.tfrecords"#生成整数型的属性def _int64_feature(value): return tf.train.Feature(int64_list=tf.train.Int64List(value=[value]))#生成字符串型的属性def _bytes_feature(value): return tf.train.Feature(bytes_list=tf.train.BytesList(value=[value]))def convert_to(data_set,name): ''' 将数据填入到tf.train.Example的协议缓冲区(protocol buffer)中,将协议缓冲区序列 化为一个字符串,通过tf.python_io.TFRecordWriter写入TFRecords文件  ''' images=data_set.images labels=data_set.labels num_examples=data_set.num_examples if images.shape[0]!=num_examples:  raise ValueError ('Imagessize %d does not match label size %d.'\       %(images.shape[0],num_examples)) rows=images.shape[1] #28 cols=images.shape[2] #28 depth=images.shape[3] #1 是黑白图像 filename = os.path.join(FLAGS.directory, name + '.tfrecords') #使用下面语句就会将三个文件存储为一个TFRecord文件,当数据量较大时,最好将数据写入多个文件 #filename="C:/Users/dbsdz/Desktop/TF练习/TFRecord" print('Writing',filename) writer=tf.python_io.TFRecordWriter(filename) for index in range(num_examples):  image_raw=images[index].tostring() #将图像矩阵化为一个字符串  #写入协议缓冲区,height、width、depth、label编码成int 64类型,image――raw编码成二进制  example=tf.train.Example(features=tf.train.Features(feature={    'height':_int64_feature(rows),    'width':_int64_feature(cols),    'depth':_int64_feature(depth),    'label':_int64_feature(int(labels[index])),    'image_raw':_bytes_feature(image_raw)}))  writer.write(example.SerializeToString())  #序列化字符串 writer.close()def inference(images, hidden1_units, hidden2_units): with tf.name_scope('hidden1'): weights = tf.Variable(  tf.truncated_normal([IMAGE_PIXELS, hidden1_units],       stddev=1.0 / math.sqrt(float(IMAGE_PIXELS))),name='weights') biases = tf.Variable(tf.zeros([hidden1_units]),name='biases') hidden1 = tf.nn.relu(tf.matmul(images, weights) + biases) with tf.name_scope('hidden2'): weights = tf.Variable(  tf.truncated_normal([hidden1_units, hidden2_units],       stddev=1.0 / math.sqrt(float(hidden1_units))),  name='weights') biases = tf.Variable(tf.zeros([hidden2_units]),       name='biases') hidden2 = tf.nn.relu(tf.matmul(hidden1, weights) + biases) with tf.name_scope('softmax_linear'): weights = tf.Variable(  tf.truncated_normal([hidden2_units,FLAGS.num_epochs],       stddev=1.0 / math.sqrt(float(hidden2_units))),name='weights') biases = tf.Variable(tf.zeros([FLAGS.num_epochs]),name='biases') logits = tf.matmul(hidden2, weights) + biases return logitsdef lossFunction(logits, labels): labels = tf.to_int64(labels) cross_entropy = tf.nn.sparse_softmax_cross_entropy_with_logits(  logits=logits, labels=labels, name='xentropy') loss = tf.reduce_mean(cross_entropy, name='xentropy_mean') return lossdef training(loss, learning_rate): tf.summary.scalar(loss.op.name, loss) optimizer = tf.train.GradientDescentOptimizer(learning_rate) global_step = tf.Variable(0, name='global_step', trainable=False) train_op = optimizer.minimize(loss, global_step=global_step) return train_opdef read_and_decode(filename_queue):  #输入文件名队列 reader=tf.TFRecordReader() _,serialized_example=reader.read(filename_queue) #解析一个example,如果需要解析多个样例,使用parse_example函数 features=tf.parse_single_example(    serialized_example,   #必须写明feature里面的key的名称   features={   #TensorFlow提供两种不同的属性解析方法,一种方法是tf.FixedLenFeature,     #这种方法解析的结果为一个Tensor。另一个方法是tf.VarLenFeature,   #这种方法得到的解析结果为SparseTensor,用于处理稀疏数据。   #这里解析数据的格式需要和上面程序写入数据的格式一致     'image_raw':tf.FixedLenFeature([],tf.string),#图片是string类型      'label':tf.FixedLenFeature([],tf.int64), #标记是int64类型      }) #对于BytesList,要重新进行编码,把string类型的0维Tensor变成uint8类型的一维Tensor image = tf.decode_raw(features['image_raw'], tf.uint8) image.set_shape([IMAGE_PIXELS]) #tensor("input/DecodeRaw:0",shape=(784,),dtype=uint8) #image张量的形状为:tensor("input/sub:0",shape=(784,),dtype=float32) image = tf.cast(image, tf.float32) * (1. / 255) - 0.5 #把标记从uint8类型转换为int32类性 #label张量的形状为tensor(“input/cast_1:0",shape=(),dtype=int32) label = tf.cast(features['label'], tf.int32) return image,labeldef inputs(train,batch_size,num_epochs): #输入参数: #train:选择输入训练数据/验证数据 #batch_size:训练的每一批有多少个样本 #num_epochs:过几遍数据,设置为0/None表示永远训练下去 ''' 返回结果: A tuple (images,labels) *images:类型为float,形状为【batch_size,mnist.IMAGE_PIXELS],范围【-0.5,0.5】。 *label:类型为int32,形状为【batch_size],范围【0,mnist.NUM_CLASSES] 注意tf.train.QueueRunner必须用tf.train.start_queue_runners()来启动线程 ''' if not num_epochs:num_epochs=None #获取文件路径,即./MNIST_data/train.tfrecords,./MNIST_data/validation.records filename=os.path.join(FLAGS.train_dir,TRAIN_FILE if train else VALIDATION_FILE) with tf.name_scope('input'):  #tf.train.string_input_producer返回一个QueueRunner,里面有一个FIFOQueue  filename_queue=tf.train.string_input_producer(#如果样本量很大,可以分成若干文件,把文件名列表传入    [filename],num_epochs=num_epochs)    image,label=read_and_decode(filename_queue)  #随机化example,并把它们整合成batch_size大小  #tf.train.shuffle_batch生成了RandomShuffleQueue,并开启两个线程  images,sparse_labels=tf.train.shuffle_batch(    [image,label],batch_size=batch_size,num_threads=2,    capacity=1000+3*batch_size,    min_after_dequeue=1000) #留下一部分队列,来保证每次有足够的数据做随机打乱  return images,sparse_labelsdef run_training(): with tf.Graph().as_default():  #输入images和labels  images,labels=inputs(train=True,batch_size=FLAGS.batch_size,        num_epochs=3)  #num_epochs就是训练的轮数   #构建一个从推理模型来预测数据的图  logits=inference(images,FLAGS.hidden1,FLAGS.hidden2)  loss=lossFunction(logits,labels) #定义损失函数  #Add to the Graph operations that train the model  train_op=training(loss,FLAGS.learning_rate)  #初始化参数,特别注意:string――input_producer内部创建了一个epoch计数变量  #归入tf.graphkey.local_variables集合中,必须单独用initialize_local_variables()初始化  init_op=tf.group(tf.global_variables_initializer(),       tf.local_variables_initializer())  sess=tf.Session()  sess.run(init_op)  #Start input enqueue threads  coord =tf.train.Coordinator()  threads=tf.train.start_queue_runners(sess=sess,coord=coord)  try:   step=0   while not coord.should_stop(): #进入永久循环    start_time=time.time()    _,loss_value=sess.run([train_op,loss])    #每100次训练输出一次结果    if step % 100 ==0:     duration=time.time()-start_time     print('Step %d: loss=%.2f (%.3f sec)'%(step,loss_value,duration))    step+=1  except tf.errors.OutOfRangeError:   print('Done training for %d epochs,%d steps.'%(FLAGS.num_epochs,step))  finally:   coord.request_stop()#通知其他线程关闭  coord.join(threads)  sess.close()def main(unused_argv): #获取数据 data_sets=input_data.read_data_sets(FLAGS.directory,dtype=tf.uint8,reshape=False,         validation_size=FLAGS.validation_size) #将数据转换成tf.train.Example类型,并写入TFRecords文件 convert_to(data_sets.train,'train') convert_to(data_sets.validation,'validation') convert_to(data_sets.test,'test') print('convert finished') run_training()if __name__ == '__main__': tf.app.run()

运行结果如图

以上这篇TFRecord格式存储数据与队列读取实例就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持。


  • 上一条:
    tensorflow estimator 使用hook实现finetune方式
    下一条:
    使用 tf.nn.dynamic_rnn 展开时间维度方式
  • 昵称:

    邮箱:

    0条评论 (评论内容有缓存机制,请悉知!)
    最新最热
    • 分类目录
    • 人生(杂谈)
    • 技术
    • linux
    • Java
    • php
    • 框架(架构)
    • 前端
    • ThinkPHP
    • 数据库
    • 微信(小程序)
    • Laravel
    • Redis
    • Docker
    • Go
    • swoole
    • Windows
    • Python
    • 苹果(mac/ios)
    • 相关文章
    • gmail发邮件报错:534 5.7.9 Application-specific password required...解决方案(0个评论)
    • 2024.07.09日OpenAI将终止对中国等国家和地区API服务(0个评论)
    • 2024/6/9最新免费公益节点SSR/V2ray/Shadowrocket/Clash节点分享|科学上网|免费梯子(0个评论)
    • 国外服务器实现api.openai.com反代nginx配置(0个评论)
    • 2024/4/28最新免费公益节点SSR/V2ray/Shadowrocket/Clash节点分享|科学上网|免费梯子(0个评论)
    • 近期文章
    • 在go语言中使用api.geonames.org接口实现根据国际邮政编码获取地址信息功能(1个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf分页文件功能(0个评论)
    • gmail发邮件报错:534 5.7.9 Application-specific password required...解决方案(0个评论)
    • 欧盟关于强迫劳动的规定的官方举报渠道及官方举报网站(0个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf文件功能(0个评论)
    • Laravel从Accel获得5700万美元A轮融资(0个评论)
    • 在go + gin中gorm实现指定搜索/区间搜索分页列表功能接口实例(0个评论)
    • 在go语言中实现IP/CIDR的ip和netmask互转及IP段形式互转及ip是否存在IP/CIDR(0个评论)
    • PHP 8.4 Alpha 1现已发布!(0个评论)
    • Laravel 11.15版本发布 - Eloquent Builder中添加的泛型(0个评论)
    • 近期评论
    • 122 在

      学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..
    • 123 在

      Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..
    • 原梓番博客 在

      在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..
    • 博主 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..
    • 1111 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
    • 2016-10
    • 2016-11
    • 2017-07
    • 2017-08
    • 2017-09
    • 2018-01
    • 2018-07
    • 2018-08
    • 2018-09
    • 2018-12
    • 2019-01
    • 2019-02
    • 2019-03
    • 2019-04
    • 2019-05
    • 2019-06
    • 2019-07
    • 2019-08
    • 2019-09
    • 2019-10
    • 2019-11
    • 2019-12
    • 2020-01
    • 2020-03
    • 2020-04
    • 2020-05
    • 2020-06
    • 2020-07
    • 2020-08
    • 2020-09
    • 2020-10
    • 2020-11
    • 2021-04
    • 2021-05
    • 2021-06
    • 2021-07
    • 2021-08
    • 2021-09
    • 2021-10
    • 2021-12
    • 2022-01
    • 2022-02
    • 2022-03
    • 2022-04
    • 2022-05
    • 2022-06
    • 2022-07
    • 2022-08
    • 2022-09
    • 2022-10
    • 2022-11
    • 2022-12
    • 2023-01
    • 2023-02
    • 2023-03
    • 2023-04
    • 2023-05
    • 2023-06
    • 2023-07
    • 2023-08
    • 2023-09
    • 2023-10
    • 2023-12
    • 2024-02
    • 2024-04
    • 2024-05
    • 2024-06
    • 2025-02
    Top

    Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号 PHP交流群

    侯体宗的博客