TF_record 加 dataset 为network 打数据基础

根据知乎文章 这个 总结而成,方便以后的使用。  主要是为了使用estimator 构建神经网络来处理数

主要流程如下1、将数据处理成tfrecord的形式,2、用tf解析tf_record ,并放到dataset中,3、像操作张量一样来操作dataset。

TensorFlow中层API:Datasets+TFRecord的数据导入

一、使用TFRecord的好处

  1. 只定义一条数据的处理方式,所有数据都按照这个方式来处理。更加简洁。
  2. 将数据操作放到图里面去,省去了feed数据的过程。
  3. 对于大的数据集,可以提速和节约空间。
  4. 对接estimator
  5. 一些小操作很方便 尤其是padding

二、TFRecord 简介

是一个字典类型数据{ “age”:15,“preference”:[1,0,1,0], "学历":{“初中”:0,“大学”:1} } 形势很灵活value的值可以是任何维度的值。

(1)使用方法 将数据写入到TFRecord文件中

  1. 首先建立一个文件读写器:
    writer = tf.python_io.TFRecordWriter('%s.tfrecord' %'test')
  2. 可以写入以下三种的类型
    1. int64:tf.train.Feature(int64_list = tf.train.Int64List(value=输入))

      float32:tf.train.Feature(float_list = tf.train.FloatList(value=输入))

      string:tf.train.Feature(bytes_list=tf.train.BytesList(value=输入))

      注:输入必须是list(向量)

  3. 将数据一条一条的写入,注意最后的张量的写入方式,因为只接受list类型,所以把张量转化为list,再加一个shape保存信息。
    # 这里我们将会写3个样本,每个样本里有4个feature:标量,向量,矩阵,张量
    for i in range(3):
        # 创建字典
        features={}
        # 写入标量,类型Int64,由于是标量,所以"value=[scalars[i]]" 变成list
        features['scalar'] = tf.train.Feature(int64_list=tf.train.Int64List(value=[scalars[i]]))
        
        # 写入向量,类型float,本身就是list,所以"value=vectors[i]"没有中括号
        features['vector'] = tf.train.Feature(float_list = tf.train.FloatList(value=vectors[i]))
        
        # 写入矩阵,类型float,本身是矩阵,一种方法是将矩阵flatten成list
        features['matrix'] = tf.train.Feature(float_list = tf.train.FloatList(value=matrices[i].reshape(-1)))
        # 然而矩阵的形状信息(2,3)会丢失,需要存储形状信息,随后可转回原形状
        features['matrix_shape'] = tf.train.Feature(int64_list = tf.train.Int64List(value=matrices[i].shape))
        
        # 写入张量,类型float,本身是三维张量,另一种方法是转变成字符类型存储,随后再转回原类型
        features['tensor']         = tf.train.Feature(bytes_list=tf.train.BytesList(value=[tensors[i].tostring()]))
        # 存储丢失的形状信息(806,806,3)
        features['tensor_shape'] = tf.train.Feature(int64_list = tf.train.Int64List(value=tensors[i].shape))
  4. 转化为相应类型之后 经过下面操作将数据一条一条的写入进去
# 将存有所有feature的字典送入tf.train.Features中
tf_features = tf.train.Features(feature= features)    

#再将其变成一个样本example
tf_example = tf.train.Example(features = tf_features)

# 序列化该样本
tf_serialized = tf_example.SerializeToString()

# 写入一个序列化的样本
writer.write(tf_serialized)
# 由于上面有循环3次,所以到此我们已经写了3个样本

如此这般之后,我们得到了 TFrecord文件 名字叫 test.tfrecord

三、 使用dataset

  1.     dataset 是我们需要用的所有的数据集,从TFrecord种读取得到
    filenames = ["test.tfrecord", "test.tfrecord"]
    dataset = tf.data.TFRecordDataset(filenames)
  2.    操作dataset,当我们得到从TFrecord中得到的数据后需要解析一下以便使用我们首先构建一个解析函数
    1. #首先创建一个解析函数
      def parse_function(example_proto):
          # 只接受一个输入:example_proto,也就是序列化后的样本tf_serialized
          =====================================================================
          #STEP1 :创建样本解析字典
           
            该字典存放着所有feature的解析方式,key为feature名,value为feature的解析方式。
      
            解析方式有两种:
      
            定长特征解析:tf.FixedLenFeature(shape, dtype, default_value)
            shape:可当reshape来用,如vector的shape从(3,)改动成了(1,3)。
            注:如果写入的feature使用了.tostring() 其shape就是()
            dtype:必须是tf.float32, tf.int64, tf.string中的一种。
            default_value:feature值缺失时所指定的值。
      
            不定长特征解析:tf.VarLenFeature(dtype)
            注:可以不明确指定shape,但得到的tensor是SparseTensor。
         ==================================================================================
          dics = {# 这里没用default_value,随后的都是None
                  'scalar': tf.FixedLenFeature(shape=(), dtype=tf.int64, default_value=None), 
                   
                  # vector的shape刻意从原本的(3,)指定成(1,3)
                  'vector': tf.FixedLenFeature(shape=(1,3), dtype=tf.float32), 
                  
                  # 使用 VarLenFeature来解析
                  'matrix': tf.VarLenFeature(dtype=dtype('float32')), 
                  'matrix_shape': tf.FixedLenFeature(shape=(2,), dtype=tf.int64), 
                  
                  # tensor在写入时 使用了toString(),shape是()
                  # 但这里的type不是tensor的原type,而是字符化后所用的tf.string,随后再回转成原        
                  tf.uint8类型
                  'tensor': tf.FixedLenFeature(shape=(), dtype=tf.string), 
                  'tensor_shape': tf.FixedLenFeature(shape=(3,), dtype=tf.int64)}
      
          +++++++++++++++++++++++++++++++++++++++++++
          STEP 2: 解析样本
          +++++++++++++++++++++++++++++++++++++++
      
          # 把序列化样本和解析字典送入函数里得到解析的样本
          parsed_example = tf.parse_single_example(example_proto, dics)
      
      
          ====================================
           STEP 3: 改变特征
          得到的parsed_example也是一个字典,其中每个key是对应feature的名字,value是相应的feature解    
          析值。如果使用了下面两种情况,则还需要对这些值进行转变。其他情况则不用。
      
          string类型:tf.decode_raw(parsed_feature, type) 来解码
          注:这里type必须要和当初.tostring()化前的一致。如tensor转变前是tf.uint8,这里就需是        
          tf.uint8;转变前是tf.float32,则tf.float32
          VarLen解析:由于得到的是SparseTensor,所以视情况需要用    
          tf.sparse_tensor_to_dense(SparseTensor)来转变成DenseTensor
          ==================================
           # 解码字符
          parsed_example['tensor'] = tf.decode_raw(parsed_example['tensor'], tf.uint8)
          # 稀疏表示 转为 密集表示
          parsed_example['matrix'] = tf.sparse_tensor_to_dense(parsed_example['matrix'])
      
      
           ====================================
           STEP 4: 改变形状
          ==================================
          # 转变matrix形状
          parsed_example['matrix'] = tf.reshape(parsed_example['matrix'],         parsed_example['matrix_shape'])
          
          # 转变tensor形状
          parsed_example['tensor'] = tf.reshape(parsed_example['tensor'], parsed_example['tensor_shape'])
      
           ====================================
           STEP 5 :返回 
          ==================================
      
      return parsed_example
      
      
    2.   执行解析函数 值得注意的是  如果对数据集有特殊的处理可以在解析函数的末尾一起返回。
      new_dataset = dataset.map(parse_function)
  3. 再之后就是使用了
#迭代器
iterator = new_dataset.make_one_shot_iterator()

# 获得下一个样本
next_element = iterator.get_next()

# 创建Session
sess = tf.InteractiveSession()

# 获取
i = 1
while True:
    # 不断的获得下一个样本
  
    # 获得的值直接属于graph的一部分,所以不再需要用feed_dict来喂
    scalar,vector,matrix,tensor = sess.run([next_element['scalar'],
                                                next_element['vector'],
                                                next_element['matrix'],
                                                next_element['tensor']])

shuffle

buffer_size设置成一个大于你数据集中样本数量的值来确保其充分打乱。如果 数据集很大 可以把数据集组成多个tf_record 这样来打乱。抽空写一下具体的操作方法

shuffle_dataset = new_dataset.shuffle(buffer_size=10000)
iterator = shuffle_dataset.make_one_shot_iterator()
next_element = iterator.get_next()

 batch

batch_dataset = shuffle_dataset.batch(4)
iterator = batch_dataset.make_one_shot_iterator()
next_element = iterator.get_next()

padding 

padded_shapes指定了内部数据是如何pad的。

  • rank数要与元数据对应
  • rank中的任何一维被设定成None或-1时都表示将pad到该batch下的最大长度
batch_padding_dataset = new_dataset.padded_batch(4, 
                        padded_shapes={'scalar': [],
                                       'vector': [-1,5],
                                       'matrix': [None,None],
                                       'matrix_shape': [None],
                                       'tensor': [None,None,None],
                                       'tensor_shape': [None]})
iterator = batch_padding_dataset.make_one_shot_iterator()
next_element = iterator.get_next()

Epoch

# num
num_epochs = 2
epoch_dataset = new_dataset.repeat(num_epochs)
iterator = epoch_dataset.make_one_shot_iterator()
next_element = iterator.get_next()
### 使用SSD框架训练自定义VOC格式的数据集 #### 准备工作 为了使用SSD框架训练自定义的PASCAL VOC格式数据集,需先准备好环境并转换数据至适合模型输入的形式。 确保已按照项目指南完成环境配置[^1]。对于特定于目标检测的任务,尤其是当采用类似于TensorFlow SSD实现时,通常需要将原始图片及其对应的标签转化为TFRecord文件形式以便高效读取与处理[^2]。 #### 数据预处理 创建一个Shell脚本来自动化这一过程是非常有帮助的做法: ```bash #!/bin/bash # 定义变量指向源数据路径以及目标存储位置 DATASET_DIR=./VOC2007/ OUTPUT_DIR=./tfrecords_ # 执行Python脚本进行数据转化 python ./tf_convert_data.py \ --dataset_name=pascalvoc \ --dataset_dir=${DATASET_DIR} \ --output_name=voc_2007_train \ --output_dir=${OUTPUT_DIR} ``` 上述命令通过调用`tf_convert_data.py`工具来把标准的PASCAL VOC结构下的图像和XML标注文件打包成`.record`扩展名的二进制记录文件,这些文件可以直接被后续训练流程所利用。 #### 修改配置文件 接下来要调整网络架构参数以适应新的类别数量和其他可能的变化。这涉及到编辑pipeline.config或其他类似的配置文档,在其中指定新生成的TFRecords的位置以及其他必要的超参设置。 #### 开始训练 一切就绪之后就可以启动实际的训练进程了。一般情况下,可以通过简单的命令行指令来进行操作,比如: ```bash python train_ssd_network.py --train_dir=PATH_TO_TRAIN_DIR --pipeline_config_path=PATH_TO_CONFIG_FILE ``` 这里的`train_ssd_network.py`代表具体的训练入口程序名称;而两个必需选项分别指定了保存检查点的地方(`train_dir`)还有之前提到过的配置文件所在之处(`pipeline_config_path`)。 #### 验证效果 最后一步是对得到的结果做评估,确认模型性能达到预期水平。可以借助内置的功能或是编写额外的小型应用程序来进行预测展示,从而直观地观察到识别精度等方面的信息变化情况[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值