python - 使用微调的 Inception-v3 模型对单个图像进行预测

标签 python tensorflow

尽管这里有很多关于 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:0softmax:0 分别是您可以在其中提供自定义图像并从中检索答案的地方,而在使用自定义微调模型时却没有这么好的入口点。

例如,微调的 Inception-v3 模型卡住图将在实际卷积层之前有 FIFOQueueQueueDequeueMany 和类似的十几个张量,以从 TFRecord 和输出张量看起来像 tower_0/logits/predictions,具有包含批量大小的不可用形状,因此您只是没有合适的点来输入新的 jpeg 图像并得出预测。

是否有任何成功案例涵盖了使用带有新图像的这种批量微调模型?或者可能有一些关于将 TFRecord/批处理节点的输入包更改为 JPEG 的想法?

附言还有一种运行预训练模型的替代方法,例如 TF Serving,但构建一个巨大的 github 存储库,每个其他步骤都有大量依赖项,这对我来说似乎难以承受。

最佳答案

我没有使用 Inception-v3 模型,但我找到了解决类似情况的方法。 对于训练,我使用自定义多进程/多线程设置将我的样本加载到批处理中并将它们送入 FIFOQueue。在卡住图上运行推理总是无限期地挂起。 这是我的方法:

创建卡住推理模型:

  1. 构建一个完全独立的推理图。为您的输入创建占位符 [in1,in2,...](形状对应于 1 个样本)并以与训练相同的方式创建模型。您的模型的输出将在下文中称为 [out1,out2...]
  2. 使用 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)
    
  3. 创建卡住图:

    frozen_graph_def = graph_util.convert_variables_to_constants(
        sess,
        input_graph_def,
        output_node_names)
    
  4. 优化模型:

    optimized_graph_def = optimize_for_inference_lib.optimize_for_inference(
        frozen_graph_def,
        input_node_names,
        output_node_names, tf.float32.as_datatype_enum)
    
  5. 保存模型:

    with tf.gfile.GFile(filename, "wb") as f:
        f.write(optimized_graph_def.SerializeToString())
    

使用卡住模型进行推理:

  1. 将模型加载到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
        )
    
  2. 访问您的输入/输出:

    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])
    ...
    
  3. 运行推理:

    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/

相关文章:

python - 训练 CNN 后准确率较低

tensorflow - Sagemaker tensorflow 端点在调用预测时不调用 input_handler

ubuntu - 用于持久存储的卷挂载 tensorflow 容器

python - 如何更改 ttk.Button 中的字体大小?

python - 无法在 Ubuntu VPS 上使用 Flask 运行 PhantomJS

python - 在python中,对同一个文件执行多个终端命令并保存所有更改一次

python - Tensorboard 分析器 : Failed to load libcupti (is it installed and accessible? )

python - 如何找到 tensorflow 数组中的第二低值

python - python 中的对数正态分布

python - Pyspark 将列除以按另一列分组的小计