《腾讯NCNN框架的模型转换x86/mips交叉编译推理》详细教程
NCNN的编译运行交叉编译
- 1.在Ubuntu上编译运行ncnn
- 1)编译ncnn x86 linux
- 2)测试ncnn x86 linux
- 2. 模型转换
- 1)onnx
- 2)pnnx
- 3.在x86上加载推理模型
- 1)准备工作
- 2)编写C++推理代码
- 3)编写Cmakelist编译
- 4.在MIPS上进行交叉编译推理
- 1)编译mips版本opencv
- 2)编译mips版本ncnn
- 3)编译上述efficientnetb0.cpp demo程序
- 4)运行推理
1.在Ubuntu上编译运行ncnn
1)编译ncnn x86 linux
// ubuntu安装依赖
sudo apt install build-essential git cmake libprotobuf-dev protobuf-compiler libomp-dev libvulkan-dev vulkan-tools libopencv-dev
// 下载ncnn以及三方库
git clone https://github.com/Tencent/ncnn.git
git submodule update --init
// 编译
cd ncnn
mkdir -p build
cd build
cmake -DCMAKE_BUILD_TYPE=Release -DNCNN_VULKAN=ON -DNCNN_BUILD_EXAMPLES=ON ..
make -j$(nproc)

// 安装到install文件夹
make install prefix=./install
检查一下install文件夹里是不是生成了bin,include和lib



2)测试ncnn x86 linux
上面我们编译的时候打开了-DNCNN_BUILD_EXAMPLES=ON,所以这里就用编译好的例子试一下,由于squeezenet提供了权重文件,所以直接测这个。

把权重文件复制到build/examples里

我们可以看一下squeezent.cpp里,ncnn需要加载.bin和.param模型文件,所以放到同一文件夹。

然后运行
cd build/examples
./squeezenet ../../images/256-ncnn.png

运行成功!
2. 模型转换
这里用pytorch onnx来举例子,简单的模型可以用ncnn编译好的bin来直接转换。
1)onnx

./onnx2ncnn a.onnx a.param a.bin
这边的param就是模型的结构描述文件,bin是模型的具体权重
如果不行尝试使用onnx-simplifier先处理一下模型
onnxsim a.onnx a_sim.onnx
然后再转换a_sim.onnx,这里不多赘述,自行尝试。
2)pnnx
如果我们直接从onnx转换到ncnn的模型经常会出现不兼容不能完全转换的情况,所以我们这边直接使用pnnx来进行模型转换。
PyTorch Neural Network eXchange
pnnx github
PyTorch Neural Network eXchange(PNNX) is an open standard for PyTorch model interoperability. PNNX provides an open model format for PyTorch. It defines computation graph as well as high level operators strictly matches PyTorch.
我们以efficientnet为例
链接: https://github.com/lukemelas/EfficientNet-PyTorch
import torch
from torchsummary import summary
from efficientnet_pytorch import EfficientNetdevice = torch.device("cuda" if torch.cuda.is_available() else "cpu")# 初始化模型
model = EfficientNet.from_pretrained('efficientnet-b0', advprop=True, num_classes=10)
model.to(device)
# 加载训练好的权重
params_dict = torch.load(r"best.pth")
# 如果训练的时候是多卡使用DataParallel来训的需要用.module.state_dict()得到权重dict
model.load_state_dict(params_dict.module.state_dict())summary(model, (3, 416, 416))
# efficientnet训练时候用了memory efficient swish激活,导出的时候换成普通swich提高兼容性
model.set_swish(memory_efficient=False)
# model_pt = torch.save(model_pt)model.eval()dummy_in = torch.randn(1, 3, 416, 416, requires_grad=True).to(device)
# 导出torchscript权重
mod = torch.jit.trace(model,dummy_in)
torch.jit.save(mod,"efb0_pnnx.pt")
pip install pnnx
pnnx ./efb0_pnnx.pt inputshape=[1,3,416,416]
然后会生成一堆文件,我们需要的就是.param和.bin文件

3.在x86上加载推理模型
1)准备工作
编译好的ncnn(看第一步)
编译好的opencv(如果不想重新编译直接sudo apt install libopencv-dev)
2)编写C++推理代码
文件结构
demo
----CMakeList.txt
----1.jpg
----src
--------effcientnetb0.cpp
----build
----bin
#include <iostream>
#include "net.h"
#include <algorithm>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <stdio.h>int main(int argc, char** argv)
{const char* img_path = argv[1];// opencv读取图片cv::Mat m = cv::imread(img_path, 1);// 图像归一化(这边视情况采用训练相同的归一化方法)m = m / 255.0 ;if (m.empty()){fprintf(stderr, "cv::imread %s failed\n", img_path);return -1;}// 创建ncnn网络ncnn::Net efficientb0; efficientb0.opt.use_vulkan_compute = true; // 加载权重if (efficientb0.load_param("model_param/efficientb0/efb0_pnnx.ncnn.param"))exit(-1);if (efficientb0.load_model("model_param/efficientb0/efb0_pnnx.ncnn.bin"))exit(-1);// 把opencv mat的data矩阵加载到ncnn mat中准备作为推理的输入ncnn::Mat in = ncnn::Mat::from_pixels_resize(m.data, ncnn::Mat::PIXEL_BGR2RGB, m.cols, m.rows, 416, 416);ncnn::Extractor ex = efficientb0.create_extractor();//在.param文件中找到输入的节点名称in0ex.input("in0", in); ncnn::Mat out;//在.param文件中找到输出的节点名称out0,推理结束ex.extract("out0", out); //输出推理结果for (int i = 0; i < out.w; i++){std::cout << i <<out[i] << std::endl;}return 0;
}
如何查看输入输出的名称如下图


3)编写Cmakelist编译
project(NCNN_DEMO)
cmake_minimum_required(VERSION 2.8.12)
set(CMAKE_BUILD_TYPE Debug)set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} "改成第一步编译好的ncnn路径xxx/ncnn/build/install/")find_package(OpenCV REQUIRED)
find_package(ncnn)
if(ncnn_FOUND)set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/bin)add_executable(efficientnetb0 src/efficientb0.cpp)target_link_libraries(efficientnetb0 ncnn ${OpenCV_LIBS})else()message(WARNING "ncnn not found, please check CMAKE_PREFIX_PATH")
endif()
# 创建build文件夹
cd build
cmake ..
make
//使用编译好的程序进行推理
./bin/effcientnetb0 ./1.jpg
输出结果
可以看到linear层的推理结果输出了,选最大的一个index就是分类结果,至此,x86上全部的推理工作就做好了。
4.在MIPS上进行交叉编译推理
Arm等平台教程比较多,我们使用mips的嵌入式开发版君正x2000进行讲解。
1)编译mips版本opencv
2)编译mips版本ncnn
3)编译上述efficientnetb0.cpp demo程序
4)运行推理
相关文章:
《腾讯NCNN框架的模型转换x86/mips交叉编译推理》详细教程
NCNN的编译运行交叉编译 1.在Ubuntu上编译运行ncnn1)编译ncnn x86 linux2)测试ncnn x86 linux 2. 模型转换1)onnx2)pnnx 3.在x86上加载推理模型1)准备工作2)编写C推理代码3)编写Cmakelist编译 4.在MIPS上进行交叉编译推理1&#x…...
关于近期安卓开发书籍阅读观后感
概述 由于笔者是Java转Android,对于安卓相关知识欠缺,故找一些入门和进阶书籍观看。笔者搜到的相关的安卓推荐博客:【Android – 学习】学习资料汇总_android书籍强烈推荐-CSDN博客相对来说比较全面。 阅读历程 笔者先阅读的是郭霖老师的…...
Servlet——个人笔记
Servlet——个人笔记 文章目录 [toc]Servlet简介Servlet命名Servlet由来实现过程 Servlet 相对 CGI 的优势简要说说什么是CGI Servlet 在IDEA中开发流程Servlet注解方式配置WebServlet注解源码WebServlet注解使用 Servlet常见容器Servlet 生命周期简介测试 Servlet 方法init()…...
富格林:戳穿虚假交易保证安全
富格林指出,虚假交易亏损骗局一直以来都是投资者的诟病。不少投资者来到这个赛道的目的铁定是为了安全盈利增值财富,因此如何去杜绝虚假交易便成了当务之急。实际上,有不少投资技巧可以为保障我们的交易安全带来一些庇护。下面富格林就给大家…...
Linux学习——文本处理工具与正则表达式
目录 一,grep 1,grep介绍 2,grep的常用选项 3,grep使用演示 1,基本使用 直接查找字符串: 使用选项 2,使用正则表达式进行匹配 1,正则表达式介绍 2,使用范例 二&…...
大厂进阶四:React源码Fiber架构解析
本文主要内容: 1、React Concurrent 2、React15架构 3、React16架构 4、Fiber架构 5、任务调度循环和fiber构造循环区别 一、React Concurrent React在解决CPU卡顿是会用到React Concurrent的概念,它是React中的一个重要特性和模块,主要的…...
MongoDB的WiredTiger存储引擎
作者:太阳 从MongoDB 3.2 开始,MongoDB实例默认的存储引擎为WiredTiger,WiredTiger存储引擎具体以下几大优点: 文档级并发 将数据持久化到磁盘 快照和checkpoint 数据压缩 本地数据加密 一、文档级别并发 1、WiredTiger使…...
windows 版本Jenkins的Jenkinsfile中共享变量
场景 jenkins部署在windows服务器上的,需要在Jenkinsfile中获取命令执行的结果存入一个变量,然后在后续的执行中使用此变量 一开始想的是定义一个环境变量,如下所示, pipeline {agent anystages {stage(test) {steps {bat for /…...
Android-->产物收集(含apk文件重命名, aab文件重命名)
以前写过修改apk生成路径和文件名的文章, 如下: AS–›Gradle 7.0.0/4.1.0/4.0/3.3/3.0 修改APK生成路径和文件名(附AAR修改方式以及分析过程)_com.android.build.gradle.internal.api.libraryvaria-CSDN博客 这种方法入侵了gradle,破坏了原有的gradle环境, 经常会导致如下问…...
matlab实现迷宫最佳路径规划
在MATLAB中实现迷宫路径的最佳路径规划,我们可以使用多种算法,其中最常见和高效的是A搜索算法(A Search Algorithm)。A*算法结合了最佳优先搜索和Dijkstra算法的优点,通过启发式函数来评估每个节点的优先级,…...
【自用】Python爬虫学习(二):网页解析的三种方式(re、bs4、xpath)
Python爬虫学习(二) 网页解析的三种方式1.正则表达式-re解析常用表达:re常用函数:在html中的运用: 2.BeautifulSoup解析常用语法:用法举例: 3.xpath解析示例代码1:示例代码2…...
从零到一:家政保洁小程序搭建全攻略与功能作用深度解析
目录 一、家政保洁小程序主要功能 二、家政保洁小程序搭建教程 (一)前期准备 (二)注册与选择工具 (三)设计与开发 (四)测试与优化 (五)发布与推广 一、…...
单元测试:为工程质量保驾护航
单元测试 单元测试是软件开发过程中确保代码质量和正确性的关键手段。它指的是对软件中的最小可测试单元(通常是函数或方法)进行验证,确保其行为符合预期。 基本概念 单元测试:验证软件中最小单元(通常是函数或方法…...
江协科技STM32学习笔记
第01章 STM32简介及开发环境搭建 1.1 STM32简介 1.1.1 STM32F103C8T6 系列:主流系列STM32F1 内核:ARM Cortex-M3 主频:72MHz RAM:20K(SRAM) ROM:64K(Flash) 供电…...
RabbitMQ再回首--往事如梦
这文章你就读吧,越读越🥸,一读一个不吱声 可靠的🐰警官:rabbitMQ,功能全面,不丢数据,体量小,容易堆积 声明exchange channel . exchangeDeclare ( String exchange , …...
头狼择校小程序
综述介绍 头狼择校,是头狼择™高校的简称,我们专注高校、大学的择校。倡导先嗅就业再择校,是预约工具和对话平台。帮您嗅招办、嗅教授、嗅学姐,预约择校有关的老师、顾问,助力考大学和考研的“双考”学生及家长了解就…...
【Electron】npm安装Electron项目失败报错问题和解决办法
前言 闲来无事,便想着研究一下Electron,没想到安装直接就卡住了 问题 npm ERR! RequestError: Hostname/IP does not match certificates altnames: Host: npm.taobao.org. is not in the certs altnames: DNS:*.tbcdn.cn, DNS:*.taobao.com, DNS:*.al…...
人工智能提示(prompt)工程入门
文章目录 人工智能提示(prompt)工程入门一、目的二、使用1、角色2、提示3、上下文4、例子5、输入6、输出 三、使用示例 人工智能提示(prompt)工程入门 一、目的 对于当前的发达的人工智能,我们可以广泛使用࿰…...
【机器学习的基本思想】模型优化与评估
【作者主页】Francek Chen 【专栏介绍】 ⌈ ⌈ ⌈Python机器学习 ⌋ ⌋ ⌋ 机器学习是一门人工智能的分支学科,通过算法和模型让计算机从数据中学习,进行模型训练和优化,做出预测、分类和决策支持。Python成为机器学习的首选语言,…...
公司电脑监控软件推荐(一口气了解8款!)一起领略电脑监控界的刀光剑影!
企业的内部管理的需求日益复杂,电脑监控软件作为提升工作效率、保障数据安全的重要工具,其重要性不言而喻。今天,我们将带您一口气了解8款顶尖的公司电脑监控软件,包括国内知名的“安企神”以及多款来自海外的优秀产品,…...
华为云AI开发平台ModelArts
华为云ModelArts:重塑AI开发流程的“智能引擎”与“创新加速器”! 在人工智能浪潮席卷全球的2025年,企业拥抱AI的意愿空前高涨,但技术门槛高、流程复杂、资源投入巨大的现实,却让许多创新构想止步于实验室。数据科学家…...
eNSP-Cloud(实现本地电脑与eNSP内设备之间通信)
说明: 想象一下,你正在用eNSP搭建一个虚拟的网络世界,里面有虚拟的路由器、交换机、电脑(PC)等等。这些设备都在你的电脑里面“运行”,它们之间可以互相通信,就像一个封闭的小王国。 但是&#…...
微信小程序之bind和catch
这两个呢,都是绑定事件用的,具体使用有些小区别。 官方文档: 事件冒泡处理不同 bind:绑定的事件会向上冒泡,即触发当前组件的事件后,还会继续触发父组件的相同事件。例如,有一个子视图绑定了b…...
在rocky linux 9.5上在线安装 docker
前面是指南,后面是日志 sudo dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo sudo dnf install docker-ce docker-ce-cli containerd.io -y docker version sudo systemctl start docker sudo systemctl status docker …...
iPhone密码忘记了办?iPhoneUnlocker,iPhone解锁工具Aiseesoft iPhone Unlocker 高级注册版分享
平时用 iPhone 的时候,难免会碰到解锁的麻烦事。比如密码忘了、人脸识别 / 指纹识别突然不灵,或者买了二手 iPhone 却被原来的 iCloud 账号锁住,这时候就需要靠谱的解锁工具来帮忙了。Aiseesoft iPhone Unlocker 就是专门解决这些问题的软件&…...
【解密LSTM、GRU如何解决传统RNN梯度消失问题】
解密LSTM与GRU:如何让RNN变得更聪明? 在深度学习的世界里,循环神经网络(RNN)以其卓越的序列数据处理能力广泛应用于自然语言处理、时间序列预测等领域。然而,传统RNN存在的一个严重问题——梯度消失&#…...
dedecms 织梦自定义表单留言增加ajax验证码功能
增加ajax功能模块,用户不点击提交按钮,只要输入框失去焦点,就会提前提示验证码是否正确。 一,模板上增加验证码 <input name"vdcode"id"vdcode" placeholder"请输入验证码" type"text&quo…...
JUC笔记(上)-复习 涉及死锁 volatile synchronized CAS 原子操作
一、上下文切换 即使单核CPU也可以进行多线程执行代码,CPU会给每个线程分配CPU时间片来实现这个机制。时间片非常短,所以CPU会不断地切换线程执行,从而让我们感觉多个线程是同时执行的。时间片一般是十几毫秒(ms)。通过时间片分配算法执行。…...
使用Matplotlib创建炫酷的3D散点图:数据可视化的新维度
文章目录 基础实现代码代码解析进阶技巧1. 自定义点的大小和颜色2. 添加图例和样式美化3. 真实数据应用示例实用技巧与注意事项完整示例(带样式)应用场景在数据科学和可视化领域,三维图形能为我们提供更丰富的数据洞察。本文将手把手教你如何使用Python的Matplotlib库创建引…...
Netty从入门到进阶(二)
二、Netty入门 1. 概述 1.1 Netty是什么 Netty is an asynchronous event-driven network application framework for rapid development of maintainable high performance protocol servers & clients. Netty是一个异步的、基于事件驱动的网络应用框架,用于…...
