是否可以修改现有的 TensorFlow 计算图?
Is it possible to modify an existing TensorFlow computation graph?
TensorFlow 图通常是从输入到输出逐步构建,然后执行。查看 Python 代码,操作的输入列表是不可变的,这表明不应修改输入。这是否意味着无法 update/modify 现有图表?
TensorFlow tf.Graph
class is an append-only data structure, which means that you can add nodes to the graph after executing part of the graph, but you cannot remove or modify existing nodes. Since TensorFlow executes only the necessary subgraph when you call Session.run()
,在图中有冗余节点没有执行时间成本(尽管它们会继续消耗内存)。
要删除图表中的所有 个节点,您可以使用新图表创建一个会话:
with tf.Graph().as_default(): # Create a new graph, and make it the default.
with tf.Session() as sess: # `sess` will use the new, currently empty, graph.
# Build graph and execute nodes in here.
是的,tf.Graph
是按照@mrry 所说的仅附加方式构建的。
但有解决方法:
从概念上讲,您可以通过克隆现有图形来修改它,并在此过程中执行所需的修改。从 r1.1 开始,Tensorflow 提供了一个名为 tf.contrib.graph_editor
的模块,它将上述想法实现为一组方便的函数。
除了@zaxily 和@mrry 所说的之外,我还想提供一个示例,说明如何实际对图形进行修改。简而言之:
- 不能修改现有的操作,所有操作都是最终的且不可变的
- 可以复制一个 op,修改它的输入或属性,然后将新的 op 添加回图中
- 必须重新创建依赖于 new/copied 操作的所有下游操作。是的,图表的重要部分将被复制复制,这不是问题
代码:
import tensorflow
import copy
import tensorflow.contrib.graph_editor as ge
from copy import deepcopy
a = tf.constant(1)
b = tf.constant(2)
c = a+b
def modify(t):
# illustrate operation copy&modification
new_t = deepcopy(t.op.node_def)
new_t.name = new_t.name+"_but_awesome"
new_t = tf.Operation(new_t, tf.get_default_graph())
# we got a tensor, let's return a tensor
return new_t.outputs[0]
def update_existing(target, updated):
# illustrate how to use new op
related_ops = ge.get_backward_walk_ops(target, stop_at_ts=updated.keys(), inclusive=True)
new_ops, mapping = ge.copy_with_input_replacements(related_ops, updated)
new_op = mapping._transformed_ops[target.op]
return new_op.outputs[0]
new_a = modify(a)
new_b = modify(b)
injection = new_a+39 # illustrate how to add another op to the graph
new_c = update_existing(c, {a:injection, b:new_b})
with tf.Session():
print(c.eval()) # -> 3
print(new_c.eval()) # -> 42
对于tensorflow v>=2.6,直接使用Graphhave been depcreated
A tf.Graph can be constructed and used directly without a tf.function, as was required in TensorFlow 1, but this is deprecated and it is recommended to use a tf.function instead. If a graph is directly used, other deprecated TensorFlow 1 classes are also required to execute the graph, such as a tf.compat.v1.Session.
话虽如此,我认为您的问题仍然相关,我认为使用 tensorflow eager execution 可能会解决您面临的问题。 运行在 eager 模式下使用 tf 时,您可以 运行,在构建之前修改图表,在构建之前测试它...
TensorFlow's eager execution is an imperative programming environment that evaluates operations immediately, without building graphs: operations return concrete values instead of constructing a computational graph to run later. This makes it easy to get started with TensorFlow and debug models, and it reduces boilerplate as well. To follow along with this guide, run the code samples below in an interactive python interpreter.
但是要小心急切模式交易 debugging/flexbillity 和 performance/speed,所以对于生产你可以考虑转向关了。
最后,tensorflow 的另一个特性可能与此问题相关,即 tensor slicing、tf.slice
。
TensorFlow 图通常是从输入到输出逐步构建,然后执行。查看 Python 代码,操作的输入列表是不可变的,这表明不应修改输入。这是否意味着无法 update/modify 现有图表?
TensorFlow tf.Graph
class is an append-only data structure, which means that you can add nodes to the graph after executing part of the graph, but you cannot remove or modify existing nodes. Since TensorFlow executes only the necessary subgraph when you call Session.run()
,在图中有冗余节点没有执行时间成本(尽管它们会继续消耗内存)。
要删除图表中的所有 个节点,您可以使用新图表创建一个会话:
with tf.Graph().as_default(): # Create a new graph, and make it the default.
with tf.Session() as sess: # `sess` will use the new, currently empty, graph.
# Build graph and execute nodes in here.
是的,tf.Graph
是按照@mrry 所说的仅附加方式构建的。
但有解决方法:
从概念上讲,您可以通过克隆现有图形来修改它,并在此过程中执行所需的修改。从 r1.1 开始,Tensorflow 提供了一个名为 tf.contrib.graph_editor
的模块,它将上述想法实现为一组方便的函数。
除了@zaxily 和@mrry 所说的之外,我还想提供一个示例,说明如何实际对图形进行修改。简而言之:
- 不能修改现有的操作,所有操作都是最终的且不可变的
- 可以复制一个 op,修改它的输入或属性,然后将新的 op 添加回图中
- 必须重新创建依赖于 new/copied 操作的所有下游操作。是的,图表的重要部分将被复制复制,这不是问题
代码:
import tensorflow
import copy
import tensorflow.contrib.graph_editor as ge
from copy import deepcopy
a = tf.constant(1)
b = tf.constant(2)
c = a+b
def modify(t):
# illustrate operation copy&modification
new_t = deepcopy(t.op.node_def)
new_t.name = new_t.name+"_but_awesome"
new_t = tf.Operation(new_t, tf.get_default_graph())
# we got a tensor, let's return a tensor
return new_t.outputs[0]
def update_existing(target, updated):
# illustrate how to use new op
related_ops = ge.get_backward_walk_ops(target, stop_at_ts=updated.keys(), inclusive=True)
new_ops, mapping = ge.copy_with_input_replacements(related_ops, updated)
new_op = mapping._transformed_ops[target.op]
return new_op.outputs[0]
new_a = modify(a)
new_b = modify(b)
injection = new_a+39 # illustrate how to add another op to the graph
new_c = update_existing(c, {a:injection, b:new_b})
with tf.Session():
print(c.eval()) # -> 3
print(new_c.eval()) # -> 42
对于tensorflow v>=2.6,直接使用Graphhave been depcreated
A tf.Graph can be constructed and used directly without a tf.function, as was required in TensorFlow 1, but this is deprecated and it is recommended to use a tf.function instead. If a graph is directly used, other deprecated TensorFlow 1 classes are also required to execute the graph, such as a tf.compat.v1.Session.
话虽如此,我认为您的问题仍然相关,我认为使用 tensorflow eager execution 可能会解决您面临的问题。 运行在 eager 模式下使用 tf 时,您可以 运行,在构建之前修改图表,在构建之前测试它...
TensorFlow's eager execution is an imperative programming environment that evaluates operations immediately, without building graphs: operations return concrete values instead of constructing a computational graph to run later. This makes it easy to get started with TensorFlow and debug models, and it reduces boilerplate as well. To follow along with this guide, run the code samples below in an interactive python interpreter.
但是要小心急切模式交易 debugging/flexbillity 和 performance/speed,所以对于生产你可以考虑转向关了。
最后,tensorflow 的另一个特性可能与此问题相关,即 tensor slicing、tf.slice
。