2016-08-03 5 views
2

私は、複雑なネットワークの不自然なバージョンを持っている:なぜこのテンソルフローループはあまりにも多くのメモリを必要としますか?

import tensorflow as tf 

a = tf.ones([1000]) 
b = tf.ones([1000]) 

for i in range(int(1e6)): 
    a = a * b 

私の直感では、これは非常に少ないメモリを必要とすべきであるということです。最初の配列割り振りのためのスペースと、ノードを利用し、各ステップでテンソル 'a'に格納されたメモリーを上書きするコマンドのストリング。しかし、メモリ使用量は非常に急速に増加します。

何が起こっているのですか?テンソルを計算して複数回上書きすると、メモリ使用量を減らす方法はありますか?

編集:ヤロスラフの提案に

おかげソリューションは、グラフ上のノードの数を最小限に抑えるためにWHILE_LOOPを使用してあることが判明しました。これは素晴らしく、はるかに速く、はるかに少ないメモリしか必要とせず、すべてグラフに含まれています。

import tensorflow as tf 

a = tf.ones([1000]) 
b = tf.ones([1000]) 

cond = lambda _i, _1, _2: tf.less(_i, int(1e6)) 
body = lambda _i, _a, _b: [tf.add(_i, 1), _a * _b, _b] 

i = tf.constant(0) 
output = tf.while_loop(cond, body, [i, a, b]) 

with tf.Session() as sess: 
    result = sess.run(output) 
    print(result) 

答えて

6

あなたa*bコマンドはtf.mul(a, b, g=tf.get_default_graph())と同等ですtf.mul(a, b)、に変換されます。このコマンドは現在のGraphオブジェクトにMulノードを追加するので、現在のグラフにノード数1万Mulを追加しようとしています。また、2GBを超えるGraphオブジェクトをシリアル化できないため、このような大きなグラフを扱うと失敗する可能性のあるチェックがいくつかあります。

私はProgramming Models for Deep LearningをMXNetの人々によって読むことをお勧めします。 TensorFlowは用語で「象徴的」なプログラミングであり、あなたはそれを絶対的なものとして扱っています。

はアップデートあなたは、Python <を避けるために tf.Variableオブジェクトと var.assignを使用することができ、より効率のために

mul_op = a*b 
result = sess.run(a) 
for i in range(int(1e6)): 
    result = sess.run(mul_op, feed_dict={a: result}) 

を養うためにfeed_dictを使用して、あなたは一度乗算オペアンプを構築し、それを繰り返し実行することができますPythonのループを使用して欲しいものを得るために、 - > TensorFlowデータ転送

+0

意味があります。私は一度sess.runを呼び出すだけで、大きなグラフをバックプロンプトしているので、入力から出力へのすべての計算を1つのステップで処理したいと思います。余分なノードを追加せずにこのループをグラフ内で行うことは可能ですか? – jstaker7

+0

'tf.Variable'オブジェクトの* bに入力を保存すると、それは依存関係を分離するので、グラフ内の他のものを評価することなくそのノードで何百万回も' sess.run'を実行できます –

+0

分かりません私は理解している。 'b'はバックプロップ中に更新される訓練可能なウェイト行列であるとしましょう。 sess.runを複数回呼び出すと、複数のsess.run呼び出しに対して追加のオーバーヘッドが発生するだけでなく、その計算がグラディエント計算から切り離され、正しく更新されるようにするためにいくつかの面倒な作業が必要になります。これらの仮定は正しいのでしょうか?私は、これをグラフで処理するより良い方法があると思う。 – jstaker7

関連する問題