什么时候使用变量而不是图形节点来存储TensorFlow中的中间结果更好?
将张量存储在变量中,而不是依赖于图中的节点,除了变量在图的多次运行中保持并可以共享之外,还有什么优势吗?对于变量和图形节点,资源管理是否更受支持?(摘自@YaroslavBulatov:) 如果需要在图形的开头存储张量以便以后重用:什么时候使用变量而不是图形节点来存储TensorFlow中的中间结果更好?,tensorflow,Tensorflow,将张量存储在变量中,而不是依赖于图中的节点,除了变量在图的多次运行中保持并可以共享之外,还有什么优势吗?对于变量和图形节点,资源管理是否更受支持?(摘自@YaroslavBulatov:) 如果需要在图形的开头存储张量以便以后重用: x | conv1 ------ | | conv2 | | |
x
|
conv1 ------
| |
conv2 |
| |
conv3 |
| loooong dependency
... |
| |
deconv1 |
| |
+ --------
|
res
在这里,您首先计算conv1
,然后在以后计算res
时在图中重用它
事实上,最好的方法是什么都不做,让TensorFlow处理这种长期依赖关系 调用
sess.run(res,feed_dict={x:…})
时,TensorFlow将计算不同的层conv1
,conv2
,…,并存储以后计算res
所需的层(此处conv1
)
我相信这与反向传播的机制是一样的,在反向传播中,TensorFlow需要在内存中保存激活,以便稍后计算梯度。(摘自@YaroslavBulatov:)
如果需要在图形的开头存储张量以便以后重用:
x
|
conv1 ------
| |
conv2 |
| |
conv3 |
| loooong dependency
... |
| |
deconv1 |
| |
+ --------
|
res
在这里,您首先计算conv1
,然后在以后计算res
时在图中重用它
最好的方法是,实际上是不做任何事情,让TensorFlow处理长期依赖 调用
sess.run(res,feed_dict={x:…})
时,TensorFlow将计算不同的层conv1
,conv2
,…,并存储以后计算res
所需的层(此处conv1
)
我相信这与反向传播的机制相同,在反向传播中,TensorFlow需要在内存中保存激活,以便稍后计算梯度。你是说tf.constant node?从性能方面来看,使用变量可能更好。常量节点将数据放入graphdef中,graphdef不是为大尺寸而设计的。有2gb的硬限制。此外,当graphdef需要序列化时(即对于分布式tf),此常量节点将通过protobuf序列化,这可能效率低下,不一定是常量节点。比如说,我想为MLP的每一层存储正向激活,然后我会将激活累积到一个列表
a.append(tf.matmul(a[-1],W)+b)
,然后通过a[l]
访问它们。这里将每个激活张量存储在一个变量中是否有益?a.append(…)
实际上不存储任何激活值,您必须执行sess.run(a[l])
来获取它们,这将执行与sess.run(tf.matmul(a[-1],W)+b)相同的计算。
我知道这一点。我想到的是在同一个图中访问a[l]
的时间要晚得多,我的问题是变量是否会优先于图中很长的顶点(“long”,如果要根据时间绘制图)。如果所有计算都是在一个调用中完成的,不带变量进行所有计算是典型的。这种方式可能会在后端提供更多的优化机会。你是说tf.constant节点?从性能方面来看,使用变量可能更好。常量节点将数据放入graphdef中,graphdef不是为大尺寸而设计的。有2gb的硬限制。此外,当graphdef需要序列化时(即对于分布式tf),此常量节点将通过protobuf序列化,这可能效率低下,不一定是常量节点。比如说,我想为MLP的每一层存储正向激活,然后我会将激活累积到一个列表a.append(tf.matmul(a[-1],W)+b)
,然后通过a[l]
访问它们。这里将每个激活张量存储在一个变量中是否有益?a.append(…)
实际上不存储任何激活值,您必须执行sess.run(a[l])
来获取它们,这将执行与sess.run(tf.matmul(a[-1],W)+b)相同的计算。
我知道这一点。我想到的是在同一个图中访问a[l]
的时间要晚得多,我的问题是变量是否会优先于图中很长的顶点(“long”,如果要根据时间绘制图)。如果所有计算都是在一个调用中完成的,不带变量进行所有计算是典型的。这种方式可能会为后端优化提供更多机会。