在连接的张量流图中初始化变量
Initializing variables in joined tensorflow graphs
我正在尝试将单独图表上的多个 Tensorflow 模型连接到单个图表上的单个模型(我想象典型的场景是需要冻结的迁移学习模型、集成等)。
我可以使用 tf.import_graph_def 连接两个图。但是,当其中一个原始图包含变量时,我无法在新图上将值注入其中。分配操作作为图表的一部分被复制,如果我手动 运行 这些操作,我会得到预期的结果。 (取消注释第四个 with graph...
块中的 sess.run
-调用)
import tensorflow as tf
graph1 = tf.Graph()
with graph1.as_default():
with tf.Session(graph=graph1) as sess:
var1 = tf.Variable([1, 1, 1], name='var1')
tensor1 = tf.multiply(var1, 2, name='tensor1')
graph2 = tf.Graph()
with graph2.as_default():
with tf.Session(graph=graph2) as sess:
placeholder = tf.placeholder(tf.int32, [3], name='placeholder')
tensor2 = tf.multiply(placeholder, 2, name='tensor2')
graph3 = tf.Graph()
with graph3.as_default():
with tf.Session(graph=graph3) as sess:
graph1out, = tf.import_graph_def(graph1.as_graph_def(), name='graph1', return_elements=['tensor1:0'])
tf.import_graph_def(graph2.as_graph_def(), name='graph2', input_map={'placeholder:0': graph1out})
with graph3.as_default():
with tf.Session(graph=graph3) as sess:
sess.run(tf.global_variables_initializer())
#sess.run(graph3.get_tensor_by_name('graph1/var1/Assign:0'))
tensor = graph3.get_tensor_by_name('graph2/tensor2:0')
result = sess.run(tensor)
运行 这个片段按原样产生:
FailedPreconditionError (see above for traceback): Attempting to use uninitialized value graph1/var1
手动运行分配操作是一种非常小的通用方法,将其作为通用函数的一部分编写起来会很麻烦。它还要求每次我重新初始化与图形的会话时进行这些分配调用。
有更通用的方法吗?例如,通过基于旧变量创建新变量并将它们锁定到现有结构?
如果没有,是否有包装分配调用的方法?所以至少我可以 运行 一个单一的通用初始化操作,而不是针对每种情况的未知数量的特定初始化操作?
通过创建 init-wrapper 解决了这个问题。对于名称以 'Apply:(int)' 结尾的所有张量,我使用 tf.reduce_sum(以标准化它们的形状)并将它们塞入 tf.stack。此 init 操作在内部被视为 noop,但它确保传递给它的每个张量都是 运行(因此也初始化了它们对应的变量)。从语义上讲,它可以被视为 tf.global_variables_initializer().
不是最优雅的解决方案,但它目前适用于我的用例。
我正在尝试将单独图表上的多个 Tensorflow 模型连接到单个图表上的单个模型(我想象典型的场景是需要冻结的迁移学习模型、集成等)。
我可以使用 tf.import_graph_def 连接两个图。但是,当其中一个原始图包含变量时,我无法在新图上将值注入其中。分配操作作为图表的一部分被复制,如果我手动 运行 这些操作,我会得到预期的结果。 (取消注释第四个 with graph...
块中的 sess.run
-调用)
import tensorflow as tf
graph1 = tf.Graph()
with graph1.as_default():
with tf.Session(graph=graph1) as sess:
var1 = tf.Variable([1, 1, 1], name='var1')
tensor1 = tf.multiply(var1, 2, name='tensor1')
graph2 = tf.Graph()
with graph2.as_default():
with tf.Session(graph=graph2) as sess:
placeholder = tf.placeholder(tf.int32, [3], name='placeholder')
tensor2 = tf.multiply(placeholder, 2, name='tensor2')
graph3 = tf.Graph()
with graph3.as_default():
with tf.Session(graph=graph3) as sess:
graph1out, = tf.import_graph_def(graph1.as_graph_def(), name='graph1', return_elements=['tensor1:0'])
tf.import_graph_def(graph2.as_graph_def(), name='graph2', input_map={'placeholder:0': graph1out})
with graph3.as_default():
with tf.Session(graph=graph3) as sess:
sess.run(tf.global_variables_initializer())
#sess.run(graph3.get_tensor_by_name('graph1/var1/Assign:0'))
tensor = graph3.get_tensor_by_name('graph2/tensor2:0')
result = sess.run(tensor)
运行 这个片段按原样产生:
FailedPreconditionError (see above for traceback): Attempting to use uninitialized value graph1/var1
手动运行分配操作是一种非常小的通用方法,将其作为通用函数的一部分编写起来会很麻烦。它还要求每次我重新初始化与图形的会话时进行这些分配调用。
有更通用的方法吗?例如,通过基于旧变量创建新变量并将它们锁定到现有结构?
如果没有,是否有包装分配调用的方法?所以至少我可以 运行 一个单一的通用初始化操作,而不是针对每种情况的未知数量的特定初始化操作?
通过创建 init-wrapper 解决了这个问题。对于名称以 'Apply:(int)' 结尾的所有张量,我使用 tf.reduce_sum(以标准化它们的形状)并将它们塞入 tf.stack。此 init 操作在内部被视为 noop,但它确保传递给它的每个张量都是 运行(因此也初始化了它们对应的变量)。从语义上讲,它可以被视为 tf.global_variables_initializer().
不是最优雅的解决方案,但它目前适用于我的用例。