为了不将优化器和渐变节点带入推理环境,我正在尝试创建两个版本的图形 - 一个带有训练节点,另一个没有.
并且想法是用于tensorflow.train.Saver
将变量从训练图形版本传递到推理图形版本.
所以我尝试了以下内容:
# Create training graph
trainingGraph = tf.Graph()
with (trainingGraph.as_default()):
trainOp, lossOp = self.CreateTrainingGraph()
trainInitOp = tf.initialize_variables(tf.all_variables(), "init_variables")
# Add saver op
self.saverOp = tf.train.Saver()
# Create inference graph
inferenceGraph = tf.Graph()
with (inferenceGraph.as_default()):
self.CreateInferenceGraph()
# Add saver op, compatible with training saver
tf.train.Saver(saver_def=self.saverOp.as_saver_def())
在这种情况下,CreateTrainingGraph()
调用CreateInferenceGraph()
并在其上添加优化器和丢失.
由于某种原因,tf.train.Saver
构造函数不会将save/restore_all
节点添加到推理图中(或者我只是不明白saver_def
选项的作用).我试过空构造函数和
sess.run([model.saverOp._restore_op_name],
{ model.saverOp._filename_tensor_name : "Params/data.pb" })
失败了,错误
returned a result with an error set
实现这个目标的正确方法是什么?
在构建推理图时,您应该能够构造一个tf.train.Saver()
没有参数的函数,并且它将为您构造适当的保存和恢复操作.然后,您应该可以调用saver.restore(sess, filename)
从文件中恢复变量.
NB为使构造函数不使用参数,(i)推理图中的变量(即结果tf.all_variables()
)必须是训练图中变量的子集,并且(ii)相应的变量必须具有完全相同的名称.如果这些条件中的任何一个不成立,则需要为saver构造函数指定变量名称映射.(但是,如果在创建任何其他变量之前self.CreateTrainingGraph()
调用self.CreateInferenceGraph()
,并且没有做任何不同的事情tf.name_scope()
,那么这应该没问题.)
(saver_def
当您加载图形时,参数很少使用 - 例如使用tf.import_graph_def()
- 已经包含来自先前创建的Saver的保存和恢复操作.然后它将在您的Python程序中创建一个重用这些操作的Saver,您将获得如果图形不包含那些操作,则会出现一个神秘的错误.)