在训练期间,Tensorflow加载数据随机减慢

时间:2017-03-03 12:41:46

标签: tensorflow

我已将所有训练数据加载到内存中,只占总内存的7%。以下框架用于训练模型:

# build graph
......
# data producer
class DataProducer(object):
  # a single feature has multiple labels and is needed to be trained separately for each label
  # in order to not copy the features multiple times, I use the self.ft_idxs to index the relationships between features and labels
  def yield_trn_batch(self, batch_size):
    for i in xrange(0, self.num_data, batch_size):
      fts = self.fts[self.ft_idxs[self.shuffled_idxs[i: i+batch_size]]
      labels = self.labels[self.shuffled_idxs[i: i+batch_size]]
      yield fts, labels

# training
for feature, label in data.yield_trn_batch(batch_size):
  sess.run(model.train_op, feed_dict={model.feature: feature, model.label: label})

但是,当特征的维度很高时,训练过程会随机减慢。 诊断如下:

  1. 图表是预定义的,tensorflow slow performance中不是这种情况。
  2. sess.run()的实际运行时间是稳定的,以下是培训批次的时间表,这似乎正常。 timeline of a training batch
  3. 缓慢的部分发生在data.yield_trn_batch()中。在开始时,加载一个小批量需要0.01s,但是在几个epoches之后它变得不稳定,有时需要1s才能加载一个小批量。但是,当我评论sess.run()并纯粹运行data.yield_trn_batch()时,它正常。我不使用队列,因此可能不是dequeue many operation very slow中的情况。
  4. 我猜图运行过程已经影响了数据加载,但不知道为什么以及如何解决这个问题(可能使用另一个线程来加载数据?)。任何人都可以解决这个问题吗?

1 个答案:

答案 0 :(得分:1)

根据我们在评论中的对话,似乎减速是由于分配大量NumPy阵列导致的内存压力。虽然NumPy数组在不再使用时可以正确地进行垃圾收集,但默认的malloc()实现不会重用它们,并逐渐增加堆的大小(以及进程的虚拟大小),方法是调用brk()系统调用。

一种解决方法是切换分配器库,它可以修复地址空间泄漏:对TensorFlow进程使用tcmalloc分配器而不是默认malloc()tcmalloc中的分配策略更适合重复分配和回收相同大小的缓冲区,并且不需要随着时间的推移增加磁头大小,这样可以提高性能。