我试图理解"正确的"用于张量流摄取的大数据集的存储方法。文档似乎相对清楚,无论如何,tfrecord文件是首选。 Large是一个主观测量,但下面的示例是sklearn.datasets.make_regression()中10,000行和1到5,000个特征的随机生成的回归数据集,全部为float64。
我尝试了两种不同的方法来编写具有截然不同性能的tfrecord文件。
对于numpy数组,X
,y
(X.shape =(10000,n_features),y.shape =(10000,)
tf.train.Example
tf.train.Features
我以tensorflow开发人员似乎更喜欢的方式构造一个tf.train.Example,至少通过https://github.com/tensorflow/tensorflow/blob/master/tensorflow/examples/how_tos/reading_data/convert_to_records.py处的tensorflow示例代码来判断。
对于X
中的每个观察或行,我创建了一个字典,其中包含功能名称(f_0,f_1,...),其值为tf.train.Feature
个具有该功能的观察数据的对象作为其float_list的单个元素。
def _feature_dict_from_row(row):
"""
Take row of length n+1 from 2-D ndarray and convert it to a dictionary of
float features:
{
'f_0': row[0],
'f_1': row[1],
...
'f_n': row[n]
}
"""
def _float64_feature(feature):
return tf.train.Feature(float_list=tf.train.FloatList(value=[feature]))
features = { "f_{:d}".format(i): _float64_feature(value) for i, value in enumerate(row) }
return features
def write_regression_data_to_tfrecord(X, y, filename):
with tf.python_io.TFRecordWriter('{:s}'.format(filename)) as tfwriter:
for row_index in range(X.shape[0]):
features = _feature_dict_from_row(X[row_index])
features['label'] = y[row_index]
example = tf.train.Example(features=tf.train.Features(feature=features))
tfwriter.write(example.SerializeToString())
tf.train.Example
包含一个包含所有功能的大tf.train.Feature
我构建了一个包含一个特征的字典(实际上是两个计算标签),其值为tf.train.Feature
,整个要素行为float_list
def write_regression_data_to_tfrecord(X, y, filename, store_by_rows=True):
with tf.python_io.TFRecordWriter('{:s}'.format(filename)) as tfwriter:
for row_index in range(X.shape[0]):
features = { 'f_0': tf.train.Feature(float_list=tf.train.FloatList(value=X[row_index])) }
features['label'] = y[row_index]
example = tf.train.Example(features=tf.train.Features(feature=features))
tfwriter.write(example.SerializeToString())
随着数据集中要素数量的增加,第二个选项的速度明显快于第一个选项,如下图所示。 请注意日志比例
10,000行:
对我来说,直观地认为创建5,000个tf.train.Feature
对象比创建一个具有5,000个元素的float_list的对象要慢得多,但它并不清楚这是"意图&# 34;将大量特征输入张量流模型的方法。
以更快的方式做这件事本身有什么不妥吗?