Memory management 为什么这个tensorflow循环需要这么多内存?

Memory management 为什么这个tensorflow循环需要这么多内存?,memory-management,tensorflow,Memory Management,Tensorflow,我有一个复杂网络的人为版本: import tensorflow as tf a = tf.ones([1000]) b = tf.ones([1000]) for i in range(int(1e6)): a = a * b 我的直觉是这需要很少的记忆。只有用于初始数组分配的空间和一系列命令,这些命令利用节点并在每一步覆盖存储在张量“a”中的内存。但是内存使用增长相当快 这里发生了什么,当我计算张量并多次覆盖它时,如何减少内存使用 编辑: 多亏了Yaroslav的建议,最终的解

我有一个复杂网络的人为版本:

import tensorflow as tf

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

for i in range(int(1e6)):
    a = a * b
我的直觉是这需要很少的记忆。只有用于初始数组分配的空间和一系列命令,这些命令利用节点并在每一步覆盖存储在张量“a”中的内存。但是内存使用增长相当快

这里发生了什么,当我计算张量并多次覆盖它时,如何减少内存使用

编辑:

多亏了Yaroslav的建议,最终的解决方案是使用while_循环来最小化图上的节点数。这非常有效,速度更快,需要的内存更少,并且都包含在图形中

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)

您的
a*b
命令转换为
tf.mul(a,b)
,这相当于
tf.mul(a,b,g=tf.get\u default\u graph())
。此命令将一个
Mul
节点添加到当前的
Graph
对象中,因此您正试图将100万
Mul
节点添加到当前的图形中。这也是一个问题,因为您无法序列化大于2GB的图形对象,所以在处理如此大的图形时,有些检查可能会失败

我推荐MXNet的人阅读。TensorFlow在其术语中是“符号”编程,您将其视为命令

要使用Python循环获得所需的内容,可以构造一次乘法运算,然后重复运行,使用
feed\u dict
提供更新

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

为了提高效率,您可以使用
tf.Variable
对象和
var.assign
来避免PythonTensorFlow数据传输。不过,我只想调用sess.run一次,并在一个步骤中处理从输入到输出的所有计算,因为我正在回溯一个大型图形。是否可以在不添加额外节点的情况下在图形中执行此循环?如果您将输入保存到
tf.Variable
对象中的a*b,您将隔离它的依赖项,这样您就可以在该节点上执行
sess.run
一百万次,而不必计算图形中的任何其他内容。我不确定是否理解。假设“b”是一个可训练的重量矩阵,在后支撑期间更新。如果我多次调用sess.run,不仅会为多个sess.run调用带来额外的开销,还会将该计算与渐变计算断开连接,并且需要做一些繁琐的工作以确保它得到正确更新。这些假设正确吗?我想我希望有更好的方法来处理这个in-graph.oversession.run调用的开销约为80 usec,因此一百万个调用将有80秒的开销。如果你想把它保持在一个。运行调用,也有TensorFlow