OpenCV读取tensorflow神经网络模型:SavedModel格式转为frozen graph的方法

  本文介绍基于Pythontensorflow库,将tensorflowkeras训练好的SavedModel格式神经网络模型转换为frozen graph格式,从而可以用OpenCV库在C++ 等其他语言中将其打开的方法。

  如果我们需要训练使用一个神经网络模型,一般情况下都是首先借助Python语言中完善的神经网络模型API对其加以训练,训练完毕后在C++Java等语言环境下高效、快速地使用它。最近,就需要在C++ 中打开、使用几个前期已经在Pythontensorflow库中训练好的神经网络模型。但是,由于训练模型时使用的是2.X版本的tensorflow库(且用的是keras的框架),所以训练模型后保存的是SavedModel格式的神经网络模型文件——就是包含3.pb格式文件,以及assetsvariables2个文件夹那种形式的模型;如下图所示。

  而在C++ 中读取神经网络模型,首先是可以借助tensorflow库的C++ API来实现,但是这种方法非常复杂——完整的TensorFlow C++ API部署起来非常困难——需要系统盘至少40 G50 G的剩余空间、动辄0.5 h1 h的编译时长,经常需要花费一周的时间才可以配置成功;所以如果仅仅是需要在C++ 中读取已经训练好的神经网络模型的话,没必要花费这么大功夫去配置TensorFlow C++ API。而同时,基于OpenCV库,我们则可以在简单、快速地配置完其环境后,就基于1个函数对训练好的tensorflow库神经网络模型加以读取、使用。这里如果大家需要配置C++ 环境的OpenCV库,可以参考文章C++计算机视觉库OpenCV在Visual Studio 2022的配置方法(https://blog.csdn.net/zhebushibiaoshifu/article/details/128260507)。

  但是,还有一个问题——OpenCV库自身目前仅支持读取tensorflowfrozen graph格式的神经网络模型,不支持读取SavedModel格式的模型。因此,如果希望基于OpenCV库读取tensorflowSavedModel格式的模型,就需要首先将其转换为frozen graph格式;那么,本文就介绍一下这个操作的具体方法,并给出2种实现这一转换功能的Python代码。

  首先,本文神经网络模型格式转换的代码是基于Python环境中tensorflow库实现的,因此需要配置好这一个库(大家都已经需要转换神经网络模型的格式了,那Python环境中tensorflow库肯定早已经配置好了);如果没有配置,可以参考文章Anaconda配置Python新版本tensorflow库(CPU、GPU通用)的方法(https://blog.csdn.net/zhebushibiaoshifu/article/details/129285815)。

  第1种代码如下。

# -*- coding: utf-8 -*-
"""
Created on Sat Mar  9 14:31:18 2024@author: fkxxgis
"""import tensorflow as tf
from tensorflow.keras import models
from tensorflow.python.framework.convert_to_constants import convert_variables_to_constants_v2# model_save_model = tf.saved_model.load("F:/Data_Reflectance_Rec/model/model_blue/")
model_save_model = models.load_model("F:/Data_Reflectance_Rec/model/model_blue/")signatures = model_save_model.signatures["serving_default"]
graph = tf.function(lambda x: model_save_model(x))
graph = graph.get_concrete_function(tf.TensorSpec(signatures.inputs[0].shape.as_list(), signatures.inputs[0].dtype.name))
frozen_variable = convert_variables_to_constants_v2(graph)
frozen_variable.graph.as_graph_def();tf.io.write_graph(graph_or_graph_def = frozen_variable.graph, logdir = "F:/Data_Reflectance_Rec/model/model_blue_new", name = "frozen_graph.pb", as_text = False)
# tf.io.write_graph(graph_or_graph_def = frozen_variable.graph, 
#                   logdir = "F:/Data_Reflectance_Rec/model/model_blue_new", 
#                   name = "frozen_graph.pbtxt", 
#                   as_text = True)

  其中,我们首先需要导入对应的Python模块和convert_variables_to_constants_v2()函数。

  随后,加载我们待转换的、SavedModel格式的tensorflow神经网络模型。这里需要注意,我写了2句不同的代码来加载初始的模型——其中,如果用第1句代码加载模型,倒也可以不报错地运行完成上述代码,但是等到用C++ 环境的OpenCV库读取这个转换后的模型时,会出现Microsoft C++ 异常: cv::Exception字样的报错,如下图所示;而如果用第2句代码加载模型,就没有问题。之所以会这样,应该是因为我当初训练这个神经网络模型时,用的是tensorflowkeras模块的Model,所以导致加载模型时,就不能用传统的加载SavedModel格式模型的方法了(可能是这样)。

  接下来,我们从初始模型中获取其签名tensorflow库中的签名(Signature),是用于定义模型输入、输出的一种机制——其定义了模型接受的输入参数和返回的输出结果的名称、数据类型和形状等信息;这个默认签名为serving_default,我们这里获取这个默认的签名即可。

  接下来,这个graph = tf.function(lambda x: model_save_model(x))表示将模型封装在tensorflow的图函数中;随后,get_concrete_function()获取具体函数并指定输入张量的形状和数据类型。说实话,这里的2行代码我也搞不太清楚具体详细含义是什么——但大体上,这些内容应该是tensorflow1.X版本中的一些操作与名词(因为frozen graph格式的模型本来就是tensorflow1.X版本中用的,而SavedModel格式则是2.X版本中常用的)。

  再次,通过convert_variables_to_constants_v2()函数,将图中的变量转换为常量,并基于as_graph_def()定义1个冻结图。

  最后,就可以通过tf.io.write_graph()函数,将冻结图写入指定的目录中,输出文件名为frozen_graph.pbas_text = False表示以二进制格式保存这个模型(如果不加这个参数,就相当于成了.pbtxt文件了,导致后续用C++环境的OpenCV库还是读取不了这个模型)。代码末尾,还有一段注释的部分——如果取消注释,将以文本格式保存冻结图,也就是.pbtxt文件。因为我们只要.pb文件就够了,所以就不需要这段代码了。

  执行上述代码,在结果文件夹中,我们将看到1.pb格式的神经网络模型结果文件,如下图所示。

  接下来,在C++Python等语言的OpenCV库中,我们都可以基于cv::dnn::readNetFromTensorflow()这个函数,来读取我们的神经网络模型了。

  除此之外,再给出另一个版本的转换代码;这个代码其实和前述代码的含义差不多,如果前述代码不能执行,大家可以再尝试尝试下面这个。

import tensorflow as tf
from tensorflow.python.framework.convert_to_constants import convert_variables_to_constants_v2loaded = tf.saved_model.load('F:/Data_Reflectance_Rec/model/model_nir/')
infer = loaded.signatures['serving_default']f = tf.function(infer).get_concrete_function(tf.TensorSpec(infer.inputs[0].shape.as_list(), dtype=tf.float32))
f2 = convert_variables_to_constants_v2(f)
graph_def = f2.graph.as_graph_def()with tf.io.gfile.GFile('frozen_graph.pb', 'wb') as f:f.write(graph_def.SerializeToString())

  至此,大功告成。

欢迎关注:疯狂学习GIS

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/275641.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

react 综合题-旧版

一、组件基础 1. React 事件机制 javascript 复制代码<div onClick{this.handleClick.bind(this)}>点我</div> React并不是将click事件绑定到了div的真实DOM上&#xff0c;而是在document处监听了所有的事件&#xff0c;当事件发生并且冒泡到document处的时候&a…

利用Java实现数据矩阵的可视化

1. 引言 在进行工程开发时&#xff0c;通常需要在窗口的某个区域将有效数据形象化地呈现出来&#xff0c;例如&#xff1a;对于某一区域的高程数据以伪色彩的方式呈现出高度的变化&#xff0c;这就需要解决利用Java进行数据呈现的问题。本文将建立新工程开始&#xff0c;逐步地…

UDP数据报套接字编程

1.1UDP编程原理 对于UDP协议来说&#xff0c;具有无连接&#xff0c;面向数据报的特征&#xff0c;即每次都是没有建立连接&#xff0c;并且一次发送全部数据报&#xff0c;一次接收全部的数据报。Java中使用UDP协议通信&#xff0c;主要基于DatagramSocket类来发送或接收数据报…

NBlog整合OSS图库

NBlog部署维护流程记录&#xff08;持续更新&#xff09;&#xff1a;https://blog.csdn.net/qq_43349112/article/details/136129806 由于项目是fork的&#xff0c;所以我本身并不清楚哪里使用了图床&#xff0c;因此下面就是我熟悉项目期间边做边调整的。 目前已经调整的功能…

Docker容器Docker桌面配置镜像加速

打开Docker Desktop应用程序&#xff0c;点击设置 具体配置如下&#xff1a; {"builder": {"gc": {"defaultKeepStorage": "20GB","enabled": true}},"experimental": false,"features": {"buil…

个人博客系列-后端项目-用户注册功能(7)

介绍 用户注册API的主要流程&#xff1a;1.前端用户提交用户名&#xff0c;密码 2. 序列化器校验用户名&#xff0c;密码是否合法。3.存入数据库。4.签发token 创建序列化器 from rest_framework import serializers from rest_framework_simplejwt.serializers import Toke…

防御安全(IPSec实验)

目录 需求&#xff1a; pc1 ping通 pc2 ,使用IPSec VPN 拓扑图&#xff1a; ​编辑实验配置&#xff1a; 注意&#xff1a; 直接在路由器r1和r2分别配置即可&#xff0c;路由器r1和r2要写一条缺省指向ISP 实验配置截图如下&#xff1a; 2. r1​编辑 3. r3​编辑 3.r…

Electron程序如何在MacOS下获取相册访问权限

1.通过entitiment.plist&#xff0c;在electron-builder签名打包时&#xff0c;给app包打上签名。最后可以通过codesign命令进行验证。 TestPhotos.plist electron-builder配置文件中加上刚刚的plist文件。 通过codesign命令验证&#xff0c;若出现这个&#xff0c;则说明成…

[BJDCTF2020]Cookie is so stable

hint提示查看cookies flag.php页面我们先随便输入一个名字 输入后我们重新进一次flag.php&#xff0c;发现cookie里存储了刚刚登陆时输入的用户名&#xff0c;直接猜是ssti 尝试后根据ssti特征判断是twig模板 {{_self.env.registerUndefinedFilterCallback("exec")…

VUE实现Provide的计算属性

通过此篇可以学到&#xff1a; 如何使用Providerinject进行“跨代”传值如何实现一个计算属性的Provider如何解决告警“injection "xxxxx" not found. ” 一、描述 目前需要创建一个计算属性传入Provide&#xff0c;并且能够被其他组件Inject 二、实现 父组件 .…

计算机网络—OSPF单区域配置

目录 目录 1.实验环境准备 2.配置 OSPF 3.验证 OSPF 配置 4.修改 OSPF hello 和 dead 时间参数 5.OSPF缺省路由发布及验证 6.控制 OSPF DR/BDR 的选举 7.配置文件 拓扑图&#xff1a; 1.实验环境准备 基本配置以及IP编址。 <Huawei>system-view Enter system vi…

Tomcat多实例及nginx反向代理tomcat

tomcat多实例介绍&#xff1a; 什么是Tomcat多实例&#xff1f; Tomcat多实例就是指在同一台服务器上运行多个独立的tomcat实例&#xff0c;每个实例之间都是相互隔离的。每个tomcat实例都具有独立的配置文件、日志文件、应用程序和端口。通过配置不同的端口和文件目录&#xf…

如何有效避免团队内耗,提升团队整体效能

团队内耗是一个普遍存在的问题&#xff0c;它可能导致工作效率低下、沟通不畅、成员间的信任缺失&#xff0c;甚至可能导致整个团队的崩溃。 它可能源于成员间的误解、利益冲突&#xff0c;或是个人情绪的波动。 如何避免团队内耗&#xff0c;是每个团队管理者和成员都应该关…

骏聪科技:以科技之力赋能企业 打造数字时代安全基石

在当今数字化时代,信息安全和技术信息化已经成为了现代社会的一个重要议题。随着科技的迅猛发展,信息技术的普及,以及网络互联的普遍性,安全技术信息化行业也蓬勃发展。这个领域的增长不仅改变了我们的日常生活,也对各行各业产生了深远的影响。在这个发展浪潮中,苏骏聪信息科技…

景联文科技:提供行业垂直大模型训练数据

近年来&#xff0c;以大模型为代表的人工智能技术已成为国家科技实力竞争的焦点。其中垂直大模型作为重要方向&#xff0c;在相关政策引导及市场需求的驱动下&#xff0c;已展现出较强的发展活力。 行业垂直大模型是针对特定行业的需求和场景进行深度定制的。这意味着模型在训练…

SpringCloud Gateway 新一代网关

一、前言 接下来是开展一系列的 SpringCloud 的学习之旅&#xff0c;从传统的模块之间调用&#xff0c;一步步的升级为 SpringCloud 模块之间的调用&#xff0c;此篇文章为第六篇&#xff0c;即介绍 Gateway 新一代网关。 二、概述 2.1 Gateway 是什么 Gateway 是在 Spring 生…

(黑马出品_高级篇_01)SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式

&#xff08;黑马出品_高级篇_01&#xff09;SpringCloudRabbitMQDockerRedis搜索分布式 微服务技术——保护 今日目标1.初识Sentinel1.1.雪崩问题及解决方案1.2.服务保护技术对比1.3.Sentinel介绍和安装1.3.1.初识Sentinel1.3.2.安装Sentinel 1.…

Unreal发布Android在刘海屏手机上不能全屏显示问题

Unreal 4.27发布Android在刘海屏手机上不能全屏显示问题 Android设置全屏刘海屏全屏设置4.27设置刘海屏在部分手机不能显示问题 Android设置全屏 AndroidManifest.xml文件配置 ...<activity android:name"com.epicgames.ue4.GameActivity" android:label"st…

`httpsok`:轻松搞定免费的泛域名SSL/TLS证书

&#x1f525;&#x1f525;&#x1f525; httpsok&#xff1a;轻松搞定免费的泛域名SSL/TLS证书 在当今互联网时代&#xff0c;网站的安全性已成为一项不可或缺的重要因素。其中&#xff0c;采用HTTPS协议是一种有效的保护措施&#xff0c;但对于个人和团队开发者来说&#x…

Ubuntu23.10安装FFmpeg及编译FFmpeg源码

安装FFmpeg: 打开终端: 输入 sudo apt install ffmpeg 安装成功: 验证FFmpeg 默认安装位置与库与头文件位置 使用FFmpeg源码编译: 1.安装YASM sudo apt-get install yasm