码农知识堂 - 1000bd
  •   Python
  •   PHP
  •   JS/TS
  •   JAVA
  •   C/C++
  •   C#
  •   GO
  •   Kotlin
  •   Swift
  • Ncnn框架在c++的推理及其认识


    目录

    认识:

    关于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

    以经典的分类网络为例

    1. // 网络加载
    2. ncnn::Net squeezenet;
    3. squeezenet.load_param("squeezenet_v1.1.param");
    4. squeezenet.load_model("squeezenet_v1.1.bin");
    5. // 数据预处理
    6. ncnn::Mat in = ncnn::Mat::from_pixels_resize(image.data, ncnn::Mat::PIXEL_BGR, image.cols, image.rows, 227, 227);
    7. const float mean_vals[3] = { 104.f, 117.f, 123.f };
    8. in.substract_mean_normalize(mean_vals, 0);
    9. // 网络推理
    10. ncnn::Extractor ex = squeezenet.create_extractor();
    11. ex.input("data", in);
    12. ncnn::Mat out;
    13. 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的一个递归的过程。

     

  • 相关阅读:
    虚拟机安装CentOS 7
    Java后端使用POST请求向mysql中插入Json数据的问题
    ElasticSearch中关于Nasted嵌套查询的介绍:生动案例,通俗易懂,彻底吸收
    web前端 html+css+javascript游戏网页设计实例 (网页制作课作业)
    docker-compose 安装 Prometheus + Grafana 配置监控页面
    二叉树的Morris遍历
    Java版企业电子招标采购系统源码—企业战略布局下的采购寻源
    纷享销客连接型CRM怎么样?
    Python杂谈--关于iter迭代器的一些讨论
    如果你还没玩过Docker Stack管理服务,你已经out了,(送Portainer集群管理教程)
  • 原文地址:https://blog.csdn.net/PHILICS7/article/details/125430079
  • 最新文章
  • 【FHE】我们如何实现同态加密推理(八):SiLU 的密文化——两条路径,和一个 8 字节的开关
    SQLcl 中 c/old/new 替换变量为何失效?先定位再替换
    不让模型写作文,直接从它脑子里读答案:Jev 决策在 .NET 的两条路线
    Halo插件:支持GitHub的图床附件策略
    电视投屏界的“一股清流”!SimpleTVCast 6.0.0-beta 抢先体验:无需TV端App,界面大换血!✨
    华三VXLAN集中式网关实战指南:Spine多活网关 + 双活接入(M-LAG)
    软件更好写之后口碑会更重要
    大 O、大 Omega、大 Theta 的区别,O(n) 复杂度是什么意思
    Java标签跳转:一个鲜为人知但却很实用的小技巧
    多智能体系统论文速读
  • 热门文章
  • 十款代码表白小特效 一个比一个浪漫 赶紧收藏起来吧!!!
    奉劝各位学弟学妹们,该打造你的技术影响力了!
    五年了,我在 CSDN 的两个一百万。
    Java俄罗斯方块,老程序员花了一个周末,连接中学年代!
    面试官都震惊,你这网络基础可以啊!
    你真的会用百度吗?我不信 — 那些不为人知的搜索引擎语法
    心情不好的时候,用 Python 画棵樱花树送给自己吧
    通宵一晚做出来的一款类似CS的第一人称射击游戏Demo!原来做游戏也不是很难,连憨憨学妹都学会了!
    13 万字 C 语言从入门到精通保姆级教程2021 年版
    10行代码集2000张美女图,Python爬虫120例,再上征途
小工具 小游戏
Copyright © 2022 侵权请联系2656653265@qq.com    京ICP备2022015340号-1

京公网安备 11010502049817号