Ubuntu16.04---腾讯NCNN框架入门到应用
来源:互联网 发布:cr2什么软件打开 编辑:程序博客网 时间:2024/05/18 03:41
Ubuntu16.04—腾讯NCNN框架入门到应用
前言
两天前腾讯发布NCNN深度学习框架后,发现可能有些同学对如何使用这些框架并不是十分的了解,一方面这是一个新的框架,另一方面Tencent出的文档对一些细节没有叙述,可能大牛们觉得很容易的步骤,我们往往会卡在那里,所以写下这篇博客来帮助一些对NCNN框架不是很熟悉的人来快速入门。
NCNN源码的地址为https://github.com/Tencent/ncnn
在Ubuntu上安装NCNN
1. 下载编译源码
ruyiwei@ruyiwei:~/code$ git clone https://github.com/Tencent/ncnn
下载完成后,需要对源码进行编译
cd ncnnmkdir build && cd buildcmake ..make -jmake install
执行完毕后我们可以看到
Install the project...-- Install configuration: "release"-- Installing: /home/ruyiwei/code/ncnn/build/install/lib/libncnn.a-- Installing: /home/ruyiwei/code/ncnn/build/install/include/blob.h-- Installing: /home/ruyiwei/code/ncnn/build/install/include/cpu.h-- Installing: /home/ruyiwei/code/ncnn/build/install/include/layer.h-- Installing: /home/ruyiwei/code/ncnn/build/install/include/mat.h-- Installing: /home/ruyiwei/code/ncnn/build/install/include/net.h-- Installing: /home/ruyiwei/code/ncnn/build/install/include/opencv.h-- Installing: /home/ruyiwei/code/ncnn/build/install/include/platform.h
我们进入 ncnn/build/tools 目录下,如下所示,我们可以看到已经生成了 caffe2ncnn 可ncnn2mem这两个可执行文件,这两个可执行文件的作用是将caffe模型生成ncnn 模型,并且对模型进行加密,具体的使用方法我门在下一节讲述。
ruyiwei@ruyiwei:~/code/ncnn/build/tools$ lltotal 3024drwxrwxr-x 3 ruyiwei ruyiwei 4096 7月 27 15:36 ./drwxrwxr-x 6 ruyiwei ruyiwei 4096 7月 27 15:36 ../-rwxrwxr-x 1 ruyiwei ruyiwei 833720 7月 27 15:36 caffe2ncnn*-rw-rw-r-- 1 ruyiwei ruyiwei 1102486 7月 27 15:36 caffe.pb.cc-rw-rw-r-- 1 ruyiwei ruyiwei 894690 7月 27 15:36 caffe.pb.hdrwxrwxr-x 4 ruyiwei ruyiwei 4096 7月 27 15:36 CMakeFiles/-rw-rw-r-- 1 ruyiwei ruyiwei 1018 7月 27 15:36 cmake_install.cmake-rw-rw-r-- 1 ruyiwei ruyiwei 9353 7月 27 15:36 Makefile-rwxrwxr-x 1 ruyiwei ruyiwei 228032 7月 27 15:36 ncnn2mem*
2. 将caffe下Alexnet网络模型转换为NCNN模型
我们在测试的过程中需要caffemodel以及deploy.prototxt,所以我们再将caffe模型转换为NCNN模型的时候,同样也需要caffemodel以及deploy.prototxt这两个文件,为了方便,我们使用AlexNet为例讲解。
alexnet 的 deploy.prototxt 可以在这里下载 https://github.com/BVLC/caffe/tree/master/models/bvlc_alexnet
alexnet 的 caffemodel 可以在这里下载 http://dl.caffe.berkeleyvision.org/bvlc_alexnet.caffemodel
由于NCNN提供的转换工具只支持转换新版的caffe模型,所以我们需要利用caffe自带的工具将旧版的caffe模型转换为新版的caffe模型后,在将新版本的模型转换为NCNN模型.
旧版本caffe模型->新版本caffe模型->NCNN模型
2.1 旧版caffe模型转新版caffe模型
我们执行如下命令.[要记得修改路径]
ruyiwei@ruyiwei:~/code/ncnn/build/tools$ ~/caffe/build/tools/upgrade_net_proto_text deploy.prototxt new_deplpy.prototxt
ruyiwei@ruyiwei:~/code/ncnn/build/tools$ ~/caffe/build/tools/upgrade_net_proto_binary bvlc_alexnet.caffemodel new_bvlc_alexnet.caffemodel
上面的命令需要根据自己的caffe位置进行修改
执行后,就可以生成新的caffe模型.
因为我们每次检测一张图片,所以要对新生成的deploy.prototxt进行修改:第一个 dim 设为 1
layer { name: "data" type: "Input" top: "data" input_param { shape: { dim: 1 dim: 3 dim: 227 dim: 227 } }}
2.2 新版caffe模型转ncnn模型
ruyiwei@ruyiwei:~/code/ncnn/build/tools$./caffe2ncnn new_deplpy.prototxt new_bvlc_alexnet.caffemodel alexnet.param alexnet.bin
执行上面命令后就可以生成NCNN模型需要的param 与bin 文件.
ruyiwei@ruyiwei:~/code/ncnn/build/tools$ lltotal 717492drwxrwxr-x 3 ruyiwei ruyiwei 4096 7月 27 16:13 ./drwxrwxr-x 6 ruyiwei ruyiwei 4096 7月 27 15:36 ../-rw-rw-r-- 1 ruyiwei ruyiwei 243860928 7月 27 16:13 alexnet.bin-rw-rw-r-- 1 ruyiwei ruyiwei 1583 7月 27 16:13 alexnet.param-rw-rw-r-- 1 ruyiwei ruyiwei 243862414 7月 27 09:28 bvlc_alexnet.caffemodel-rwxrwxr-x 1 ruyiwei ruyiwei 833720 7月 27 15:36 caffe2ncnn*-rw-rw-r-- 1 ruyiwei ruyiwei 1102486 7月 27 15:36 caffe.pb.cc-rw-rw-r-- 1 ruyiwei ruyiwei 894690 7月 27 15:36 caffe.pb.hdrwxrwxr-x 4 ruyiwei ruyiwei 4096 7月 27 15:36 CMakeFiles/-rw-rw-r-- 1 ruyiwei ruyiwei 1018 7月 27 15:36 cmake_install.cmake-rw-rw-r-- 1 ruyiwei ruyiwei 3629 6月 6 21:40 deploy.prototxt-rw-rw-r-- 1 ruyiwei ruyiwei 9353 7月 27 15:36 Makefile-rwxrwxr-x 1 ruyiwei ruyiwei 228032 7月 27 15:36 ncnn2mem*-rw-rw-r-- 1 ruyiwei ruyiwei 243862660 7月 27 16:03 new_bvlc_alexnet.caffemodel-rw-r--r-- 1 ruyiwei ruyiwei 3662 7月 27 16:03 new_deplpy.prototxt
3. 对模型参数加密
得到的alexnet.param是明文可见的,往往发布的过程需要对这些文件进行加密,NCNN提供了对应的加密工具,ncnn2mem,
ruyiwei@ruyiwei:~/code/ncnn/build/tools$ ./ncnn2mem alexnet.param alexnet.bin alexnet.id.h alexnet.mem.h
最后可以生成 alexnet.param.bin 这样的二进制加密文件.
对于加密文件的读取也和原来不同,在源码中,非加密param读取方式为
ncnn::Net net;net.load_param("alexnet.param");net.load_model("alexnet.bin");
加密param.bin读取方式为
ncnn::Net net;net.load_param_bin("alexnet.param.bin");net.load_model("alexnet.bin");
4. 编译NCNN例程
前面介绍了如何将caffe模型转为NCNN模型并且加密,最后我们来编译NCNN的例程,这样可以更直观的运行或者理解NCNN.
首先我们需要进入ncnn/examples目录
新建一个makefile,内容如下,最重要的是,NCNN例程序只支持opencv2,不支持opencv3.
NCNN = /home/ruyiwei/code/ncnnOPENCV = /home/ruyiwei/Downloads/opencv-2.4.13INCPATH = -I${NCNN}/build/install/include \ -I${OPENCV}/modules/objdetect/include \ -I${OPENCV}/modules/highgui/include \ -I${OPENCV}/modules/imgproc/include \ -I${OPENCV}/modules/core/includeLIBS = -lopencv_core -lopencv_highgui -lopencv_imgproc \ -fopenmp -pthreadLIBPATH = -L${OPENCV}/build/lib%:%.cpp $(CXX) $(INCPATH) $(LIBPATH) $^ ${NCNN}/build/install/lib/libncnn.a $(LIBS) -o $@
在当前目录执行
ruyiwei@ruyiwei:~/code/ncnn/examples$ ./squeezenet test.jpg
可得到如下结果
ruyiwei@ruyiwei:~/code/ncnn/examples$ ./squeezenet test.jpg 404 = 0.990161908 = 0.004498405 = 0.004008
test.jpg 为下图所示:
为了可以更直观的显示,我们修改代码如下:
#include <stdio.h>#include <algorithm>#include <vector>#include <opencv2/core/core.hpp>#include <opencv2/highgui/highgui.hpp>using namespace std;using namespace cv;#include "net.h"static int detect_squeezenet(const cv::Mat& bgr, std::vector<float>& cls_scores){ 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(bgr.data, ncnn::Mat::PIXEL_BGR, bgr.cols, bgr.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.set_light_mode(true); ex.input("data", in); ncnn::Mat out; ex.extract("prob", out); cls_scores.resize(out.c); for (int j=0; j<out.c; j++) { const float* prob = out.data + out.cstep * j; cls_scores[j] = prob[0]; } return 0;}static int print_topk(const std::vector<float>& cls_scores, int topk, vector<int>& index_result, vector<float>& score_result){ // partial sort topk with index int size = cls_scores.size(); std::vector< std::pair<float, int> > vec; vec.resize(size); for (int i=0; i<size; i++) { vec[i] = std::make_pair(cls_scores[i], i); } std::partial_sort(vec.begin(), vec.begin() + topk, vec.end(), std::greater< std::pair<float, int> >()); // print topk and score for (int i=0; i<topk; i++) { float score = vec[i].first; int index = vec[i].second; index_result.push_back(index); score_result.push_back(score); //fprintf(stderr, "%d = %f\n", index, score); } return 0;}static int load_labels(string path, vector<string>& labels){ FILE* fp = fopen(path.c_str(), "r"); while (!feof(fp)) { char str[1024]; fgets(str, 1024, fp); //¶ÁÈ¡Ò»ÐÐ string str_s(str); if (str_s.length() > 0) { for (int i = 0; i < str_s.length(); i++) { if (str_s[i] == ' ') { string strr = str_s.substr(i, str_s.length() - i - 1); labels.push_back(strr); i = str_s.length(); } } } } return 0;}int main(int argc, char** argv){ const char* imagepath = argv[1]; vector<string> labels; load_labels("synset_words.txt", labels); cv::Mat m = cv::imread(imagepath, CV_LOAD_IMAGE_COLOR); if (m.empty()) { fprintf(stderr, "cv::imread %s failed\n", imagepath); return -1; } std::vector<float> cls_scores; detect_squeezenet(m, cls_scores); vector<int> index; vector<float> score; print_topk(cls_scores, 3, index, score); for (int i = 0; i < index.size(); i++) { cv::putText(m, labels[index[i]], Point(50, 50 + 30 * i), CV_FONT_HERSHEY_SIMPLEX, 1.2, Scalar(0, 100, 200), 2, 8); } imshow("m", m); imwrite("test_result.jpg", m); waitKey(0); return 0;}
这样就可以直观的显示出具体的类别,而不是数字,结果如下:
感谢
https://github.com/guozhongluo/ncnn-vs2015-examples-demo
https://github.com/Tencent/ncnn/wiki
- Ubuntu16.04---腾讯NCNN框架入门到应用
- Ubuntu系统NCNN框架入门指南
- 腾讯优图开源项目ncnn
- 腾讯优图开源深度学习框架ncnn,主打手机端,同类cpu框架最快
- 腾讯优图NCNN框架在windows下的vs2013配置
- 腾讯开源ncnn:示例程序运行
- 腾讯开源ncnn:Ubuntu下运行示例
- ubuntu16.04 latex应用
- 腾讯云ubuntu16.04 搭建svn
- 入门DWR框架应用
- ubuntu16.04 应用下载随记
- Spring入门到应用
- 腾讯开源ncnn:caffemodel转化为.param和.bin文件
- 腾讯开源ncnn:自己的模型运行结果与caffe的结果不一样
- spring框架入门到熟练
- Quartz 框架快速入门(三)--应用到WEB项目中
- NClay框架MVC应用入门
- NClay框架MVC应用入门
- Linux安装oracle数据库(静默模式)
- 提取文档中的指定内容
- 工作五年还在一线写代码丢人吗
- Snackbar使用详解
- hydra框架之责任链设计模式
- Ubuntu16.04---腾讯NCNN框架入门到应用
- 看spring源码,spring源码解读,博客整理
- 使用ajax提交表单有很多优势 (下面是一个上传文件的实例 new FormData class)
- 利用Aforge做的摄像监控程序(带视频差异录像)
- sqoop导入数据出错ERROR manager.SqlManager: Error executing statement: java.sql.SQLException: Access denied
- 在el表达式中引用变量进行比较
- Power of Matrix UVA
- Form表单生成数字、字母验证码_Ajax--------struts2
- 根据二叉树的先序和中序来重建二叉树-C++