ncnn架构踩坑日记

1 网上有网友说只能用openCV2的库,事实证明会出现错误

报错:error: undefined reference to `cv::imread(cv::String const&, int)' 

解决方法:在CMakeLists.txt加入安装OpenCV的版本号: 
将 
find_package( OpenCV REQUIRED ) 
更改为 
find_package( OpenCV 3 REQUIRED ) 

问:请问下为什么要改成find_package(OpenCV 3 REQUIRED)? 2.4里面应该也有imread这些函数的? 我编译明明链接了highgui.so 但是就是说未定义应用

我个人认为是之前链接过2.4的库,新装3以后,还在原来的位置找,找不到,这时候加上3就可以找到了

切记:ncnn中不要用conda中安装的opencv,也不要使用下面的安装方式

conda remove opencv
conda install -c menpo opencv
pip install --upgrade pip
pip install opencv-contrib-python

出现的错误记录如下:

terminate called after throwing an instance of 'cv::Exception'
  what():  OpenCV(3.4.2) /tmp/build/80754af9/opencv-suite_1535558553474/work/modules/highgui/src/window.cpp:632: error: (-2:Unspecified error) The function is not implemented. Rebuild the library with Windows, GTK+ 2.x or Carbon support. If you are on Ubuntu or Debian, install libgtk2.0-dev and pkg-config, then re-run cmake or configure script in function 'cvShowImage'

使用cmake安装

2 NCNN框架结构

在NCNN中,类似于Caffe,每一层的数据被保存为Mat类型,这是一个NCNN自定的类,其计算使用了汇编,非常高效。网络定义为一个ncnn::Net类,其中的layers储存了每一层的信息,blobs(数据交换结构)储存了网络的中间数据。在计算时,先利用param文件和bin文件实例化一个ncnn::Net类,根据得到的net实例化一个ncnn::Extractor类,extractor中的net会被转为const类,以保证运算的时候blobs和layers等重要信息不会被改变。
当需要计算时,可以在extractor中的任意一层送入数据,如

ncnn::Mat in_blob(224, 224, 3);  // set input blob with given shape
extractor.input("data", in_blob);  // set network input using extractor 

随后就可以取出任意层的数据

ncnn::Mat output;
extractor.extract("res5.1.sum", output);  // extract any blob you want

在extract方法中,使用了net中的forward_layer方法递归地遍历网络

2.1 param格式分析

7767517
75 83
Input                 data              0 1 data 0=227 1=227 2=3
Convolution      conv1            1 1 data conv1 0=64 1=3 2=1 3=2 4=0 5=1 6=1728

ReLU             relu_conv1       1 1 conv1 conv1_relu_conv1 0=0.000000

第一行:版本号

第二行:1(层数量=75)2(数据交换结构(blob)数量=83) 

三四行:相关层的信息

前四个值含义固定:

1 层的类型 2 层的名称 3 输入数据结构(blob)数量(bottom)(input层特殊)4输出数据结构(blob)数量(top)

后面有三种类型的值《《《严格按照顺序排序》》》: 
第一种: 
网络输入层名(一个层可能有多个输入,于是有多个网络输入层名) 
第二种: 
网络输出层名(一个层可能有多个输出,于是有多个网络输出层名)

第三种:特殊参数(可能没有): 一种是k=v的类型;另一种是k=len,v1,v2,v3….(数组类型)。该层在ncnn中是存放到paramDict结构中,不同类型层,各种参数意义不一样。

for example

7767517
9 9
Input            data             0 1 data 0=28 1=28 2=1
Convolution      conv1            1 1 data conv1 0=20 1=5 2=1 3=1 4=0 5=1 6=500
Pooling          pool1            1 1 conv1 pool1 0=0 1=2 2=2 3=0 4=0
Convolution      conv2            1 1 pool1 conv2 0=50 1=5 2=1 3=1 4=0 5=1 6=25000
Pooling          pool2            1 1 conv2 pool2 0=0 1=2 2=2 3=0 4=0
InnerProduct     ip1              1 1 pool2 ip1 0=500 1=1 2=400000
ReLU             relu1            1 1 ip1 ip1_relu1
InnerProduct     ip2              1 1 ip1_relu1 ip2 0=10 1=1 2=5000
Softmax          prob             1 1 ip2 prob 0=0

以第一个卷积层为例

层类型:Convolution

层名称:conv1

输入数据结构数量:1

输出数据结构数量(top blob):1

网络输入层名:data

网络输出层名:conv1

特殊参数1:0=20,num_output: 20

特殊参数2:1=5,kernel_size: 5

特殊参数3:2=1,stride: 1

特殊参数4:3=1

特殊参数5:4=0

特殊参数6:5=1

特殊参数7:6=500,该层的参数量,5*5*1*20=500

 

在load_param时: 
ncnn::Net::blobs存放着每一个blob的相关信息,主要信息为name、producer、consumers,含义分别为:名字、产生这个blob数据的层、消费这个blob数据的层。

ncnn::Net::layers存放的是: 
ncnn::Net::layers::type 
ncnn::Net::layers::name 
ncnn::Net::layers::bottoms 存的是此层需要的输入blob的idx 
ncnn::Net::layers::tops 存的是此层输出的blob的idx

2.2 blob结构

对于NCNN,在网络层传递的过程中,进行数据流动的方式是通过自定义的blob实现的,对于blob通过生产者编号和消费者编号进行定义,producer表示输出该blob的网络层编号,consumers表示以该blob作为输入的网络层编号,前者只能是一个制造者,后者可以是多个使用者。

class Blob
{
public:
    // empty
    Blob();

public:
#if NCNN_STRING
    // blob name
    std::string name;
#endif // NCNN_STRING
    // layer index which produce this blob as output
    int producer;
    // layer index which need this blob as input
    std::vector<int> consumers;
};

2.3 网络层基类

Layer类是所有其他网络层的一个基类,所有的网络层都会从Layer继承,实现互异的计算过程,所有网络层的相似之处在于输入输出的规范以及前向传播的过程。
Option是属性类,lightmode表示轻量级模式在网络推理中会不断地进行垃圾回收,num_thread表示线程数量,并且定义两个内存分配器,一个是对基本数据结构blob的内存分配,另一个是对计算空间workspace的内存分配。

class Option
{
public:
    Option();

public:
    bool lightmode;
    int num_threads;
    Allocator* blob_allocator;
    Allocator* workspace_allocator;
};


 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值