TF_IO_TFRecords.md

Target

  • 二分类任务样本制作成标准TF格式(TFRecords)
  • 读入TFRecords并展示图片
  • 高效多线程读入TFRecords

Introduction

tensorflow/core/example/example.proto 中有详细的例子说明.

message Example {
  Features features = 1;
};

简要说就是每个样本变成了一个key-value的字典形式, key为字符串,value可以是字符串, 整型, 浮点型. 不同类型的标签在TF中会非常容易的实现. 但是在Caffe中(-.-)..

Value的格式(注:Int为Int64)
  • BytesList
  • FloatList
  • Int64List

tensorflow/core/example/feature.proto 中定义

// Containers to hold repeated fundamental values.
message BytesList {
  repeated bytes value = 1;
}
message FloatList {
  repeated float value = 1 [packed = true];
}
message Int64List {
  repeated int64 value = 1 [packed = true];
}

// Containers for non-sequential data.
message Feature {
  // Each feature can be exactly one kind.
  oneof kind {
    BytesList bytes_list = 1;
    FloatList float_list = 2;
    Int64List int64_list = 3;
  }
};

message Features {
  // Map from feature name to feature.
  map<string, Feature> feature = 1;
};

[个人理解]
说明一下, 一条数据或一个样本其实就是一个Example(其实还有SequenceExample,本文只说明Example), 数据中会存在许多的属性, 所有的属性信息都存储在Features类中, 并且每个属性由Key-Value来实现 map<string, Feature> feature. 所有的Key都是字符型, 但是数据可以是bytes,float或int64类型.

官方例子:

//features {
//     feature {
//       key: "age"
//       value { float_list {
//         value: 29.0
//       }}
//     }
//     feature {
//       key: "movie"
//       value { bytes_list {
//         value: "The Shawshank Redemption"
//         value: "Fight Club"
//       }}
//     }
//}

了解了存储格式代码就比较好弄了

制作TFRecords

#_*_ coding:utf-8 _*_
import os
import numpy as np
import tensorflow as tf
import cv2
'''
Example : fileName
Train/1.jpg 0
Train/2.jpg 1
Train/3.jpg 1
Train/4.jpg 1
'''

# 因为创建Feature需要list
def toList(value):
    if type(value) == list:
        return value
    else:
        return [value]

# 创建不用类型的Feature数据
def _int64_feature(value):
    value = toList(value)
    value = [int(x) for x in value]
    return tf.train.Feature(int64_list=tf.train.Int64List(value = value))

def _float_feature(value):
    value = toList(value)
    value = [float(x) for x in value]
    return tf.train.Feature(float_list=tf.train.FloatList(value = value))

def _bytes_feature(value):
    return tf.train.Feature(bytes_list=tf.train.BytesList(value = toList(value)))

# Make TFRecords
def MakeTFRecord(fileName,tfrecords,imageRoot):
    # 创建一个TFRecordWriter来进行写入数据
    writer = tf.python_io.TFRecordWriter(tfrecords)
    fp = open(fileName,'r')
    lines = fp.readlines()
    for line in lines:
        line = line.strip().split()
        imagePath = os.path.join(imageRoot,line[0])
        print imagePath

        ## PIL Image 通道顺序RBG
        #img = Image.open(imagePath)
        #img_raw = img.tobytes()

        ## cv2 通道顺序BGR, 本例采取灰度图
        img = cv2.imread(imagePath,0)
        # 注意resize之后要赋值回img
        img = cv2.resize(img,(128,128))
        #cv2.imshow("d",img)
        #cv2.waitKey(0)
        # 把图像数据变成二进制,节省空间
        img_raw = img.tostring()
        # 创建一个Example
        example = tf.train.Example(
            # 创建一个Features
            features=tf.train.Features(
                # 填写不同类型的key-value
                feature={
                    "img_raw":_bytes_feature(img_raw),
                    "label": _int64_feature(line[1:])
                }
        ))
        # 把example进行序列化,Serializes the protocol message to a binary string
        writer.write(example.SerializeToString())
    writer.close()

读取并显示 TFRecords

其实上面的制作理解了,读其实只是一个逆过程,一个解序列化的过程

# 创建tfrecords迭代器,每个样本都是序列化的
serialized_ex_it = tf.python_io.tf_record_iterator(tfrecords)
for serialized_ex in serialized_ex_it:
    # 创建Example对象
    example = tf.train.Example()
    # 进行解序列化(注:解析的是Example对象)
    example.ParseFromString(serialized_ex)
    # 输出所有信息, 如果想知道TFRecords中属性可以输出example
    print example
    # 取出正确的key并且正确的类型的value值,错一个都会取不出值
    image = example.features.feature['img_raw'].bytes_list.value
    label = example.features.feature['label'].int64_list.value

    print image, label

虽然上述可以读取数据,但是每个样本都需要解析一次,往往我们的数据都是结构化的,能不能一次就读入许多数据,并且在训练的时候数据是需要反复输入到训练集中的.

# Read TFRecords using queue structs
def ReadTFRecord(tfrecords):
    # 可以把多个tfrecords排成一个queue,这样可以方便的使用多个tfrecords文件
    record_queue = tf.train.string_input_producer([tfrecords])
    # 读取TFRecords器
    reader = tf.TFRecordReader()
    # 一个数据一个数据的读返回key-value值,都保存在serialized_ex中
    # 注意: 这里面keys是序列化的副产物,命名为tfrecords+random(),表示唯一的ID,没有作用,可以设置为_
    #keys, serialized_ex = reader.read(record_queue)
    _, serialized_ex = reader.read(record_queue)
    # 直接解析出features数据,并且使用固定特征长度,及每个Example中一定会存在一个image和一个label
    # 并不是输入的图片大小不同就使用VarLenFeature.
    features = tf.parse_single_example(serialized_ex,
            features={
                # 取出key为img_raw和label的数据,尤其是int位数一定不能错!!!
                'img_raw': tf.FixedLenFeature([],tf.string),
                'label': tf.FixedLenFeature([], tf.int64)
            })
    img = tf.decode_raw(features['img_raw'], tf.uint8)

    # 注意定义的为int多少位就转换成多少位,否则容易出错!!
    label = tf.cast(features['label'], tf.int64)
    return img, label

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

推荐阅读更多精彩内容