29-Tfrecords文件的读取与存储

tfrecords是tensorflow自带的文件格式,也是一种二进制文件:

  1. 方便读取和移动
  2. 是为了将二进制数据和标签(训练的类别标签)数据存储在同一个文件中
  3. 文件格式:*.tfrecords
  4. 写如文件的内容:Example协议块,是一种类字典的格式

TFRecords存储的api

"""api
1、建立TFRecord存储器
tf.python_io.TFRecordWriter(path)
    写入tfrecords文件
    path: TFRecords文件的路径
    return:写文件
method
    write(record):向文件中写入一个字符串记录
    close():关闭文件写入器
注:字符串为一个序列化的Example,Example.SerializeToString()

2、构造每个样本的Example协议块
tf.train.Example(features=None)
    写入tfrecords文件
    features:tf.train.Features类型的特征实例
    return:example格式协议块

tf.train.Features(feature=None)
    构建每个样本的信息键值对
    feature:字典数据,key为要保存的名字,
    value为tf.train.Feature实例
    return:Features类型

tf.train.Feature(**options)
    **options:例如
    bytes_list=tf.train. BytesList(value=[Bytes])
    int64_list=tf.train. Int64List(value=[Value])
    tf.train. Int64List(value=[Value])
    tf.train. BytesList(value=[Bytes])
    tf.train. FloatList(value=[value])

同文件阅读器流程,中间需要解析过程

解析TFRecords的example协议内存块
tf.parse_single_example(serialized,features=None,name=None)
    解析一个单一的Example原型
    serialized:标量字符串Tensor,一个序列化的Example
    features:dict字典数据,键为读取的名字,值为FixedLenFeature
    return:一个键值对组成的字典,键为读取的名字

tf.FixedLenFeature(shape,dtype)
    shape:输入数据的形状,一般不指定,为空列表
    dtype:输入数据类型,与存储进文件的类型要一致
    类型只能是float32,int64,string

"""

读取tfrecords的api与流程

"""api
同文件阅读器流程,中间需要解析过程

解析TFRecords的example协议内存块
tf.parse_single_example(serialized,features=None,name=None)
    解析一个单一的Example原型
    serialized:标量字符串Tensor,一个序列化的Example
    features:dict字典数据,键为读取的名字,值为FixedLenFeature
    return:一个键值对组成的字典,键为读取的名字
"""
"""流程
tf.FixedLenFeature(shape,dtype)
    shape:输入数据的形状,一般不指定,为空列表
    dtype:输入数据类型,与存储进文件的类型要一致
    类型只能是float32,int64,string


1、构造TFRecords阅读器
2、解析Example
3、转换格式,bytes解码
"""

tfrecords文件的读取

import tensorflow as tf

# 定义cifar的数据等命令行参数
FLAGS = tf.app.flags.FLAGS
tf.app.flags.DEFINE_string("cifar_dir", "cifar-10-batches-py", "文件的目录")
tf.app.flags.DEFINE_string("cifar_tfrecords", "./tmp/cifar.tfrecords", "存进tfrecords的文件")

class CifarRead():
    """
    完成读取二进制文件,写进tfrecords,读取tfrecords
    """

    def __init__(self, filelist):
        self.file_list = filelist  # 文件列表
        # 定义读取图片的一些属性
        self.height = 32
        self.width = 32
        self.channel = 3
        # 存储的字节
        self.label_bytes = 1
        self.image_bytes = self.height * self.width * self.channel
        self.bytes = self.label_bytes + self.image_bytes

    def read_and_decode(self):
        # 构造文件队列
        file_queue = tf.train.string_input_producer(self.file_list)
        # 构造二进制文件读取器,并指定读取长度
        reader = tf.FixedLengthRecordReader(self.bytes)
        key, value = reader.read(file_queue)
        # 解码内容
        print(value)
        # 二进制文件的解码
        label_image = tf.decode_raw(value, out_type=tf.uint8)
        print(label_image)
        # 分割图片和标签:特征值和目标值
        label = tf.slice(label_image, [0], [self.label_bytes])  #读取标签
        image = tf.slice(label_image, [self.label_bytes], [self.image_bytes])  #读取特征向量
        print("label:", label)
        print("image:", image)
        # 对图片的特征数据进行形状的改变 [3072] --> [32, 32, 3]
        image_reshape = tf.reshape(image, [self.height, self.width, self.channel])
        print("image_reshape:", image_reshape)

        # 批处理数据
        image_batch, label_batch = tf.train.batch([image_reshape, label], batch_size=10, num_threads=1, capacity=10)
        print(image_batch, label_batch)
        return image_batch, label_batch

    def write_to_tfrecords(self, image_batch, label_batch):
        """
        将图片的特征值和目标值存进tfrecords
        :param image_batch: 10张图片的特征值
        :param label_batch: 10张图片的目标值
        :return: None
        """
        #建立一个tfrecords存储器
        writer = tf.python_io.TFRecordWriter(path=FLAGS.cifar_tfrecords)  #注意:tf.python_io.TFRecordWriter已经被tf.io.TFRecordWriter代替
        #循环将所有样本写入文件,每张图片样本都要构造一个example协议
        for i in range(10):
            #取出第i个图片数据的特征值和目标值
            image = image_batch[i].eval().tostring()   #.eval()获取值
            label = label_batch[i].eval()[0]    #因为是一个二维列表,所以必须取[0]
            """注意:eval必须写在session中"""
            #构造一个样本的example
            example = tf.train.Example(features=tf.train.Features(feature={
                "image":tf.train.Feature(bytes_list=tf.train.BytesList(value=[image])),
                "label":tf.train.Feature(int64_list=tf.train.Int64List(value=[label]))
            }))
            #写入单独的样本
            writer.write(example.SerializeToString())   #序列化后再写入文件
        #关闭
        writer.close()

    def read_from_tfrecords(self):
        #构造文件阅读器
        file_queue = tf.train.input_producer([FLAGS.cifar_tfrecords])
        #构造文件阅读器,读取内容example
        reader = tf.TFRecordReader()
        key, value = reader.read(file_queue)  #value也是一个example的序列化
        #由于存储的是example,所以需要对example解析
        features = tf.parse_single_example(value, features={
            "image":tf.FixedLenFeature(shape=[], dtype=tf.string),
            "label":tf.FixedLenFeature(shape=[], dtype=tf.int64)
        })
        print(features["image"], features["label"]) #注意:此时是tensor
        #解码内容,如果读取的string类型,需要解码,如果是int64,float32就不需要解码。因为里面都是bytes,所以需要解码
        image = tf.decode_raw(features["image"], tf.uint8)
        label = tf.cast(features["label"], tf.int32)   #label不需要解码,因为int64实际在存储的时候还是以int32存储的,不会占用那么多空间,所以这里可以直接转换成int32
        print(image, label)
        #固定图片的形状,以方便批处理
        image_reshape = tf.reshape(image, [self.height, self.width, self.channel])
        print(image_reshape)
        #进行批处理
        image_batch, label_batch = tf.train.batch([image_reshape, label], batch_size=10, num_threads=1, capacity=10)
        return image_batch, label_batch
import os

if __name__ == "__main__":
    # 找到文件,放入列表 路径+名字 ->列表当中
    file_name = os.listdir(FLAGS.cifar_dir)
    file_list = [os.path.join(FLAGS.cifar_dir, file) for file in file_name if "0" <= file[-1] <= "9"]
    print(file_list)
    cf = CifarRead(file_list)
    image_batch, label_batch = cf.read_and_decode()
    # image_batch, label_batch = cf.read_from_tfrecords()
    with tf.Session() as sess:
        coord = tf.train.Coordinator()
        threads = tf.train.start_queue_runners(sess, coord=coord)
        print(sess.run([image_batch, label_batch]))
        #存进tfrecords文件
        print("开始存储...")
        cf.write_to_tfrecords(image_batch, label_batch) #因为这个函数里面有eval,所以必须在session里面运行
        print("结束存储...")
        # print("读取的数据:\n",sess.run([image_batch, label_batch]))
        coord.request_stop()
        coord.join()

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,451评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,172评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,782评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,709评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,733评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,578评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,320评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,241评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,686评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,878评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,992评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,715评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,336评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,912评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,040评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,173评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,947评论 2 355

推荐阅读更多精彩内容