【问题标题】:How to convert TensorFlow 2 saved model to be used with OpenCV dnn.readNet如何将 TensorFlow 2 保存的模型转换为与 OpenCV dnn.readNet 一起使用
【发布时间】:2022-10-24 13:31:36
【问题描述】:

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

这是我的信息系统

操作系统平台:Windows 10 64 位

张量流版本: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

转换过程成功生成model.onnx,返回如下:

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

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()

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

我尝试使用下面的脚本从我的 saved_model 中获取 freeze_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())

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

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 模式)导入模型。不幸的是,这意味着将我保存的模型导出到frozen_graph 的脚本不起作用。

保存的模型

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

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

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

【问题讨论】:

    标签: opencv deep-learning tensorflow2.0 onnx tf2onnx


    【解决方案1】:

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

    make_FB

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

    使用 pyopencv

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

    【讨论】:

      猜你喜欢
      • 2021-06-26
      • 2018-10-27
      • 2020-03-09
      • 2020-04-30
      • 2018-10-09
      • 2020-10-21
      • 1970-01-01
      • 2020-08-25
      • 2019-05-06
      相关资源
      最近更新 更多