2017-05-12 10 views
1

我正在Python中while循環中訓練神經網絡,該循環一直持續到達到某個停止條件。我注意到,當我訓練我的網絡,我可以看到「鋸齒」 /波浪狀的內存使用模式,如:Tensorflow在訓練循環迭代期間鋸齒內存使用情況

sawtooth memory usage pattern

我已經成功地重現此使用比非常簡單的例子我的生產模式。顯然這有點不同,因爲我不更新參數,但我相信它複製了我所看到的行爲。

import tensorflow as tf 
import numpy as np 

def main(x_vals): 
    x = tf.placeholder(tf.float32, [500, 1000, 1000]) 

    rs = tf.reduce_sum(x) 

    sess = tf.Session() 

    v = sess.run(rs, feed_dict={x:x_vals}) 
    print(v) 


if __name__ == "__main__": 
    x_vals = np.random.rand(500, 1000, 1000) 
    while True: 
     main(x_vals) 

鋸齒的大小似乎與輸入數據的大小大致成比例。可以理解的是,每循環迭代似乎有一個循環。

這裏發生了什麼? Tensorflow會複製每次會話評估的所有數據嗎?這本身並不是一個問題,但是如果我可以避免複製每次訓練循環迭代中的數據(因爲我的整個數據集都適合內存),我想這樣做,因爲我認爲分配非常昂貴。我是否偏離了某個地方的最佳實踐?

回答

2

使用feed_dict通常會複製數據。最近加入有新的功能,將避免拷貝,但你必須確保你的數據是字對齊,請參閱
https://github.com/tensorflow/tensorflow/issues/9690

+0

謝謝,這證實了我的懷疑。你會推薦什麼替代方法來使用feed_dicts? –

+0

如果您已經在使用feed_dict,那麼對齊上述問題中的數據可能會最簡單。否則,你可以重寫你的數據管道是純粹的TensorFlow(即,使用TensorFlow操作直接從文件讀取) –

+0

一個後續行動:你知道是否有可能使用tensor.proto(來自核心/框架/張量.proto)而不是example.proto將我的數據存儲爲.tfrecord?我現在使用tensorflow服務的張量原型,因此採用我的模型可以更容易地使用該協議緩衝區作爲數據插座。 –

0

我想後調查後的幾天的後續討論。 @雅羅斯拉夫指出我的方向是正確的,但是完整的答案有一點點顏色。

可以通過使用預加載的變量(如果數據集適合內存)試圖避免feed_dict來限制每個會話中的一些內存分配量。但是,也有一些動態分配由優化計算圖表完成,可能是爲了存儲梯度。

我已經包含了演示這個的代碼。下面是內存使用的一個片段。左側重複調用預加載函數,右側則重複調用loaded_each_iteration。

enter image description here

import tensorflow as tf 
import numpy as np 

A_shape = [100000, 3000] 
b_shape = [100000, 1] 

x_shape = [3000, 1] 

def loaded_each_iteration(A_vals): 
    A = tf.placeholder(tf.float32, A_shape) 

    b = tf.constant(np.random.rand(*b_shape), name='b', dtype=tf.float32) 

    x = tf.Variable(np.zeros(x_shape, dtype=np.float32), name='x') 
    diff = tf.matmul(A, x) - b 
    cost = tf.nn.l2_loss(diff) 

    train_op = tf.train.AdagradOptimizer(0.00001).minimize(cost, var_list=[x]) 

    sess = tf.Session() 

    sess.run(x.initializer) 
    sess.run(tf.global_variables_initializer()) 
    while True: 
     _, c = sess.run([train_op, cost], feed_dict={A:A_vals}) 
     print(c) 


def preloaded(A_vals): 
    A_init = tf.placeholder(tf.float32, A_shape) 
    A = tf.Variable(A_init, trainable=False, collections=[], name='A', dtype=tf.float32) 

    b = tf.constant(np.random.rand(*b_shape), name='b', dtype=tf.float32) 

    x = tf.Variable(np.zeros(x_shape, dtype=np.float32), name='x') 
    diff = tf.matmul(A, x) - b 
    cost = tf.nn.l2_loss(diff) 

    train_op = tf.train.AdagradOptimizer(0.00001).minimize(cost, var_list=[x]) 

    sess = tf.Session() 

    sess.run([A.initializer, x.initializer], feed_dict={A_init:A_vals}) 
    sess.run(tf.global_variables_initializer()) 
    while True: 
     _, c = sess.run([train_op, cost]) 
     print(c) 


if __name__ == "__main__": 
    A_vals = np.random.rand(*A_shape) 
    while True: 
     loaded_each_iteration(A_vals)