三种基础数据类型:bytes,float,int64
对应tf.train中三种类型:BytesList (字符串列表), FloatList (浮点数列表), Int64List (64位整数列表),构造它们三个依照下面的方式传入相对应的value。
tf.train.BytesList(value=[context_idxs.tostring()]
tf.train.Int64List(value=[1,2])
tf.train.FloatList(value=[0.1,0.2])
要将我们的数据写入 .tfrecords 文件,需要将每一个样本数据封装为tf.train.Example格式,再将Example逐个写入文件。Example格式中的数据基础类型是tf.train.Feature
tf.train.Feature(): 它的参数是BytesList, FloatList, Int64List三种
tf.train.Feature(bytes_list=tf.train.BytesList(value=)
tf.train.Feature(int64_list=tf.train.Int64List(value=)
tf.train.Feature(float_list=tf.train.FloatList(value=)
tf.train.Features: 它的参数是一个字典,k-v对中 v 的类型是Feature,对应每一个字段。
tf.train.Features(feature={
"k1": tf.train.Feature(bytes_list=tf.train.BytesList(value=])),
"k2": tf.train.Feature(bytes_list=tf.train.BytesList(value=)),
"k3": tf.train.Feature(float_list=tf.train.FloatList(value=)),
})
tf.train.FeatureList: 它的参数是一个Feature的list, [Feature1, Feature2,…]
"context_idxs": tf.train.FeatureList(feature=
[tf.train.Feature(int64_list=tf.train.Int64List(value=[])])
tf.train.FeatureLists: 它的参数是一个字典,k-v对中 v 的类型是FeatureList。
feature_lists=tf.train.FeatureLists(feature_list={
"k1": tf.train.FeatureList(feature=
[tf.train.Feature(int64_list=tf.train.Int64List(value=[])]),
"k2": tf.train.FeatureList(feature=
[tf.train.Feature(int64_list=tf.train.Int64List(value=v))])
})
我们需要根据我们的数据,找到每一个字段应该映射为 Feature或FeatureList, 多个Feature组成Features,多个FeatureList组成FeatureLists, 然后我们就定义了我们的一个训练数据对应的 Features,FeatureLists, 再将其封装为 tf.train.Example 就可以写入 tfrecords二进制文件了。
tf.train.Example(features=): 传入的features对应一个 tf.train.Features
tf.train.SequenceExample(context=, featurelists=): 传入的context对应一个 tf.train.Features, features_lists对应一个tf.train.FeatureLists
这样就需要选择使用Example还是SequenceExample, SequenceExample多了一个featurelists, 也就是说如果数据中存在字段,我们把它映射为了FeatureList而不是Feature, 那么就要用SequenceExample, 否则用Example。
那么什么样的数据需要映射为FeatureList或Feature?
我的理解是对于长度固定的字段类型,映射为Feature, 比如分类问题中的类别这个字段一般用一个数字表示,二分类就是0或1,那么就class=0映射为tf.train.Feature(tf.train.Int64List(value=[0])), 只要这个字段包含的数据维度是固定的,就可以封装为 Feature。
对于长度不固定的字段类型,映射为FeatureList。比如NLP样本有一个特征是一句话,那么一句话的长度是不固定的,NLP中一般是先分词,然后把每个词对应为该词在字典中的索引,一句话就用一个一维整形数组来表示 [2, 3, 5, 20, …],这个数组的长度是不固定的,我们就映射为
tf.train.FeatureList(feature=[tf.train.Feature(value=[v]) for v in [2, 3, 5, 20,...] ] )
writer = tf.python_io.TFRecordWriter(out_file)
for row in train_data:
record = tf.train.SequenceExample(row) # 将一行数据转换为定义的Example格式
# record = tf.train.Example()
writer.write(record.SerializeToString())