Using TFRecords and tf.Example

-----这篇其实是TensorFlow的官方tutorials,由于没有翻译,笔者姑且翻译一下,用来日后思考。-------

原址:https://www.tensorflow.org/tutorials/load_data/tf_records

读取数据的效率对于连续载入数据和将数据储存在文件集(每个文件大概100-200MB)是很有帮助的。如果数据是输入到一个网络上来说更是如此,当然这对将预处理的数据输入到cache同样有用。

储存二进制的数据的一种简单的格式就是TFRecord格式。

Protocol buffers 是一个跨平台、跨语言的库,它被使用在高效率的连续载入结构化的数据。Protocol messages 以  .proto结尾,这通常是理解消息类型的最简单的方式。

tf.Example 消息(或者protobuf)是一种象征着   {"string":value} 映射的灵活的消息类型。它被设计与TensorFlow使用,在高阶的APIs(例如TFX)中使用。

这份说明将会阐释关于 tf.Example 的创建,语法和使用,以及之后的载入,write 和读取 tf.Example 消息,以及读取 .tfrecord 文件。

注意:当必要时,这些结构是可选的,对于将已经存在的代码再去使用TFRecord, 除非你正在使用tf.data以及读取数据仍然对训练来说是一个瓶颈。

Setup

from __future__ import absolute_import, division, print_function, unicode_literals

import tensorflow as tf
tf.enable_eager_execution()

import numpy as np
import IPython.display as display

tf.Example

1. tf.Eample的数据类型

实际上,一个 tf.Example 是一个{"string":tf.train.Feature}的映射。

tf.train.Feature消息类型能接受以下三种类型(查看.proto file寻求帮助)

大部分其他的常见普通类型都可强制转换成下面其中的一个。

  1. tf.train.BytesList(下列类型可强制转换)
    1. string
    2. byte  
  2. tf.train.FloatList
    1.  float(float32)
    2.  double(float64)
  3. tf.train.Int64List
    1. bool
    2. enum
    3. int32
    4. int64
    5. uint32
    6. uint64

你可以使用下列函数来将标准的TensorFlow类型转换为与tf.Example相兼容的tf.train.Feature.

每个函数有一个标量输入,返回一个包含上述三种list类型中的一种的tf.train.Feature

# The following functions can be used to convert a value to a type compatible
# with tf.Example.

def _bytes_feature(value):
  """Returns a bytes_list from a string / byte."""
  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]))

Note: 为了简单起见,本示例只使用了标量输入。处理非标量输入最简单的方法就是使用tf.serialize_tensor来将tensor转换为binary-strings。字符串在tensorflow中是标量。使用tf.parse_tensor可以将binary-string转换回tensor.

下面是这些函数如何工作的一些例子,我们注意下不同的输入类型和标准化的输出类型。如果输入类型与前面列举出来的类型不匹配的话,函数就会报错。

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))
bytes_list {
  value: "test_string"
}

bytes_list {
  value: "test_bytes"
}

float_list {
  value: 2.7182817459106445
}

int64_list {
  value: 1
}

int64_list {
  value: 1
}

所有的 proto messages 可以使用.SerializeToString 方法被载入成为 binary-string

feature = _float_feature(np.exp(1))

feature.SerializeToString()
b'\x12\x06\n\x04T\xf8-@'

创建一个tf.Example消息

假设你要从已经存在的数据中生成tf.Example消息,在实际中,这个数据集可能来自任何地方。但是从单样本生成tf.Example消息的步骤是相同的。

  1. 在每个样本中,每个值需要被转换成包含三种兼容类型中的一个的tf.train.Feature,使用上述的函数。
  2. 我们从在步骤1中产生的 feature name string 和编码过的value组成一个字典
  3. #2中产生的字典被转换为一个Features message

下面的代码,我们用numpy产生一个dataset

这个dataset有4个特征:一个bool特征,False 和True出现的概率相等;一个整型特征[0,5)均匀分布;一个字符串 特征,他是从一个用整型特征作为index,一个字符串表格生成的;一个float 特征,标准正态分布生成。

  10,000个独立同分布的样本。

# the number of observations in the dataset
n_observations = int(1e4)

# boolean feature, encoded as False or True
feature0 = np.random.choice([False, True], n_observations)

# integer feature, random from 0 .. 4
feature1 = np.random.randint(0, 5, n_observations)

# string feature
strings = np.array([b'cat', b'dog', b'chicken', b'horse', b'goat'])
feature2 = strings[feature1]

# float feature, from a standard normal distribution
feature3 = np.random.randn(n_observations)

--to be continued--

猜你喜欢

转载自www.cnblogs.com/saurywb/p/11374086.html