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(參數塊數)
剩下的是網絡結構。

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