记录ncnn导出模型的权重读取的一点思路

2023-11-14

ncnn的.param和.bin文件的读取,参考这个基本上可以触类旁通


前言

大概找了找全网使用ncnn框架导出权重模型的博客(可以参考的只有2篇,一篇过时了,没法儿使用;另一篇的函数重载似乎提及了也没什么用处,因为另一篇提到的函数重载事实上在ncnn中已经代码体现了,但是未能深入逐层输出,而且我运行了发现出了bug),翻了ncnn的github,有大量技术发烧友都在追求ncnn工具导出后的FP16、INT8模型的权重、偏置参数读取,然而苦于ncnn框架规模实在太大,C++技术高度密集,权重输出确实不太容易。

我在本文中利用线上开源的onnx转ncnn FP16的网站将nanodet-plus.onnx模型转变为.param和.bin,并在此基础上对ncnn进行修改和编译,验证框架使用我修改后的批量目标检测的nanodet.cpp,该部分代码不提供,我只提供结果。另外,不对ncnn进行深入分析,本文只提供如何输出权重值的思路和代码实现。再次重申:

本文只提供:

1、ncnn中我用于输出权重值的修改后若干文件(您可以替换之后重现我的结果);

2、nanodet-plus在ncnn框架下使用ncnn格式的模型作为批量图片的目标检测的一个输入(图片是另一个输入)的结果(您可以使用nanodet-plus官方原装的单张图片的目标检测作为测试框架,道理一样,不用纠结,我懒得改了);

3、提供权重输出的思路(相信会对你有帮助);

本文不提供:

1、批量图片的目标检测代码;

2、不提供算法优化;

3、不提供整个模型输出的方案;


一、ncnn的.param格式解读

这边可以直接参考nihui的ncnn github官网来解读,不过要是不想看英文,想直接快速上手,直接看下面。

图片来源:https://blog.csdn.net/qq_25105061/article/details/131457787 

layer:描述网络一共有多少层,例如:ReLU、Conv 都叫一个layer;

blob:表示数据节点,例如一个Conv就有一个输入blob和输出blob;

bottom_count:当前层接收输入blob的层个数;

top_count:将当前层的输出作为输入blob的层个数;

bottom_name:当前层输入数据的生产层名字;

blob_name: 消费当前的输出结果的层名字;

差不多够用!继续往下!

二、ncnn中眼花缭乱的load_param和load_model

根据文件引用关系:net.cpp的line1293、line1736分别指向load_param和load_model的最接近Layer类的模型和参数加载函数,随后lin1293的load_param指向line1449的pd.load_param(dr),该函数需要到paramdict.cpp中寻找,找到int Net::load_param()从而配合line1293该函数的其余内容完整输出.param文件。随后看load_model,到net.cpp的line1763,找到layer->load_model,该函数需要到layer.cpp和layer.h中寻找定义和声明,layer就是基类,因此我们随便找一个基于Layer基类的派生类Convolution,寻找convolution.cpp,查找其内的load_param和load_model,我们只关注load_model,因为load_param过于直观了,load_model需要回到modelbin.cpp中查找Mat ModelBin::load(int w, int h, int type) const,我们根据“Mat mret = m.reshape(w, h);”查找mat.cpp中的reshape函数,并设置使用指针来输出权重值。

1. net.cpp

图示cout代码输出.param中的layer_cout和blob_cout。

图示cout代码用于确认逐层layer参数载入,且可以确认参数载入来自于Layer类,由于Layer已经是基类,因此我们随便选择Layer派生类比如Convolution。 

2. convolution.cpp

这部分是load_param的内容。

这部分是load_model的内容。

我们可以看到weight_data和bias_data都通过mb类实例下的load函数得到,我们可以确认mb实例是对ModelBin的例化。接下来我们看ModelBin类定义。

3. modelbin.cpp

有效的部分是该load函数,我对此处进行了修改,原内容直接返回m.reshape(w, h),我多增加一步以确定是否经过该步。接下来我们确认确实是reshape函数起作用,因此我们需要查找Mat类定义。

4. net.cpp

其中起作用的包含两部分: 

 

此处红色框内我对权重值进行了打印!

最后的部分输出结果:

三、ncnn重新编译步骤和nanodet-plus编译运行

其实前面两部分基本上对输出权重做了流程化的介绍,接下来就是把ncnn中已经更改的文件、终端输出的内容和实现步骤讲讲,该拿出来的拿出来,该讲明白的讲明白。

1. 实现步骤

从添加更改文件后的命令如下:

1、重新编译并安装ncnn:

mkdir build

cd build

cmake ..

make -j32

make install

2、增加路径:export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH

3、在编译运行nanodet-ncnn工程之前:

export ncnn_DIR=/root/autodl-tmp/ncnn/build/install/lib/cmake/ncnn

4、清除./nanodet/demo_ncnn/build的内容:rm -rf *

5、加入.param和.bin:cp -r ../nanodet.param ../nanodet/model ./

6、编译工程:

cmake ..

make

7、运行工程(以批量检测为例):

./nanodet_demo 1 /root/autodl-tmp/nanodet/demo_ncnn/pic/(这个参考nanodet官方)

2. 文件内容

我应该已经上传到csdn了。


总结

简单对ncnn的权重参数进行了输出,够累,只能说对AI编译器的理解又进了一步!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

记录ncnn导出模型的权重读取的一点思路 的相关文章

  • 记一次事务报错问题 Transaction synchronization is not active

    问题场景 在一次请求的返回结果中出现了这个错误信息 Transaction synchronization is not active 意思是 事务同步器没有激活 看着不像是业务代码里返回的提示 猜测是spring事务框架报出来的异常没有被
  • 基于SRS的视频直播服务器搭建

    srs提供的一个demo实例 包括实时流的rtmp播放 hls播放 视频会议 ffmpeg视频变换 jwplayer播放 OSMF播放 vlc播放等等功能 下面是在Centos 6 x环境下的编译搭建流程 1 下载或更新源码或者使用git更

随机推荐

  • MVC项目案例

    MVC项目 1 需求 访问链接 http localhost 8080 car get 得到JSON数据 name 保时捷 color 红色 price 641000 0 2 项目结构 cn tedu 放启动类 存子包 cn tedu se
  • [nodejs] 运行的nodejs代码走代理连接外网

    1 背景 nodejs后端调用三方服务sdk 运行主机在公司内外有网址过滤 无法连接到三方服务地址 设置代码走代理后服务调用正常 2 方法 修改node modules rest facade src Client js代码 让网络连接能够
  • Xorm 使用手册,增删改查之查

    Xorm 使用手册 增删改查之查 Xorm轻松学习 个人博客站点 简书 猫轻王 https www jianshu com u 6cce817646be 掘金 猫轻王 https juejin cn user 164091868034745
  • R 实践深度学习

    特点 将帮助您了解流行的深度学习架构及其在 R 中的变体 并为它们提供现实生活中的示例 涵盖了用于预测和分类的基本深度学习技术和概念 将了解神经网络 深度学习架构以及使用 R 实现深度学习的基础知识 将引导您使用重要的深度学习库 如 Ker
  • 4.28黄金双线收官会跌吗?今日如何稳健布局?

    近期有哪些消息面影响黄金走势 双线收官黄金多空该如何研判 黄金消息面解析 现货黄金价格周五 4月28日 小幅收跌 在美国公布第一季GDP增速低于预期后 金价在过去五个交易日内第四次收于2000美元下方 在今年初高通胀 利率继续上行和银行业危
  • 数字通信实验1 调制解调的matlab实现_实验要求

    实验1 调制解调的matlab实现 一 实验目的 掌握2ASK 2FSK 2PSK 2DPSK的调制解调实现流程 二 实验内容 完成2ASK相干解调的收发端完整程序 并画出已调制信号波形 功率谱密度波形 接收端各关键点波形 分别完成2FSK
  • 经验分享:如何运用R的MICE包对数据集中不同变量采用不同方法及跳过部分变量进行多重插补

    运用R的MICE包对数据集进行多重插补 multiple imputation 遇到两个具体需求 1 只需针对缺失值较高的部分变量而不是全部变量进行填充 但仍想将全部变量纳入数据集中 2 对于不同的具体变量 采用不同的多重插补具体方法 如处
  • 微信小程序——如何获取到输入框的值

    在微信小程序中 可以通过以下几种方式来获取输入框的值 使用 bindinput 绑定输入事件 通过 event detail value 获取输入框的值 具体操作如下
  • 拔叉零件的加工工艺,设计18铣槽的铣床夹具

    目 录 一 序言 1 二 零件的分析 3 1 零件的作用 3 2 零件的工艺分析 3 三 确定毛坯 4 四 工艺规程设计 5 五 夹具设计 14 六 总结 17 七 参考文献 18 一 序 言 机械制造工艺学课程设计使我们学完了大学的全部基
  • mock拦截axios请求,以及axios请求拦截设置token

    直接上源码
  • 投中网发布!持安科技荣登中国企业服务产业最佳投资案例TOP10

    近日 2022年度投中榜发布 持安科技凭借业内领先的零信任产品创新力 出众的方案落地实力及广阔的市场发展潜力 成功入选 投中2022年度中国企业服务产业最佳投资案例TOP10 投中榜 是投中信息秉承专业 严谨 客观 公正的原则 对中国私募股
  • 算法通过村第八关-树(深度优先)白银笔记

    文章目录 前言 1 最大深度问题 2 判断平衡树 3 最小深度 4 N叉树的最大深度 总结 前言 提示 我的整个生命 只是一场为了提升社会地位的低俗斗争 埃莱娜 费兰特 失踪的孩子 这一关我们看一些比较特别的题目 关于二叉树的深度和高度问题
  • 笔记-Flutter 之点击空白处取消TextField焦点

    本人是做iOS开发的 点击空白处取消TextField焦点这个需求是非常简单的 在学习Flutter过程中 面对这个需求走了不少弯路 现在得到了一个感觉不错的解决方案 这里和大家分享一下 也希望对小伙伴们有所帮助 GestureDetect
  • 程序设计语言-软件设计(二十一)

    数据结构与算法 二十 快速排序 堆排序 四 https blog csdn net ke1ying article details 129269655 这篇主要讲的是 编译与解释 文法 正规式 有限自动机 表达式 传值与传址 多种程序语言特
  • Taylor公式和插值多项式

    Taylor公式和插值多项式 笔记总结自 复旦大学 陈纪修 数学分析 课程 第5章第3节 Taylor公式和插值多项式 文章目录 Taylor公式和插值多项式 一 Taylor公式 带Peano余项的Taylor公式 带Lagrange余项
  • java代码实现分页_Java分页实现(示例代码)

    首先我们要清楚java分页的思路 第一我们要明白前端页面需要向java后台传递当前页码数以及每页显示多少条数据 第二java后台代码需要向前端页面传递每页显示的数据 以及总条数以及总页数 代码如下 首先我们要创建一个分页类用来存储数据 pu
  • 汇编——寄存器的分类和功能

    在汇编中 个人感觉最重要的部分其实就是寄存器了 这次我们了解一下寄存器的分类和功能 先说一下寄存器是什么吧 其实就是一部分的空间 我们可以使用这些空间来存储内容 寄存器的空间都是16位的 80x86中 后来有增长 也就是1个字的空间 堆栈则
  • Google Earth Engine(GEE) 03-矢量数据类型

    Google Earth Engine GEE 03 矢量数据类型 GEE基本语法 Geometry Dictionary Feature和FeatureCollection之间的关系 Dictionary Feature 常用函数 Fea
  • day--03springmvc

    回顾 1 响应 页面跳转 controller方法的字符串返回值 使用Model对象进行数据共享 默认是存储在request域对象中 使用ModelAndView对象 直接响应数据 controller方法返回的是普通字符串 control
  • 记录ncnn导出模型的权重读取的一点思路

    ncnn的 param和 bin文件的读取 参考这个基本上可以触类旁通 前言 大概找了找全网使用ncnn框架导出权重模型的博客 可以参考的只有2篇 一篇过时了 没法儿使用 另一篇的函数重载似乎提及了也没什么用处 因为另一篇提到的函数重载事实