TFRecord和Example

Note

TFRecord格式是Tensorflow首选的格式,用于存储大量数据并有效读取数据。
TFRecord 格式是一种用于存储二进制记录序列的简单格式。

TFRecord文件

A TFRecord file is just a list of binary records.

import tensorflow as tf

# 创建TFRecord文件
with tf.io.TFRecordWriter("my_data.tfrecord") as f:
    f.write(b"This is the first record")
    f.write(b"And this is the second record")
# 读取TFRecord文件
filepaths = ["my_data.tfrecord"]
dataset = tf.data.TFRecordDataset(filepaths)
for item in dataset:
    print(item)
tf.Tensor(b'This is the first record', shape=(), dtype=string)
tf.Tensor(b'And this is the second record', shape=(), dtype=string)

协议缓冲区

尽管TFRecord的每个记录可以包含任意的二进制数据,但通常来说它会包含序列化的协议缓冲区(protobufs)。

协议缓冲区是一个跨平台、跨语言的库,用于高效地序列化结构化数据。

协议消息由 .proto 文件定义,这通常是了解消息类型最简单的方法,如:

syntax = "proto3"
message Person {
    string name = 1;
    int32 id = 2;
    repeated string email = 3;
}

此定义表示我们使用的是protobuf格式的第三个版本。

它指定每个Person对象具有string类型的name,int32类型的id和零个或多个string类型的email。

数字1、2和3是字段标识符。

Example

TFRecord文件中通常使用的protobufs是Example protobuf,它表示数据集中的一个实例。

以下是Example protobuf类型的定义:

syntax = "proto3";

message BytesList { repeated bytes value = 1; }
message FloatList { repeated float value = 1 [packed = true]; }
message Int64List { repeated int64 value = 1 [packed = true]; }
message Feature {
    oneof kind {
        BytesList bytes_list = 1;
        FloatList float_list = 2;
        Int64List int64_list = 3;
    }
};
message Features { map<string, Feature> feature = 1; };
message Example { Features features = 1; };

BytesList、FloatList和IntList的定义非常简单直接,[packed=true] 用于重复的数字字段以实现更有效的编码。

一个 Feature 包含一个BytesList或FloatList或IntList。

一个 Features(带s)包含将特征名称映射到相应特征的值的字典。

最后,一个 Example 仅包含一个 Features 对象(为了可扩展所以又包装了一层)。