如何将TensorFlow 2保存的模型转换为opencv dnn.readnet

发布于 01-20 06:58 字数 4803 浏览 8 评论 0原文

我正在努力寻找一种方法,使用 TensorFlow 2 对象检测 API 将经过训练的网络转换为与 OpenCV 一起用于部署目的。我尝试了两种方法,但没有成功。 有人可以帮助我解决这个问题或提出最好、最简单的深度学习框架来将我的模型转换为 OpenCV(OpenCV 友好)吗? 我非常感谢您提供的任何帮助。

这是我的信息系统

操作系统平台:Windows 10 64位

Tensorflow版本:2.8

Python版本:3.9.7

OpenCV版本:4.5.5

第一种方法:使用tf2onnx

因为我使用的是TensorFlow 2,所以我使用了以下代码

python -m tf2onnx.convert --saved-model tensorflow-model-path --output model.onnx --opset 15

转换过程生成模型.onnx 成功并返回以下内容: 输入图片description here

但是,当我尝试读取转换后的模型时,出现以下错误:

File "C:\Tensorflow\testcovertedTF2ToONNX.py", line 10, in <module> net = cv2.dnn.readNetFromONNX('C:/Tensorflow/model.onnx') cv2.error: Unknown C++ exception from OpenCV code

用于读取转换后的网络的代码很简单。

import cv2
import numpy as np
 
image = cv2.imread("img002500.jpg")
if image is None:
    print("image emplty")
image_height, image_width, _ = image.shape
net = cv2.dnn.readNetFromONNX('model.onnx')
image = image.astype(np.float32)

input_blob = cv2.dnn.blobFromImage(image, 1, (640,640), 0, swapRB=False, crop=False)
net.setInput(input_blob)
output = net.forward()

第二种方法:尝试从保存的模型中获取冻结图

我尝试使用下面的脚本从我的保存的模型中获取frozen_graph.pb,可以在
中找到 https://github.com/opencv/opencv/issues/16879#issuecomment- 603815872

import tensorflow as tf
print(tf.__version__)

from tensorflow.python.framework.convert_to_constants import convert_variables_to_constants_v2

loaded = tf.saved_model.load('models/mnist_test')
infer = loaded.signatures['serving_default']

f = tf.function(infer).get_concrete_function(input_tensor=tf.TensorSpec(shape=[None, 640, 640, 3], dtype=tf.float32))
f2 = convert_variables_to_constants_v2(f)
graph_def = f2.graph.as_graph_def()

# Export frozen graph
with tf.io.gfile.GFile('frozen_graph.pb', 'wb') as f:
   f.write(graph_def.SerializeToString())

然后,我尝试使用生成文本图形表示(graph.pbtxt) tf_text_graph_ssd.py 在 https://github.com/opencv/opencv 中找到/wiki/TensorFlow-Object-Detection-API

python tf_text_graph_ssd.py --input path2frozen_graph.pb --config path2pipeline.config --output outputgraph.pbtxt

该脚本的执行返回以下错误:

cv.dnn.writeTextGraph(modelPath, outputPath)
cv2.error: OpenCV(4.5.5) D:\a\opencv-python\opencv-python\opencv\modules\dnn\src\tensorflow\tf_graph_simplifier.cpp:1052: error: (-215:Assertion failed) permIds.size() == net.node_size() in function 'cv::dnn::dnn4_v20211220::sortByExecutionOrder'

During the handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Tensorflow\generatepBtxtgraph\tf_text_graph_ssd.py", line 413, in <module>
    createSSDGraph(args.input, args.config, args.output)
  File "C:\Tensorflow\generatepBtxtgraph\tf_text_graph_ssd.py", line 127, in createSSDGraph
    writeTextGraph(modelPath, outputPath, outNames)
  File "C:\Tensorflow\generatepBtxtgraph\tf_text_graph_common.py", line 320, in writeTextGraph
    from tensorflow.tools.graph_transforms import TransformGraph
ModuleNotFoundError: No module named 'tensorflow.tools.graph_transforms'

尝试使用 dnn.readNet 读取生成的冻结模型而不使用 graph.pb,代码如下:

import cv2
import numpy as np
 
image = cv2.imread("img002500.jpg")
if image is None:
    print("image emplty")
image_height, image_width, _ = image.shape
net = cv2.dnn.readNet('frozen_graph_centernet.pb')
image = image.astype(np.float32)
# create blob from image (opencv dnn way of pre-processing)
input_blob = cv2.dnn.blobFromImage(image, 1, (1024,1024), 0, swapRB=False, crop=False)
net.setInput(input_blob)
output = net.forward()

返回以下错误

Traceback (most recent call last):
  File "C:\Tensorflow\testFrozengraphTF2.py", line 14, in <module>
    output = net.forward()
cv2.error: OpenCV(4.5.5) D:\a\opencv-python\opencv-python\opencv\modules\dnn\src\dnn.cpp:621: error: (-2:Unspecified error) Can't create layer "StatefulPartitionedCall" of type "StatefulPartitionedCall" in function 'cv::dnn::dnn4_v20211220::LayerData::getLayerInstance'

我了解 OpenCV 不使用 StatefulPartitionedCall(TF Eager 模式)导入模型。不幸的是,这意味着将我保存的模型导出到 freeze_graph 的脚本不起作用。

保存的模型

您可以从下面的链接获取我保存的模型

https:// www.dropbox.com/s/liw5ff87rz7v5n5/my_model.zip?dl=0

#note:导出的模型与 TensorFlow 脚本配合良好

I am struggling to find a way to convert my trained network using TensorFlow 2 Object detection API to be used with OpenCV for deployment purposes. I tried two methods for that but without success.
Could someone help me resolve this issue or propose the best and easy deep learning framework to convert my model to OpenCV (OpenCV friendly)?
I really appreciate any help you can provide.

This is my information system

OS Platform: Windows 10 64 bits

Tensorflow Version: 2.8

Python version: 3.9.7

OpenCV version: 4.5.5

1st Method: Using tf2onnx

I used the following code since I am using TensorFlow 2

python -m tf2onnx.convert --saved-model tensorflow-model-path --output model.onnx --opset 15

The conversion process generates the model.onnx successfully and returns the following:
enter image description here

However, when I try to read the converted model, I get the following error:

File "C:\Tensorflow\testcovertedTF2ToONNX.py", line 10, in <module> net = cv2.dnn.readNetFromONNX('C:/Tensorflow/model.onnx') cv2.error: Unknown C++ exception from OpenCV code

The code used to read the converted network is simple.

import cv2
import numpy as np
 
image = cv2.imread("img002500.jpg")
if image is None:
    print("image emplty")
image_height, image_width, _ = image.shape
net = cv2.dnn.readNetFromONNX('model.onnx')
image = image.astype(np.float32)

input_blob = cv2.dnn.blobFromImage(image, 1, (640,640), 0, swapRB=False, crop=False)
net.setInput(input_blob)
output = net.forward()

2nd Method: Trying to get Frozen graph from saved model

I tried to get frozen_graph.pb from my saved_model using the script below, found in
https://github.com/opencv/opencv/issues/16879#issuecomment-603815872

import tensorflow as tf
print(tf.__version__)

from tensorflow.python.framework.convert_to_constants import convert_variables_to_constants_v2

loaded = tf.saved_model.load('models/mnist_test')
infer = loaded.signatures['serving_default']

f = tf.function(infer).get_concrete_function(input_tensor=tf.TensorSpec(shape=[None, 640, 640, 3], dtype=tf.float32))
f2 = convert_variables_to_constants_v2(f)
graph_def = f2.graph.as_graph_def()

# Export frozen graph
with tf.io.gfile.GFile('frozen_graph.pb', 'wb') as f:
   f.write(graph_def.SerializeToString())

Then, I tried to generate the text graph representation (graph.pbtxt) using tf_text_graph_ssd.py found in https://github.com/opencv/opencv/wiki/TensorFlow-Object-Detection-API

python tf_text_graph_ssd.py --input path2frozen_graph.pb --config path2pipeline.config --output outputgraph.pbtxt

The execution of this script returns the following error:

cv.dnn.writeTextGraph(modelPath, outputPath)
cv2.error: OpenCV(4.5.5) D:\a\opencv-python\opencv-python\opencv\modules\dnn\src\tensorflow\tf_graph_simplifier.cpp:1052: error: (-215:Assertion failed) permIds.size() == net.node_size() in function 'cv::dnn::dnn4_v20211220::sortByExecutionOrder'

During the handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Tensorflow\generatepBtxtgraph\tf_text_graph_ssd.py", line 413, in <module>
    createSSDGraph(args.input, args.config, args.output)
  File "C:\Tensorflow\generatepBtxtgraph\tf_text_graph_ssd.py", line 127, in createSSDGraph
    writeTextGraph(modelPath, outputPath, outNames)
  File "C:\Tensorflow\generatepBtxtgraph\tf_text_graph_common.py", line 320, in writeTextGraph
    from tensorflow.tools.graph_transforms import TransformGraph
ModuleNotFoundError: No module named 'tensorflow.tools.graph_transforms'

Trying to read the generated frozen model without a graph.pb using dnn.readNet the code below:

import cv2
import numpy as np
 
image = cv2.imread("img002500.jpg")
if image is None:
    print("image emplty")
image_height, image_width, _ = image.shape
net = cv2.dnn.readNet('frozen_graph_centernet.pb')
image = image.astype(np.float32)
# create blob from image (opencv dnn way of pre-processing)
input_blob = cv2.dnn.blobFromImage(image, 1, (1024,1024), 0, swapRB=False, crop=False)
net.setInput(input_blob)
output = net.forward()

returns the following error

Traceback (most recent call last):
  File "C:\Tensorflow\testFrozengraphTF2.py", line 14, in <module>
    output = net.forward()
cv2.error: OpenCV(4.5.5) D:\a\opencv-python\opencv-python\opencv\modules\dnn\src\dnn.cpp:621: error: (-2:Unspecified error) Can't create layer "StatefulPartitionedCall" of type "StatefulPartitionedCall" in function 'cv::dnn::dnn4_v20211220::LayerData::getLayerInstance'

I understand that OpenCV doesn't import models with StatefulPartitionedCall (TF Eager mode). Unfortunately, this means the script found to export my saved model to frozen_graph did not work.

saved model

you can get my saved model from the link below

https://www.dropbox.com/s/liw5ff87rz7v5n5/my_model.zip?dl=0

#note: the exported model works well with the TensorFlow script

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

高速公鹿 2025-01-27 06:58:29

第二种方法:尝试从保存的模型

make_fb

获取冷冻图

https://medium.com/@sebastingarcaocosta/how-to-to-to-port-a-tensorflow-2--x-keras-model-to-a-frozen-and-frozen-and-optimistimized-graph-graph-39740846d9eb

使用pyopencv

模型= cv.dnn.readnetfromtensorflow('./ frozen_graph2.pb')

2nd Method: Trying to get Frozen graph from saved model

make_FB

https://medium.com/@sebastingarcaacosta/how-to-export-a-tensorflow-2-x-keras-model-to-a-frozen-and-optimized-graph-39740846d9eb

use pyopencv

model = cv.dnn.readNetFromTensorflow('./frozen_graph2.pb')

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文