将 TensorFlow Frozen Inference Graph 加载到 OpenCV DNN 时出错

Posted

技术标签:

【中文标题】将 TensorFlow Frozen Inference Graph 加载到 OpenCV DNN 时出错【英文标题】:Error Loading Tensorflow Frozen Inference Graph to OpenCV DNN 【发布时间】:2020-10-26 07:00:35 【问题描述】:

我已经使用 Tensorflow API 训练了一个对象检测模型,该模型基于 Roboflow 的这个 Google Colaboratory notebook 的示例。 https://colab.research.google.com/drive/1wTMIrJhYsQdq_u7ROOkf0Lu_fsX5Mu8a

到目前为止一切顺利,我已经成功地将经过训练的模型提取为推理图,再次遵循同一个笔记本:

import re
import numpy as np

output_directory = './fine_tuned_model'

lst = os.listdir(model_dir)
lst = [l for l in lst if 'model.ckpt-' in l and '.meta' in l]
steps=np.array([int(re.findall('\d+', l)[0]) for l in lst])
last_model = lst[steps.argmax()].replace('.meta', '')

last_model_path = os.path.join(model_dir, last_model)
print(last_model_path)
!python /content/models/research/object_detection/export_inference_graph.py \
    --input_type=image_tensor \
    --pipeline_config_path=pipeline_fname \
    --output_directory=output_directory \
    --trained_checkpoint_prefix=last_model_path

这给了我一个frozen_inference_graph.pb文件,我可以用它在 OpenCV DNN 中制作我的对象检测程序。同样按照此示例https://***.com/a/57055266/9914815,我准备了模型和管道配置的.pbtxt 文件作为cv2.dnn.readNetFromTensorflow 函数的第二个参数。这是足以重现我遇到的错误的代码:

model = cv2.dnn.readNetFromTensorflow('models/trained/frozen_inference_graph.pb', 
                                      'models/trained/output.pbtxt')

当我使用预训练的 SSD MobileNet V2 COCO 模型时,此代码运行成功,ssd_mobilenet_v2_coco_2018_03_29.pbtxt

但是使用我训练的 .pbtxt 文件,它会抛出这个错误:

C:\Users\Satria\Desktop\ExploreOpencvDnn-master>python trainedmodel_video.py -i test1.mp4 -o test1result.mp4
Traceback (most recent call last):                                                                                                                            
File "trainedmodel_video.py", line 48, in <module> 'models/trained/output.pbtxt') cv2.error:
OpenCV(4.1.1) C:\projects\opencv-python\opencv\modules\dnn\src\tensorflow\tf_importer.cpp:544:error:
(-2:Unspecified error) Input layer not found: FeatureExtractor/MobilenetV2/Conv/weights in function
'cv::dnn::dnn4_v20190621::`anonymous-namespace'::TFImporter::connect' 

它说没有找到输入层。为什么会这样? 另请注意,错误消息指出了一个目录:

C:\projects\opencv-python\opencv\modules\dnn\src\tensorflow\tf_importer.cpp

这太奇怪了,因为我的电脑里根本没有那个目录。 我尝试对我的和示例 SSD mobilenet 模型的 pbtxt 和配置文件进行 diffcheck,但我找不到在任何地方使用的特定目录的任何实例,甚至它们里面也没有目录路径。

这是由使用 Google Colab 进行培训引起的吗? 我可以在 OpenCV DNN 中使用 Colab 训练的 Tensorflow 模型吗?

提前致谢!

【问题讨论】:

【参考方案1】:

在我自己生成的 pbtxt 文件中添加额外的输入节点后解决

有人建议我使用的 OpenCV 版本 4.11 已过时。 我更新到 4.30,仍然无法正常工作,但它现在让我可以使用 FusedBatchNormV3,这在未来非常重要。

现在,在仔细查看示例中的 diffcheck 和生成的 pbtxt 之后,

在示例 .pbtxt 文件 ssd_mobilenet_v2_coco_2018_03_29.pbtxt 的第 30 行之前

node   
  name: "Preprocessor/mul"  
  op: "Mul" 
  input: "image_tensor" 
  input: "Preprocessor/mul/x"   
   
node   
  name: "Preprocessor/sub"  
  op: "Sub" 
  input: "Preprocessor/mul" 
  input: "Preprocessor/sub/y"   
   
node   
  name: "FeatureExtractor/MobilenetV2/Conv/Conv2D"  
  op: "Conv2D"  
  input: "Preprocessor/sub" 
  input: "FeatureExtractor/MobilenetV2/Conv/weights"    

它有一个额外的输入节点,它使用Preprocessor,而不仅仅是FeatureExtractor/MobilenetV2/Conv/Conv2D

同时在生成的 pbtxt 上它只有这个

node 
  name: "FeatureExtractor/MobilenetV2/Conv/Conv2D"
  op: "Conv2D"
  input: "FeatureExtractor/MobilenetV2/Conv/weights"

我将示例 .pbtxt 的输入节点复制到了我自己生成的 .pbtxt 中,并且成功了!!!

【讨论】:

以上是关于将 TensorFlow Frozen Inference Graph 加载到 OpenCV DNN 时出错的主要内容,如果未能解决你的问题,请参考以下文章

如何使用来自 Google AutoML 视觉分类的 TensorFlow Frozen GraphDef (single saved_model.pb) 进行推理和迁移学习

显式 tensorflow 会话在 Tensorflow/nmt 中给出获取错误

带你了解TensorFlow pb模型常用处理方法

Infer 在 Mac 上的安装和环境配置

Ts的infer类型推导

Frozen Bokeh 应用程序太大