我有一个训练有素的模型,使用tf.train.Saver
保存,生成4个相关文件
checkpoint
model_iter-315000.data-00000-of-00001
model_iter-315000.index
model_iter-315000.meta
现在,因为它是通过docker容器生成的,所以机器本身和docker上的路径是不同的,就像我们在两台不同的机器上工作一样。
我正在尝试在容器外部加载已保存的模型。
当我运行以下
时sess = tf.Session()
saver = tf.train.import_meta_graph('path_to_.meta_file_on_new_machine') # Works
saver.restore(sess, tf.train.latest_checkpoint('path_to_ckpt_dir_on_new_machine') # Fails
错误是
tensorflow.python.framework.errors_impl.NotFoundError: PATH_ON_OLD_MACHINE ;没有这样的文件或目录
即使我在调用tf.train.latest_checkpoint
时提供了新路径,但我收到错误,该错误显示旧路径。
我该如何解决这个问题?
答案 0 :(得分:1)
如果您打开checkpoint
文件,您会看到类似的内容:
model_checkpoint_path: "/PATH/ON/OLD/MACHINE/model.ckpt-315000"
all_model_checkpoint_paths: "/PATH/ON/OLD/MACHINE/model.ckpt-300000"
all_model_checkpoint_paths: "/PATH/ON/OLD/MACHINE/model.ckpt-285000"
[...]
只需移除/PATH/ON/OLD/MACHINE/
,或将其替换为/PATH/ON/NEW/MACHINE/
,您就可以了。
修改:
将来,在创建tf.train.Saver
时,您应该使用save_relative_paths
选项。引用doc:
save_relative_paths :如果为True,则会写入相对路径 检查点状态文件。如果用户想要复制,则需要这样做 检查点目录并从复制的目录重新加载。
答案 1 :(得分:1)
“checkpoint”文件是一个索引文件,它本身具有嵌入其中的路径。在文本编辑器中打开它并将路径更改为正确的新路径。
或者,使用tf.train.load_checkpoint()
加载特定检查点,而不是依靠TensorFlow为您找到最新的检查点。在这种情况下,它不会引用“检查点”文件,并且不同的路径也不会成为问题。
或者写一个小脚本来修改“checkpoint”的内容。
答案 2 :(得分:0)
这是一种不需要编辑检查点文件或手动查看检查点目录内部的方法。如果我们知道检查点前缀的名称,则可以使用regex并假设tensorflow在checkpoint
文件的第一行中写入最新的检查点:
import tensorflow as tf
import os
import re
def latest_checkpoint(ckpt_dir, ckpt_prefix="model.ckpt", return_relative=True):
if return_relative:
with open(os.path.join(ckpt_dir, "checkpoint")) as f:
text = f.readline()
pattern = re.compile(re.escape(ckpt_prefix + "-") + r"[0-9]+")
basename = pattern.findall(text)[0]
return os.path.join(ckpt_dir, basename)
else:
return tf.train.latest_checkpoint(ckpt_dir)