Python Tensorflow:将导入的图形操作应用于2d tensor的每个元素

Python Tensorflow:将导入的图形操作应用于2d tensor的每个元素,python,tensorflow,Python,Tensorflow,有一些问题回答了我的部分问题,但我无法将这些问题联系起来。 假设我有一个只在2个元素的1d数组上运行的图 input = tf.placeholder(tf.float32, [2], name="input") 我想构建一个可以接收任意长2d数组的图,并在上面运行第一个图 x = tf.placeholder(tf.float32, [None, 2], name = 'x') 我知道如何导入第一个图形(tf.import\u graph\u def),以及如何使用tf.map\u fn

有一些问题回答了我的部分问题,但我无法将这些问题联系起来。 假设我有一个只在2个元素的1d数组上运行的图

input = tf.placeholder(tf.float32, [2], name="input")
我想构建一个可以接收任意长2d数组的图,并在上面运行第一个图

 x = tf.placeholder(tf.float32, [None, 2], name = 'x')
我知道如何导入第一个图形(tf.import\u graph\u def),以及如何使用
tf.map\u fn
在数组上运行一些操作。但是我怎样才能把两者结合起来呢? 对于网络的每次运行,我都需要传递不同的输入。但是映射是在tf.import_graph_def内完成的。我应该每次在循环中调用的函数中进行导入吗?听起来不对

下面的代码有效,但我相信有更好的方法:

with tf.Graph().as_default() as g_1:
input = tf.placeholder(tf.float32, [2], name="input")
y = tf.add(input[0], input[1])
output = tf.identity(y, name="output")

gdef_1 = g_1.as_graph_def()

tf.reset_default_graph()
with tf.Graph().as_default() as g_combined:
    x = tf.placeholder(tf.float32, [None, 2], name = 'x')

    def calc_z(el):
        y, = tf.import_graph_def(gdef_1, input_map={"input:0": el},
                               return_elements=["output:0"])
        return y

    final_result = tf.map_fn(calc_z, x)

    init = tf.global_variables_initializer()

with tf.Session(graph=g_combined) as sess:
    # For tensorboard
    # run it as tensorboard --logdir=graphs
    writer = tf.summary.FileWriter('./graphs', sess.graph)
    # Run the initializer
    sess.run(init)
    print(sess.run([final_result], feed_dict = {x:[[1,2],[3,4],[5,6]]}))
    writer.close()
更新:我试图获得相同的结果,但保持导入的图形可训练,但没有做到。
import\u meta\u graph
的return\u elements参数似乎被忽略,只返回了saver。然后调用restore失败,并出现错误

不能输入张量张量(“map/while/save/Const:0”,shape=(),dtype=string) 我正在使用下面的代码:


您当前的解决方案实际上已经很好了。当构建
g_combined
时,图形仅导入一次,而不是在
x
中的每个元素导入一次,因此它会执行您想要的操作

如果您有一个元图,它应该与类似,因为
input\u map
return\u elements
也应该与它一起使用(注意,此函数也会返回导入的保护程序)。但是,您也可以将元图导入另一个图中,将其冻结(例如使用),然后将该图def导入到最终的图中

import tensorflow as tf

meta_graph_path = ...
meta_graph_save_path = ...
with tf.Graph().as_default() as g_meta_import, tf.Session() as sess:
    saver = tf.train.import_meta_graph(meta_graph_path)
    saver.restore(sess, meta_graph_save_path)
    frozen_graph = tf.graph_util.convert_variables_to_constants(
        sess, tf.get_default_graph().as_graph_def(), 'output')

with tf.Graph().as_default() as g_combined:
    x = tf.placeholder(tf.float32, [None, 2], name = 'x')
    def calc_z(el):
        y, = tf.import_graph_def(frozen_graph, input_map={'input:0': el},
                                 return_elements=['output:0'])
        return y
    final_result = tf.map_fn(calc_z, x)
    init = tf.global_variables_initializer()

此解决方案的唯一缺点是,导入的零件显然将被冻结,无法进行培训。

我认为您当前的代码非常好。在
x
中,每个元素不会重新导入图形一次,
calc\u z
实际上只调用一次,
gdef\u 1
导入一次,并在
g\u combined
中连接,因此
tf.map\u fn
中的每次迭代都使用导入的图形。请注意,
tf.import\u graph\u def
实际上并不是图形操作中的TensorFlow。谢谢!实际上,我的问题涉及一个元图,它是预先训练的。我试图在map函数中调用import\u meta\u graph,但这不起作用。我该怎么办?(可能会发布一个单独的问题?)这是另一种情况,但在查看源代码时,我认为应该是一样的(不同的是,
import\u meta\u graph
将返回一对保存程序和
return\u元素
张量)。。。您也可以在单独的图中导入元图,将其冻结,然后像现在一样导入冻结的graphdef,但是导入的元图将不再是可训练的。请在此或在其他问题中详细说明您在导入元图时面临的问题。非常感谢!冻结和导入似乎有效,我正在验证!如果您愿意,请将其作为答案发布,以便我可以接受。现在我意识到,在某些情况下,我需要导入的图形是可训练的。我尝试了您使用import\u meta\u图形的想法,但失败了。首先,return\u elements参数似乎未被处理(我使用的是v1.15),只返回了saver。然后还原失败,出现错误“Tensor(“map/while/save/Const:0”,shape=(),dtype=string)可能无法馈送”。我把代码贴在了邮件的正文里question@MosheKravchik嗯,我不确定这些错误是从哪里来的。不过还是有一些想法。如果
return\u elements
无法使用
import\u meta\u graph
,您应该仍然能够使用类似
tf.get\u default\u graph().get\u operation\u by_name('yy')。输出[0]
(或者
'import/yy'
,如果您没有指定范围,我不确定这是否是默认值)。关于恢复,在一个会话中执行
saver.restore
,然后完成该会话并打开一个新会话,这是没有意义的。我只会在您实际使用的第二个会话上调用
restore
。@MosheKravchik关于错误,不确定这是否有意义,但您是否尝试将
import\u scope='
传递到
import\u meta\u graph
?我不确定它是否会在默认情况下为导入的操作名添加一些前缀,这会导致保存程序找不到变量(我认为这不是错误,只是以防万一)。确实可以获得
yy
。我将恢复移动到第二个会话,不幸的是,这没有任何区别,我仍然得到了可能无法输入的
张量(“map/while/save/Const:0”,shape=(),dtype=string)
错误:-(@MosheKravchik抱歉,我不知道这一错误的原因是什么,也许可以尝试发布一个新问题,以防其他人可能会帮助你。。。
import tensorflow as tf

meta_graph_path = ...
meta_graph_save_path = ...
with tf.Graph().as_default() as g_meta_import, tf.Session() as sess:
    saver = tf.train.import_meta_graph(meta_graph_path)
    saver.restore(sess, meta_graph_save_path)
    frozen_graph = tf.graph_util.convert_variables_to_constants(
        sess, tf.get_default_graph().as_graph_def(), 'output')

with tf.Graph().as_default() as g_combined:
    x = tf.placeholder(tf.float32, [None, 2], name = 'x')
    def calc_z(el):
        y, = tf.import_graph_def(frozen_graph, input_map={'input:0': el},
                                 return_elements=['output:0'])
        return y
    final_result = tf.map_fn(calc_z, x)
    init = tf.global_variables_initializer()