Ncnn框架在c++的推理及其认识

3 篇文章 0 订阅

目录

认识:

关于NCNN的模型转换:

关于NCNN模型文件的认识:

在c++下的推理:

认识:

        ncnn是腾讯优图推出的在手机端极致优化的高性能神经网络前向计架框架,适用于手机端的CPU计算且无需依赖第三方计算库,ncnn只用作推理而非边训练边推理。

ncnn (GitHub地址:GitHub - Tencent/ncnn: ncnn is a high-performance neural network inference framework optimized for the mobile platform ncnn 从设计之初深刻考虑手机端的部署和使用。无第三方依赖,跨平台,手机端 CPU 的速度快于目前所有已知的开源框架。基于 ncnn,开发者能够将深度学习算法轻松移植到手机端高效执行,开发出人工智能 APP,将 AI 带到你的指尖。ncnn 目前已在腾讯多款应用中使用,如 QQ,Qzone,微信,天天P图等。

同时由于NCNN模型是全部用c++来写的,所以它可以跨平台,比如常见的嵌入式设备上可以通用,另外我了解到它的负责人是nihui大佬,nihui群里更是大佬云集。

关于NCNN的模型转换:

先附上脚本转换网站(daquexian前辈):

一键转换 Caffe, ONNX, TensorFlow 到 NCNN, MNN, Tengine (convertmodel.com)

这是一个在线的模型转换网站

对于Pytorch模型:

一种是可以通过PNNX直接转ncnn,pnnx是一个工具,支持动态尺寸输入,目前只支持torchscript转ncnn,且只支持torch.trace的torchscript。这种网上资料较少。

另一种则是通过中间模型onnx转ncnn,这种网上资料比起pnnx转ncnn更多。

关于NCNN模型文件的认识:

param和bin

param是网络结构文件,而bin则是参数文件

查看网络结构是不是同一个可用netron.app在线网站查看

以打开mobiefacenet的param

第一行的7767517为magic num

第二行的的160为网络层数,从第三行开始数,172为blob数量,相当于一个数据节点,带输入和输出。

从第三行开始为网络层,第一列为网络层类型,第二列为网络层名,第三列为bottom_count,第四列为top_count,bottom_count为该层在多少个网络层之下(相当于输入的blob数),top_count为该层在多少个网络层之上(理解为输出的blob数),后面的列依次为bottom_name,blob_name 以及该层的所带的参数,如果bottom_count为0则可以省略正如input那一层。

在c++下的推理:

 前提,在电脑上装好环境,比如已经编译好了的ncnn库,protobuf,opencv库

ncnn环境配置参照:

Windows下ncnn环境配置(VS2019)_逮仔的博客-CSDN博客_ncnn vs2019

以经典的分类网络为例

// 网络加载
ncnn::Net squeezenet;
squeezenet.load_param("squeezenet_v1.1.param");
squeezenet.load_model("squeezenet_v1.1.bin");

// 数据预处理
ncnn::Mat in = ncnn::Mat::from_pixels_resize(image.data, ncnn::Mat::PIXEL_BGR, image.cols, image.rows, 227, 227);
const float mean_vals[3] = { 104.f, 117.f, 123.f };
in.substract_mean_normalize(mean_vals, 0);

// 网络推理
ncnn::Extractor ex = squeezenet.create_extractor();
ex.input("data", in);
ncnn::Mat out;
ex.extract("prob", out);

具体步骤

  1. 网络加载
    1. load_param
    2. load_model
  2. 数据预处理
    1. from_pixels_resize
    2. substract_mean_normalize
  3. 网络推理
    1. create_extractor
    2. input
    3. extract
  4. 每一层的推理(隐含在模型内的)

注意的地方:

作为初学者可以把ncnn的推理看做是一个黑盒子,只关注网络的输入和输出,本例子网络中的data则是输入层的名字,prob则是输出层的名字,关于怎么知道不同训练过程的输入和输出网络层的名字?用netron可视化观察,同时还能看到它输出的通道数知道自己该用什么样的数据结构去接受输出内容。

在netron的可视化下

 最后输出名为518,输出通道数量为512

最后,整体看来确实简单,推理实际上是forward的一个递归的过程。

  • 4
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值