使用 TF-slim 训练的模型与 python 推理完美配合,但使用 C++ 给出完全错误的结果

Posted

技术标签:

【中文标题】使用 TF-slim 训练的模型与 python 推理完美配合,但使用 C++ 给出完全错误的结果【英文标题】:Model trained with TF-slim works perfectly with python inference but gives totally wrong results with C++ one 【发布时间】:2018-05-21 11:14:05 【问题描述】:

我已经使用TF-slim 在我自己的自定义数据上训练了一个二类MobileNet_v1。使用 eval_image_classifier.py 代码 this command 测试模型,准确度为 0.936。由于我的实际目标是使用 c++ 代码部署模型,因此我使用 freeze_graph.py 使用以下命令冻结模型:

python3 freeze_graph.py --input_graph=/path/to/graph.pbtxt \
      --input_checkpoint=/path/to/model.ckpt-CHECKPOINTNUMBER \
      --output_graph=frozen_inference_graph.pb \
      --output_node_names=MobilenetV1/Predictions/Reshape_1

graph.pbtxt 是与训练过程一起创建的。我通过在预训练的 MobileNet 模型上发出 summarise_graph 代码获得了输出节点名称。现在,为了在 c++ 中测试我的模型,我使用了label_image(实际上我有自己的代码,但为了确保代码本身我使用它),使用以下命令:

bazel-bin/tensorflow/examples/label_image/label_image \
    --image=/path/to/image.jpg --input_layer=fifo_queue_Dequeue \
    --output_layer=MobilenetV1/Predictions/Reshape_1 \
    --graph=frozen_inference_graph.pb --input_width=192 \
    --input_height=42 --labels=Labels.txt --input_mean=0 \
    --input_std=255

为了得到input_layer,我首先使用了summarize_graph

bazel-bin/tensorflow/tools/graph_transforms/summarize_graph \
  --in_graph=frozen_inference_graph.pb

但是,它没有提供任何输入:

--input_layer= --input_layer_type= --input_layer_shape= --output_layer=MobilenetV1/Predictions/Reshape_1

然后,我尝试通过首先导入冻结模型来使用tensorboard。这是我在那里看到的输入:

使用上面label_image代码的命令,无论输入的图片是什么,模型都只输出一个类。我自己的代码也有同样的情况,我试图尽可能地复制eval_image_classifier.py 执行的预处理步骤。但是,由于结果差异很大,我认为这不是预处理的问题。

我检查了一些问题,例如this one。在这里,提出问题的人已经对权重进行了量化,他说没有这个结果是一样的,这不是我的情况。还有this one,问题似乎在于指定了错误的输入层。我想我自己的问题可能也是因为输入层,但我不知道我还能如何确定输入层名称?我也试过prefetch_queue/fifo_queue,但它给了我这个错误:

Running model failed: Invalid argument: Expects arg[0] to be resource but float is provided

我应该说我对 Tensorflow 比较陌生,到目前为止几乎只使用高级 API 而不是详细的源代码。因此,我将不胜感激任何不太专业且为新手提供足够详细信息的帮助!

【问题讨论】:

【参考方案1】:

我设法解决了这个问题。事实证明,您不应该使用 graph.pbtxt 来冻结模型。为了以正确的方式进行冻结,我们首先需要导出一个推理图:

python3 export_inference_graph.py --alsologtostderr \
   --model_name=mobilenet_v1 --output_file=unfrozen_graph.pb \
   --dataset_name=custom --dataset_dir=/path/to/data_dir

我以前尝试过这个,但是将创建的 unfrozen_graph 与 freeze_graph.py 一起使用给了我错误,所以我放手了,然后完全忘记了它。这些错误的原因是在export_inference_graph.py 代码中用作默认输入尺寸的错误输入尺寸以及我使用自定义尺寸训练我的模型的事实。

长话短说,我使用以下命令冻结了图表:

python3 freeze_graph.py --input_graph=/path/to/unfrozen_graph.pb \
  --input_binary=true --input_checkpoint=/path/to/model.ckpt-CHECKPOINTNUMBER \
  --output_graph=frozen_inference_graph.pb \
  --output_node_names=MobilenetV1/Predictions/Reshape_1

这一次,冻结的图形没有问题,输入层名称为“输入”(操作:占位符)。

【讨论】:

以上是关于使用 TF-slim 训练的模型与 python 推理完美配合,但使用 C++ 给出完全错误的结果的主要内容,如果未能解决你的问题,请参考以下文章

tf-slim 批量规范:训练/推理模式之间的不同行为

Opencv+TF-Slim实现图像分类及深度特征提取

恢复预训练模型的 TensorFlow 检查点文件

应用TF-Slim快速实现迁移学习

TI深度学习(TIDL)-- 3

TI深度学习(TIDL)-- 3