将 Tensorflow 冻结推理图加载到 OpenCV DNN 时出错
Error Loading Tensorflow Frozen Inference Graph to OpenCV DNN
我已经使用 Tensorflow API 训练了一个对象检测模型,下面是一个基于 Roboflow 的 Google Colaboratory 笔记本的示例。
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 中制作我的对象检测程序。同样在这个示例 之后,我准备了模型和管道配置的 .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 和配置文件进行差异检查,但我找不到在任何地方使用的该特定目录的任何实例,甚至它们内部也没有目录路径。
这是使用 Google Colab 训练造成的吗?
有什么正确的方法可以在 OpenCV DNN 中使用 Colab 训练的 Tensorflow 模型吗?
提前致谢!
在我自己生成的pbtxt文件中添加一个额外的输入节点后解决
有人建议我使用的 OpenCV 版本 4.11 已过时。
我更新到 4.30,仍然无法正常工作,但是它现在让我可以使用 FusedBatchNormV3,这在未来非常重要。
现在,在仔细查看示例中的差异检查和生成的 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 API 训练了一个对象检测模型,下面是一个基于 Roboflow 的 Google Colaboratory 笔记本的示例。 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 中制作我的对象检测程序。同样在这个示例 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 和配置文件进行差异检查,但我找不到在任何地方使用的该特定目录的任何实例,甚至它们内部也没有目录路径。
这是使用 Google Colab 训练造成的吗? 有什么正确的方法可以在 OpenCV DNN 中使用 Colab 训练的 Tensorflow 模型吗?
提前致谢!
在我自己生成的pbtxt文件中添加一个额外的输入节点后解决
有人建议我使用的 OpenCV 版本 4.11 已过时。 我更新到 4.30,仍然无法正常工作,但是它现在让我可以使用 FusedBatchNormV3,这在未来非常重要。
现在,在仔细查看示例中的差异检查和生成的 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 中,它起作用了!!!