Python tensorflow从graph def重新加载模式到会话
我有一个导出的tensorflow保存模型,用于服务。 我想从graphdef对象“重新加载”它,我可以通过spark广播它。 我使用以下方式加载它:Python tensorflow从graph def重新加载模式到会话,python,tensorflow,Python,Tensorflow,我有一个导出的tensorflow保存模型,用于服务。 我想从graphdef对象“重新加载”它,我可以通过spark广播它。 我使用以下方式加载它: sess = tf.Session() tf.saved_model.loader.load(sess, ['serve'], folder) sess.run('dense_1/Softmax:0', {'input_1:0': input_image}) # works 然后,为了再次将其加载到不同的会话,我尝试了: graph_def
sess = tf.Session()
tf.saved_model.loader.load(sess, ['serve'], folder)
sess.run('dense_1/Softmax:0', {'input_1:0': input_image}) # works
然后,为了再次将其加载到不同的会话,我尝试了:
graph_def = sess.graph.as_graph_def()
# then, to load
with tf.Session(graph=tf.Graph()) as sess:
tf.import_graph_def(graph_def, name="")
sess.run('dense_1/Softmax:0', {'input_1:0': input_image})
我得到一个错误:
failedPreceptionError:尝试使用未初始化的值\u 1/内核
我试着加上
sess.run(tf.global\u variables\u initializer())
但还是一样的错误。
我缺少什么?您不能通过graphdef将变量值从一个会话复制到另一个会话。变量值存储在会话中,而图定义仅包含图的结构。您需要从一个会话“导出”变量值,然后在另一个会话中恢复它们。如果您希望避免使用检查点或类似工具,可以使用在大多数情况下都可以工作的功能,如:
import tensorflow as tf
# Gets variable values as a list of pairs with the name and the value
def get_variable_values(sess):
# Find variable operations
var_ops = [op for op in sess.graph.get_operations() if op.type == 'VariableV2']
# Get the values
var_values = []
for v in var_ops:
try:
var_values.append(sess.run(v.outputs[0]))
except tf.errors.FailedPreconditionError:
# Uninitialized variables are ignored
pass
# Return the pairs list
return [(op.name, val) for op, val in zip(var_ops, var_values)]
# Restore the variable values
def restore_var_values(sess, var_values):
# Find the variable initialization operations
assign_ops = [sess.graph.get_operation_by_name(v + '/Assign') for v, _ in var_values]
# Run the initialization operations with the given variable values
sess.run(assign_ops, feed_dict={op.inputs[1]: val
for op, (_, val) in zip(assign_ops, var_values)})
# Test
with tf.Graph().as_default(), tf.Session() as sess:
v = tf.Variable(0., tf.float32, name='a')
v.load(3., sess)
var_values = get_variable_values(sess)
graph_def = tf.get_default_graph().as_graph_def()
with tf.Graph().as_default(), tf.Session() as sess:
tf.import_graph_def(graph_def, name="")
restore_var_values(sess, var_values)
print(sess.run('a:0'))
# 3.0
graphdef是否包含任何权重?我确实看到一些节点具有
tensor_content
属性,但其他节点确实是空的。@user3599803 graphdef包含一些实际值,大部分是图形中的常量(例如,显示如何从图形定义中提取常量,以及轴、形状等)。然而,可训练参数是没有在图形中存储其值的变量。对于使用常量值初始化的变量(如本例所示),将创建保存该值的Const
操作(名称为var\u name/initial\u value
),但这仅用于初始化。我仍然会收到错误failedPremissionError:在运行行时尝试使用未初始化的值批处理\u规范化\u 91/移动\u平均值/local\u步骤\u 4
:var\u values=sess.run([v.outputs[0]用于var\u ops中的v])
@user3599803您需要在第一次会话中初始化变量,然后才能提取它们的值。我更改了代码,所以忽略了未初始化的变量。然而,如果你想使用它们,它们最终需要以某种方式初始化。酷,这是可行的。最后一个问题,我在keras代码中看到,model.get\u weights()
对session.run()进行一次调用。在循环中调用sess.run()是否有效?因为它似乎运行得有点慢。