如何在TensorFlow中处理大量数据?

17
对于我的项目,我有大量的数据,大约60GB分散在npy文件中,每个文件大小约为1GB,每个文件包含约750k条记录和标签。每个记录是345个float32,而标签是5个float32。
我阅读了tensorflow数据集文档和队列/线程文档,但我无法确定如何最好地处理训练输入,以及如何保存未来预测的模型和权重。
我的模型非常简单,它看起来像这样:
x = tf.placeholder(tf.float32, [None, 345], name='x')
y = tf.placeholder(tf.float32, [None, 5], name='y')
wi, bi = weight_and_bias(345, 2048)
hidden_fc = tf.nn.sigmoid(tf.matmul(x, wi) + bi)
wo, bo = weight_and_bias(2048, 5)
out_fc = tf.nn.sigmoid(tf.matmul(hidden_fc, wo) + bo)
loss = tf.reduce_mean(tf.squared_difference(y, out_fc))
train_op = tf.train.AdamOptimizer().minimize(loss)
我训练神经网络的方式是以随机顺序逐个读取文件,然后使用打乱后的numpy数组来索引每个文件,并手动创建每个批次以使用feed_dict喂给train_op。从我阅读的所有内容来看,这种方法非常低效,应该用数据集或队列和线程来替换,但正如我所说,文档没有帮助。那么,处理大量数据的最佳方式是什么呢?此外,作为参考,我的数据保存在一个numpy文件中,需要进行两个操作步骤。
with open('datafile1.npy', 'wb') as fp:
    np.save(data, fp)
    np.save(labels, fp)

这可能正是您正在寻找的:导入数据(使用Dataset API) - kww
使用大型数据集时,不应一次性传递所有数据。使用小批量数据来克服这个问题。但更重要的是,一开始不要将所有数据都加载到内存中。使用小批量数据。 - ParmuTownley
Karhy,我确实阅读了数据集文档,但其中大部分似乎都假定数据已经预加载到内存中。Paramdeep,我正在使用小批量,这只是我从numpy文件中加载数据的方法,然后稍后我会洗牌数据并手动制作小批量来填充x和y占位符。这就是我试图找出更有效的解决方案的原因。 - Joao Paulo Farias
1个回答

13

针对npy文件的实用程序确实会将整个数组分配到内存中。我建议您将所有numpy数组转换为TFRecords格式,并在训练中使用这些文件。这是在TensorFlow中读取大型数据集的最有效方法之一。

转换为TFRecords

def array_to_tfrecords(X, y, output_file):
  feature = {
    'X': tf.train.Feature(float_list=tf.train.FloatList(value=X.flatten())),
    'y': tf.train.Feature(float_list=tf.train.FloatList(value=y.flatten()))
  }
  example = tf.train.Example(features=tf.train.Features(feature=feature))
  serialized = example.SerializeToString()

  writer = tf.python_io.TFRecordWriter(output_file)
  writer.write(serialized)
  writer.close()

这里可以找到一个处理图像的完整示例:点击这里

阅读TFRecordDataset

def parse_proto(example_proto):
  features = {
    'X': tf.FixedLenFeature((345,), tf.float32),
    'y': tf.FixedLenFeature((5,), tf.float32),
  }
  parsed_features = tf.parse_single_example(example_proto, features)
  return parsed_features['X'], parsed_features['y']

def read_tfrecords(file_names=("file1.tfrecord", "file2.tfrecord", "file3.tfrecord"),
                   buffer_size=10000,
                   batch_size=100):
  dataset = tf.contrib.data.TFRecordDataset(file_names)
  dataset = dataset.map(parse_proto)
  dataset = dataset.shuffle(buffer_size)
  dataset = dataset.repeat()
  dataset = dataset.batch(batch_size)
  return tf.contrib.data.Iterator.from_structure(dataset.output_types, dataset.output_shapes)

数据手册可以在这里找到


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接