前言
- 本文内容主要搬运自官方文档
- 意在梳理相关内容,解决工作中遇到的问题:提升数据加载、处理效率
- 本文主要围绕tf.record、tf.data、tf.keras展开梳理,会涉及一些个人demo
1. tf.record & tf.Example
- 对数据进行序列化并将其存储在一组可线性读取的文件(每个文件 100-200MB)中。这尤其适用于通过网络进行流式传输的数据。这种做法对缓冲任何数据预处理也十分有用。
- tf.Example 消息(或 protobuf)是一种灵活的消息类型,表示 {“string”: value} 映射。
- 如果使用tf.data并且读取数据是目前训练的瓶颈,官方介绍了一些优化方法
1.1 tf.Example基本概念
从根本上讲,tf.Example 是 {“string”: tf.train.Feature} 映射
- tf.train.Feature 消息类型可以接受以下三种类型
类型 | 可转换自 |
---|---|
tf.train.BytesList | String Byte |
tf.train.FloatList | float double |
tf.train.Int64List | bool enum int32 uint32 int64 unint64 |
- 可以通过快捷函数将标量的输入值转化为上述三个类型之一
- def _bytes_feature(value)
- def _float_feature(value)
- def _int64_feature(value)
- 对于非标量,可转换为二进制字符串后再输入
- 最后,使用.SerializeToString方法将所有的消息,序列化成二进制字符串
import tensorflow as tf
import numpy as np
## !!单条数据转换!!
def _bytes_feature(value):
"""Returns a bytes_list from a string / byte."""
if isinstance(value, type(tf.constant(0))): # tensorflow.python.framework.ops.EagerTensor
value = value.numpy() # BytesList won't unpack a string from an EagerTensor.
return tf.train.Feature(bytes_list=tf.train.BytesList(value=[value]))
def _float_feature(value):
"""Returns a float_list from a float / double."""
return tf.train.Feature(float_list=tf.train.FloatList(value=[value]))
def _int64_feature(value):
"""Returns an int64_list from a bool / enum / int / uint."""
return tf.train.Feature(int64_list=tf.train.Int64List(value=[value]))
# 测试
print(_bytes_feature(b'test_string'))
print(_bytes_feature(u'test_bytes'.encode('utf-8')))
print(_float_feature(np.exp(1)))
print(_int64_feature(True))
print(_int64_feature(1))
feature = _float_feature(np.exp(1))
feature.SerializeToString()
1.2 如何创建tf.Example消息
- 目标:如何把一个平平无奇的观测值(文本、整数、浮点数…)转化为tf.Example消息 以及 解析
- 我们的原始数据可能来自任何地方、有各种存储格式,但是从单个观测值来看,创建tf.Example消息的过程是相同的
- tf.Example 消息只是 Features 消息外围的包装器
# 创建一个包含若干数据类型的数据集
n_observations = int(1e4)
feature0 = np.random.choice([False, True], n_observations) # bool
feature1 = np.random.randint(0, 5, n_observations) # int
strings = np.array([b'cat', b'dog', b'chicken', b'horse', b'goat'])
feature2 = strings[feature1] # byte
feature3 = np.random.randn(n_observations) # float
def serialize_example(feature0, feature1, feature2, feature3):
"""
Creates a tf.Example message ready to be written to a file.
"""
# Create a dictionary mapping the feature name to the tf.Example-compatible
# data type.
feature = {
'feature0': _int64_feature(feature0),
'feature1': _int64_feature(feature1),
'feature2': _bytes_feature(feature2),
'feature3'