包含一下两个部分内容
- 制作tfrecord文件
- 读取tfrecord文件
主要参考https://www.cnblogs.com/wj-1314/p/11211333.html
- 制作tfrecord文件
tfrecord文件的核心就是Example消息,制作tfrecord文件一般就分为构造Example消息和将其写入tfrecord文件。
构造Example消息
参考https://blog.csdn.net/hfutdog/article/details/86244944
首先tf.train.Example类将数据处理成二进制形式,用于提升IO效率和方便数据管理。一个Example消息体包含了一系列的feature属性。每一个feature属性是一个{"string": tf.train.Feature}的映射。也就是 key-value 的键值对。key 取值是String类型。而value是Feature类型的消息体。
tf.train.Feature是一种信息类型,这种信息有三种类型,可以通过以下三个类将原始数据转换成对应的三种类型:
tf.train.BytesList
,可以将string类和byte类型的数据强制转换成此类;tf.train.Int64List,可以将
bool,enum,int32,uint32,int64,uint64类型的数据强制转换成此类;tf.train.FloatList
,可以将float(float32)和double(float64)类型的数据强制转换成此类;
这三种类型通过函数tf.train.Feature(),将标准的TensorFlow类型转换为一个与tf.train.Example兼容的类型。
如何创建一个tf.train.Example消息(以构造单个Example消息为例):
(一)、对于每一个数据,它的值需要转化成tf.train.Feature所包含的上诉三种类型之一,使用对应的函数转换即可,例如:
feature_val1 = tf.train.BytesList(value=[value_ob1]) #value_ob1是原始数据,被转换成tf.train.BytesList类型的feature_val
feature_val2 = tf.train.FloatList(value=[value_ob2])
(二)、创建一个从feature名的字符串到编码feature值的映射字典(feature值通过tf.train.Feature()构造的对象),如下所示
feature_dict = {
'feature_name1': tf.train.Feature(bytes_list=feature_val1),
'feature_name2': tf.train.Feature(float_list=feature_val2),
}
(三)、创建一个tf.train.Features对象,作为参数值传递给tf.train.Example的features属性:
features = tf.train.Features(feature=feature_dict)
(四)、创建一个 Features信息(也就是Example对象)
example = tf.train.Example(features=features)
(五)、上面四个步骤创建了一个对象,但是我们在写入文件的时候,不能直接处理对象,需要将对象转化成字符串,所以还需要使用tf.train.Example的方法SerializeToString(),将Example对象序列化为字符串。
example_str = example.SerializeToString()
tf.io.TFRecordWriter(或者是tf.python_io.TFRecordWriter,还没找到二者区别,或许与tensorflow的版本有关)写入文件
序列化Example对象后,通过tf.io.TFRecordWriter将其写入到TFRecord文件:
# 创建一个tf.io.TFRecordWriter对象
tf_writer = tf.io.TFRecordWriter("ob_file.tfrecord") #ob_file.tfrecord需要写入的文件所在路径
tf_writer.write(example_str)
tf.writer.close()
- 读取tfrecord文件
这里通过 tf.data.TFRecordDataset
类,将一个或多个 TFRecord 文件的内容作为输入管道的一部分进行流式传输。
(一)、建立一个data
data = tf.data.TFRecordDataset("ob_file") #ob_file就是record文件名
(二)、在对data中的数据进行操作时,需要对tfrecord文件中的数据进行解析,使用 tf.parse_single_example接口 ,这个接口对单个example对象进行解析。
feats = tf.parse_single_example(serial_exmp, features=data_dict)
serial_exmp是需要解析的example信息,data_dict是一个字典,字典的键与写入tfrecord文件时单个example对象的feature名对应,字典的值也是对应内容。 tf.parse_single_example接口的使用实例如下所示:
features = {
'feature_name1': tf.FixedLenFeature((), tf.string),
'feature_name2': tf.FixedLenFeature((), tf.float32),
}
parsed_features = tf.parse_single_example(example_string, features=features)
tf.parse_single_example通常结合Dataset的map方法,对data中的所有数据都进行解析:
# 定义一个解析函数
def _parse_record(example):
features = {
'feature_name1': tf.FixedLenFeature((), tf.string),
'feature_name2': tf.FixedLenFeature((), tf.float32)
}
parsed_features = tf.parse_single_example(example, features=features)
return parsed_features
# 使用上面的函数对data中的每个example进行解析
data_parse = data.map(_parse_record)