我在一台机器上训练TensorFlow(1.2)模型并尝试在另一台机器上进行评估。当我呆在一台机器本地时,一切正常。
我没有使用占位符和feed-dict来获取数据到模型,而是TF文件队列和批处理生成器。我怀疑使用占位符这会更容易,但我正在尝试使TF批量生成器机器工作。
在我的评估代码中,我有以下几行:
saver = tf.train.Saver()
ckpt = tf.train.get_checkpoint_state(os.path.dirname(ckpt_dir))
if ckpt and ckpt.model_checkpoint_path:
saver.restore(sess, ckpt.model_checkpoint_path)
这会产生如下错误:
017-08-16 12:29:06.387435: W tensorflow/core/framework/op_kernel.cc:1158] Invalid argument: Unsuccessful TensorSliceReader constructor: Failed to get matching files on /data/perdue/minerva/tensorflow/models/11/20170816/checkpoints-20: Not found: /data/perdue/minerva/tensorflow/models/11/20170816
引用的目录(/data/...
)存在于我的培训机器上,但不存在于评估机器上。我尝试过像
saver = tf.train.import_meta_graph(
'/local-path/checkpoints-XXX.meta',
clear_devices=True
)
saver.restore(
sess, '/local-path/checkpoints-XXX',
)
但这会产生不同的错误:
tensorflow.python.framework.errors_impl.FailedPreconditionError: Attempting to use uninitialized value train_file_queue/limit_epochs/epochs
或者,如果我在恢复后立即显式调用初始化函数,
AttributeError: 'Tensor' object has no attribute 'initializer'
在这里,train_file_queue/limit_epochs/epochs
是训练图的一个元素,我希望评估函数忽略(我有另一个新元素test_file_queue
指向与评估数据不同的文件队列其中的文件)。
我认为在第二种情况下,当我在恢复之后立即调用初始化程序时,本地变量中的某些内容并不像#"正常&那样起作用#34; Tensor,但我不确定究竟是什么问题。
如果我只使用通用Saver
和restore
TF在原始机器上做正确的事情 - 它只是恢复模型参数,然后使用我的新文件队列进行评估。但是我无法限制在那台机器上,我需要能够在其他机器上评估模型。
我还试过冻结一个protobuf和一些其他选项,而且我总是需要使用文件队列作为最上游的输入。
使用TensorFlow的文件队列和批处理生成器进行训练,然后在不同的机器上/在不同的环境中部署模型的正确方法是什么?我怀疑如果我使用feed-dict来获取图表中的数据,这将非常简单,但在使用内置文件队列和批处理生成器时,它并不清楚。
感谢您的任何意见或建议!
答案 0 :(得分:1)
至少部分对这种困境的回答在TF 1.2或1.3中得到了回答。 Saver()
构造函数有一个新标志:
saver = tf.train.Saver(save_relative_paths=True)
这使得当您保存检查点目录并将其移动到另一台计算机并将其用于restore()
模型时,一切都可以正常工作而不会出现与数据不存在的路径相关的错误(来自旧的路径)进行训练的机器。)
在这种情况下,我并不清楚我对API的使用是非常惯用的,但至少代码的工作方式使得我可以将训练有素的模型从一台机器导出到另一台机器。