2017-03-03 89 views
0

我已經將所有訓練數據加載到內存中,只佔內存總量的7%。並且以下框架用於訓練模型:Tensorflow加載數據在訓練過程中隨機放慢

# 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.01秒,但是在幾個時間段之後,它變得不穩定並且有時花費超過1秒來加載小批量。但是,當我評論sess.run()並純粹運行data.yield_trn_batch()時,它正常運行速度很快。我不使用隊列,因此它可能不是dequeue many operation very slow中的情況。

我猜想圖運行過程已經影響了數據加載,但不知道爲什麼以及如何解決這個問題(也許使用另一個線程來加載數據?)。任何人都可以解決這個問題嗎?

+0

我想我們需要更多的細節來解決這個問題。你的Python進程是否消耗大量內存?你能分享'data.yield_trn_batch(batch_size)'的代碼嗎?如果你反覆餵食同一批次,它是否仍然放慢速度? – mrry

+0

我更新了代碼和內存使用情況。當我餵食同一批次時,幾個時代後速度似乎不會增長。數據收益代碼是否有問題? –

+0

我的猜測是,你正在產生的數組片是Python使用的內存分配器的一個尷尬的大小,並且每個批次都在增加堆的大小(本身不是內存泄漏,但釋放的內存不會是按照你的希望重用)。你可以嘗試使用'tcmalloc'如[本文檔]中所述(http://stackoverflow.com/documentation/tensorflow/3883/how-to-debug-a-memory-leak-in-tensorflow/13427/use-the -tcmalloc分配器#噸= 20170304002146036458)? – mrry

回答

1

根據我們在評論中的對話,看起來減速是由於分配大量NumPy陣列造成的內存壓力。雖然NumPy陣列在不再使用時會被正確垃圾收集,但默認的malloc()實現將不會重用它們,並通過調用brk()系統調用逐漸增加堆的大小(以及進程的虛擬大小)。

一種解決方法是切換分配器庫,它可以修復地址空間泄漏:使用tcmalloc分配器而不是默認malloc()爲您的TensorFlow進程。 tcmalloc中的分配策略更適合於重複分配和回收相同大小的緩衝區,並且不需要隨時間增加頭的大小,這應該會導致更好的性能。