我对SavedModel
API提出了一些问题,documentation我找到了this question无法解释的详细信息。
前三个问题是关于传递给add_meta_graph_and_variables()
tf.saved_model.builder.SavedModelBuilder
方法的论据的内容,而第四个问题是关于为什么要使用SavedModel
API而不是tf.train.Saver
}}
signature_def_map
参数的格式是什么?保存模型时,我通常需要设置此参数吗?
同样,assets_collection
参数的格式是什么?
为什么要保存带有元图的标签列表而不是只给它一个名字(即只附加一个唯一标签)?为什么我要为给定的元图添加多个标签?如果我尝试通过某个标记从pb
加载metagrpah,但pb
中的多个元图与该标记匹配会怎样?
文档认为建议使用SavedModel
在自包含文件中保存整个模型(而不是仅包含变量)。但tf.train.Saver
除了.meta
文件中的变量外,还会保存图表。那么使用SavedModel
有什么好处?文档说
当您想要保存和加载变量,图表和图表时 元数据 - 基本上,当您想要保存或恢复模型时 - 我们 建议使用SavedModel。 SavedModel是一个语言中立的, 可恢复的,密封的序列化格式。 SavedModel启用 更高级别的系统和工具,用于生产,消费和转换 TensorFlow模型。
但这个解释非常抽象,并没有真正帮助我理解SavedModel
的优点。什么是SavedModel
(而不是tf.train.Saver
)更好用的具体例子?
请注意,我的问题与How do I return the response from an asynchronous call?不重复。我没有问如何保存模型,我问的是SavedModel
的属性非常具体的问题,这只是TensorFlow为保存和加载模型提供的多种机制之一。链接问题中的所有答案均未触及SavedModel
API(再次与tf.train.Saver
不同)。
答案 0 :(得分:35)
编辑:我在TensorFlow 1.4上写了这篇文章。截至今天(TensorFlow 1.12稳定,1.13rc和2.0即将到来),问题中链接的文档得到了很大改善。
我试图使用tf.saved_model
,并且发现文档非常(太)抽象。这是我对你的问题的完整答案:
signature_def_map
<强>一个。格式请参阅汤姆对Tensorflow: how to save/restore a model的回答。 (Ctrl-F
for&#34; tf.saved_model&#34; - 目前,该问题上该短语的唯一用途是在他的回答中)。
<强>湾需要我的理解是你通常需要它。如果您打算使用该模型,则需要知道图形的输入和输出。我认为它类似于C ++函数签名:如果您打算在调用函数或在另一个C ++文件中定义函数,则需要在主文件中签名(即原型或头文件中)。 / p>
assets_collection
格式:无法找到明确的文档,因此我转到了构建器source code。看起来该参数是dtype=tf.string
的Tensors的迭代,其中每个Tensor是资产目录的路径。因此,TensorFlow Graph collection应该可行。我想这是参数的同名,但是从源代码我希望Python list
也可以工作。
(你没有问过你是否需要来设置它,但从佐伊对What are assets in tensorflow?和iga的答案的回答判断相关的Tensorflow serving: “No assets to save/writes” when exporting models,它通常不需要设置。)
<强>一个。为什么列出我不知道为什么必须传递列表,但您可以传递一个包含一个元素的列表。例如,在我当前的项目中,我只使用[tf...tag_constants.SERVING]
标签。
<强>湾何时使用多个假设您使用显式设备放置进行操作。也许你想保存图形的CPU版本和GPU版本。显然你想保存每个服务版本,并说你想保存训练检查点。您可以使用CPU / GPU标签和培训/服务标签来管理所有案例。 docs提示:
添加到SavedModel的每个MetaGraphDef必须使用用户指定的标记进行注释。标签提供了一种方法来识别要加载和恢复的特定MetaGraphDef,以及共享的变量和资产集。这些标签通常使用其功能(例如,服务或培训)以及可选的硬件特定方面(例如,GPU)来注释MetaGraphDef。
<强>℃。碰撞强>
懒得自己强迫碰撞 - 我看到两个需要解决的案例 - 我去了装载机source code。在def load
内,您会看到:
saved_model = _parse_saved_model(export_dir)
found_match = False
for meta_graph_def in saved_model.meta_graphs:
if set(meta_graph_def.meta_info_def.tags) == set(tags):
meta_graph_def_to_load = meta_graph_def
found_match = True
break
if not found_match:
raise RuntimeError(
"MetaGraphDef associated with tags " + str(tags).strip("[]") +
" could not be found in SavedModel. To inspect available tag-sets in"
" the SavedModel, please use the SavedModel CLI: `saved_model_cli`"
)
在我看来,它正在寻找完全匹配。例如。说你有一个带有标签的元图和#34; GPU&#34;和&#34;服务&#34;以及带有标记&#34;服务&#34;的元图。如果您加载&#34;服务&#34;,您将获得后一个元图。另一方面,假设你有一个元图&#34; GPU&#34;和&#34;服务&#34;和元数据&#34; CPU&#34;和&#34;服务&#34;。如果您尝试加载&#34;服务&#34;,您将收到错误消息。如果您尝试在同一文件夹中保存两个具有完全相同标签的元图,我希望您覆盖第一个元图。它看起来不像构建代码以任何特殊方式处理这种冲突。
SavedModel
或tf.train.Saver
:这也让我很困惑。韦克对Should TensorFlow users prefer SavedModel over Checkpoint or GraphDef?的回答为我解决了这个问题。我会投入两分钱:
在本地Python + TensorFlow的范围内,您可以让tf.train.Saver
完成所有操作。但是,它会花费你。让我概述一下save-a-trained-model-deploy用例。你需要你的保护对象。最简单的方法是将其设置为保存完整的图形(每个变量)。由于您正在使用静态图表,因此您可能不想一直保存.meta
。您需要在训练钩中指定它。你可以阅读on cv-tricks。培训完成后,您需要将检查点文件转换为pb
文件。这通常意味着清除当前图形,恢复检查点,将变量冻结为tf.python.framework.graph_util
的常量,并用tf.gfile.GFile
编写。你可以阅读on medium。之后,您希望在Python中部署它。您需要输入和输出Tensor名称 - 图表def中的字符串名称。您可以阅读on metaflow (实际上是tf.train.Saver
方法的非常好的博文)。某些操作节点可以让您轻松地将数据输入其中。有些不是那么多。我通常放弃寻找合适的节点,并添加了一个tf.reshape
,它实际上并没有将任何内容重新整形为图形def。那是我的ad-hoc输入节点。输出相同。最后,您可以部署模型,至少在本地部署Python。
或者,您可以使用我在第1点中链接的答案,使用SavedModel
API完成所有这些操作。由于Tom的回答 ,减少了头痛 。如果能够正确记录 ,您将在 中获得更多支持和功能。看起来它更容易使用命令行服务(媒体链接覆盖了Saver
这样做 - 看起来很难,祝你好运!)。它实际上融入了新的Estimators。根据文件,
SavedModel是一种语言中立,可恢复,密集的序列化格式。
强调我的:看起来你可以更容易地将训练有素的模型放入不断增长的C ++ API中。
我看到它的方式,就像数据集API一样。它比其他方式更容易 !
至于SavedModel
tf.train.Saver
的具体示例:如果&#34;基本上,当您想保存或恢复模型时#34;对你来说还不够清楚:正确的使用时间是它让你的生活更轻松。对我来说,这看起来总是如此。特别是如果您使用Estimators,在C ++中部署或使用命令行服务。
这就是我对你的问题的研究。或者四个列举的问题。呃,八个问号。希望这会有所帮助。