尽管这里有很多关于 SO 的问题引发了重用经过训练的 tensorflow 模型的问题,但使用最主流的模型之一仍然是一个挑战 Inception-v3在自定义数据集上进行微调以仅预测某些单个图像的概率。
在对这个主题做了一些研究之后(最相似的 SO 线程肯定是 Tensorflow: restoring a graph and model then running evaluation on a single image )我可以得出结论,卡住一些经过训练的模型的 graph.pb 文件就像拥有 chalice ,因为你不不需要重建图形、选择要恢复的张量或其他任何东西——您只需调用 tf.import_graph_def
并通过 sess.graph.get_tensor_by_name
获取您需要的输出层。
但问题在于,在 tensorflow 提供的示例中(例如 classify_image.py),此类 «frozen graph» 已经很好地准备了输入和输出点,例如 DecodeJpeg/contents:0
和 softmax:0
分别是您可以在其中提供自定义图像并从中检索答案的地方,而在使用自定义微调模型时却没有这么好的入口点。
例如,微调的 Inception-v3 模型卡住图将在实际卷积层之前有 FIFOQueue
、QueueDequeueMany
和类似的十几个张量,以从 TFRecord 和输出张量看起来像 tower_0/logits/predictions
,具有包含批量大小的不可用形状,因此您只是没有合适的点来输入新的 jpeg 图像并得出预测。
是否有任何成功案例涵盖了使用带有新图像的这种批量微调模型?或者可能有一些关于将 TFRecord/批处理节点的输入包更改为 JPEG 的想法?
附言还有一种运行预训练模型的替代方法,例如 TF Serving,但构建一个巨大的 github 存储库,每个其他步骤都有大量依赖项,这对我来说似乎难以承受。
最佳答案
我没有使用 Inception-v3 模型,但我找到了解决类似情况的方法。 对于训练,我使用自定义多进程/多线程设置将我的样本加载到批处理中并将它们送入 FIFOQueue。在卡住图上运行推理总是无限期地挂起。 这是我的方法:
创建卡住推理模型:
- 构建一个完全独立的推理图。为您的输入创建占位符
[in1,in2,...]
(形状对应于 1 个样本)并以与训练相同的方式创建模型。您的模型的输出将在下文中称为[out1,out2...]
。 使用
tf.train.Saver()
加载您训练过的模型参数(为此,新模型中的名称必须与训练模型中的名称相匹配)。像这样的东西:loader = tf.train.Saver() graph = tf.get_default_graph() input_graph_def = graph.as_graph_def() with tf.Session() as sess: loader.restore(sess, input_checkpoint)
创建卡住图:
frozen_graph_def = graph_util.convert_variables_to_constants( sess, input_graph_def, output_node_names)
优化模型:
optimized_graph_def = optimize_for_inference_lib.optimize_for_inference( frozen_graph_def, input_node_names, output_node_names, tf.float32.as_datatype_enum)
保存模型:
with tf.gfile.GFile(filename, "wb") as f: f.write(optimized_graph_def.SerializeToString())
使用卡住模型进行推理:
将模型加载到
graph
with tf.gfile.GFile(frozen_graph_filename, "rb") as f: graph_def = tf.GraphDef() graph_def.ParseFromString(f.read()) with tf.Graph().as_default() as graph: tf.import_graph_def( graph_def, input_map=None, return_elements=None, name='', op_dict=None, producer_op_list=None )
访问您的输入/输出:
in1 = graph.get_tensor_by_name(input_tensor_names[0]) in2 = graph.get_tensor_by_name(input_tensor_names[1]) ... out1 = graph.get_tensor_by_name(output_tensor_names[0]) ...
运行推理:
with tf.Session(graph=graph) as sess: sess.run([out1], feed_dict={in1: {data}, in2: {data})
提示:如何获取输入/输出节点/张量名称:
inputs = [in1, in2...]
outputs = [out1, out2...]
output_tensor_names = [n.name for n in outputs]
input_tensor_names = [n.name for n in inputs]
output_node_names = [n[:str(n).find(":")] for n in output_tensor_names]
input_node_names = [n[:str(n).find(":")] for n in input_tensor_names]
希望对您有所帮助。
关于python - 使用微调的 Inception-v3 模型对单个图像进行预测,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40444514/