ncnn的编译和使用

1.opencv

要做图像识别首先编译opencv2.4。官网下载opencv2.4

1 unzip opencv-3.2.0.zip
2 cd ~/opencv-3.2.0

3.编译opencv  
cd ~/opencv-3.2.0
mkdir build
cd build
cmake …
make -j8

如果出现这个错误:

CMakeFiles/Makefile2:890: recipe for target 'modules/core/CMakeFiles/opencv_core.dir/all' failed
make[1]: *** [modules/core/CMakeFiles/opencv_core.dir/all] Error 2
Makefile:160: recipe for target 'all' failed
make: *** [all] Error 2

解决方案参考:https://stackoverflow.com/questions/40322301/compile-opencv-3-on-ubuntu-16-04-linking-error-usr-lib-x86-64-linux-gnu-libsox

2.ncnn的编译

git clone https://github.com/Tencent/ncnn
cd ncnn
mkdir build && cd build
cmake ..
make -j
make install

3.模型的转化

下载的alexnet模型要先转化成新版的caffemodel,随后转化成.bin和.param文件
https://github.com/Tencent/ncnn/wiki/ncnn-组件使用指北-alexnet
如果你想量化这个模型,可以参考
https://github.com/BUG1989/caffe-int8-convert-tools
最后也是生成.bin和.param,生成的bin文件大约是源文件的1/4。

4.使用模型进行测试

需要自己新建一个目录,编写.cpp文件,然后写一个CMakeLists.txt进行编译。
CMakeLists.txt如下:

cmake_minimum_required(VERSION 3.5)
find_package(OpenCV REQUIRED core highgui imgproc)


#include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../src)
#include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../src)
include_directories(/home/zyr/quantize/ncnn/build/install/include)
link_directories(/home/zyr/quantize/ncnn/build/install/lib)

FIND_PACKAGE( OpenMP REQUIRED)  
if(OPENMP_FOUND)  
    message("OPENMP FOUND")  
    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")  
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")  
    set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${OpenMP_EXE_LINKER_FLAGS}")  
endif()  

add_executable(classify classify.cpp)

target_link_libraries(classify ncnn ${OpenCV_LIBS})

classify.cpp例子:
https://github.com/Tencent/ncnn/wiki/ncnn-组件使用指北-alexnet


#include <iostream>
#include <fstream>

#include <stdio.h>
#include <algorithm>
#include <vector>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include "opencv2/imgproc/imgproc.hpp"

#include "net.h"

using namespace std;

int main(){
    string img_path = "000002.jpg";
    cv::Mat img = cv::imread(img_path, CV_LOAD_IMAGE_COLOR);
    cv::Mat img2;
    int input_width = 227;
    int input_height = 227;
    // resize图片大小 resize到alexnet的输入尺寸
    cv::resize(img, img2, cv::Size(input_width, input_height));

    // 加载转换并且量化后的alexnet网络
    ncnn::Net net;
    net.load_param("alexnet.param");
    net.load_model("alexnet.bin");
    // 把opencv的mat转换成ncnn的mat
    ncnn::Mat input = ncnn::Mat::from_pixels(img2.data, ncnn::Mat::PIXEL_BGR, img2.cols, img2.rows);
    // ncnn前向计算
    ncnn::Extractor extractor = net.create_extractor();
    extractor.input("data", input);
    ncnn::Mat output;
    extractor.extract("prob", output);
    // 输出预测结果
    ncnn::Mat out_flatterned = output.reshape(output.w * output.h * output.c);
    std::vector<float> scores;
    scores.resize(out_flatterned.w);
    for (int j=0; j<out_flatterned.w; j++)
    {
        scores[j] = out_flatterned[j];
    }
    cout<<"done"<<endl;
    return 0;
}

c++在linux下的编译:

cmake .
make
./classify 

https://www.cnblogs.com/lidabo/p/7359422.html
http://www.cnblogs.com/dilex/p/9315308.html

5.param文件

Alexnet.param是这样的:

7767517
24 24
Input            data             0 1 data 0=227 1=227 2=3
Convolution      conv1            1 1 data conv1 0=96 1=11 2=1 3=4 4=0 5=1 6=34848 8=2
ReLU             relu1            1 1 conv1 conv1_relu1
LRN              norm1            1 1 conv1_relu1 norm1 0=0 1=5 2=0.000100 3=0.750000
Pooling          pool1            1 1 norm1 pool1 0=0 1=3 2=2 3=0 4=0
ConvolutionDepthWise conv2            1 1 pool1 conv2 0=256 1=5 2=1 3=1 4=2 5=1 6=307200 7=2 8=2
ReLU             relu2            1 1 conv2 conv2_relu2
LRN              norm2            1 1 conv2_relu2 norm2 0=0 1=5 2=0.000100 3=0.750000
Pooling          pool2            1 1 norm2 pool2 0=0 1=3 2=2 3=0 4=0
Convolution      conv3            1 1 pool2 conv3 0=384 1=3 2=1 3=1 4=1 5=1 6=884736 8=2
ReLU             relu3            1 1 conv3 conv3_relu3
ConvolutionDepthWise conv4            1 1 conv3_relu3 conv4 0=384 1=3 2=1 3=1 4=1 5=1 6=663552 7=2 8=2
ReLU             relu4            1 1 conv4 conv4_relu4
ConvolutionDepthWise conv5            1 1 conv4_relu4 conv5 0=256 1=3 2=1 3=1 4=1 5=1 6=442368 7=2 8=2
ReLU             relu5            1 1 conv5 conv5_relu5
Pooling          pool5            1 1 conv5_relu5 pool5 0=0 1=3 2=2 3=0 4=0
InnerProduct     fc6              1 1 pool5 fc6 0=4096 1=1 2=37748736
ReLU             relu6            1 1 fc6 fc6_relu6
Dropout          drop6            1 1 fc6_relu6 fc6_drop6
InnerProduct     fc7              1 1 fc6_drop6 fc7 0=4096 1=1 2=16777216
ReLU             relu7            1 1 fc7 fc7_relu7
Dropout          drop7            1 1 fc7_relu7 fc7_drop7
InnerProduct     fc8              1 1 fc7_drop7 fc8 0=1000 1=1 2=4096000
Softmax          prob             1 1 fc8 prob 0=0 1=1

其中第一行的7767517是ncnn magic numger(幻数),
第二行的24 24。24为layer number(网络层数),24为blob number(参数块数)
剩下的是网络结构。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章