《NNIE-lite 为算法工程师而生》
趟过NNIE的小伙伴可能都知道,NNIE是有很多坑的,而且是纯C的环境,除非你有几年C的开发经验,否则阅读起来不是那么容易的,而作为算法工程师,我相信更多人和我一样擅长Python和C++,所以在把NNIE用起来还是有些费力的。而作为算法工程师,你的工作更应该 focus on 模型上,现在有了NNIE-lite这个项目,极大的帮助大家脱离苦海,算法工程师可以把目光聚焦在模型效果和效率上,而不用再为其他的琐事担心了,使用NNIE像用ncnn一样简单。
Key Words:NNIE、 C++、 OpenCV
Beijing, 2020
作者:RaySue
Code:https://github.com/RaySue/NNIE-lite
Agile Pioneer
如果你有摄像头端(海思NNIE)移植算法的需求
如果你更擅长于C++编程
如果你擅长使用cmake构建工程
恰好你喜欢用OpenCV来进行io处理,这个比起bgr来调试十分方便
Come on and star the repo https://github.com/RaySue/NNIE-lite
那么 NNIE-lite 就是非常适合你的,我当时如果有NNIE-lite这样的项目,可能至少节省我一周的时间去梳理使用NNIE的逻辑。
模型转换 :以TensorRT为例:把你的caffe或onnx模型转为.engine文件,然后就可以利用TensorRT框架使用GPU进行加速了;
数据预处理 :准备推理输入数据,如图片颜色通道排列和分离,像素数据转换成浮点数,数据归一化处理等;
模型推理 :对输入数据进行推理计算,并输出推理数据,在手写体识别例子中,输出的是预测为0~9这10个数字对应的概率值;
后处理 :对推理输出的数据进行解析,得到最终推理结果,在分割的例子中,从Tensor中解析出最终你要的各个类别的idx组成的矩阵就是分割的结果。
NNIE 是 Neural Network Inference Engine 的简称,是海思媒体 SoC 中专门针对神经网络特别是深度学习卷积神经网络进行加速处理的硬件单元,支持现有大部分的公开网络,如 Alexnet、VGG16、Googlenet、Resnet18、Resnet50 等分类网络,Faster R- CNN、YOLO、SSD、RFCN 等检测网络,以及 SegNet、FCN 等场景分割网络。
sample_nnie_main.c例程函数调用关系:
NNIE-lite 是面向算法工程师打造的,可以很容易的在Hisi芯片上移植算法,验证算法的效果和效率,而不必过多关心NNIE的细节,而且也不用对C语言有太多的经验。
参见博客https://blog.csdn.net/racesu/article/details/107045858里面详细介绍了如何搭建模型转换的环境。
在工程目录的examples中有使用NNIE-lite做通用分类和通用分割的例子,每个例子都可以单独运行,main函数中就是调用的整个流程。
希望越来越多的小伙伴能够加入到 NNIE-lite,贡献你们已经跑通的demo,我会把你们的名字写在 NNIE-lite 的页面上。
模型 | 输入数据维度 | cv500 | av100 |
---|---|---|---|
MNIST | 1x28x28x1 | 0.1 ms | 0.1 ms |
Yolov1 | 1x448x448x3 | 102 ms | 36 ms |
Yolov2 | 1x416x416x3 | 201 ms | 75 ms |
Yolov3 | 1x416x416x3 | 182 ms | 60 ms |
SSD | 1x300x300x3 | 149 ms | 53 ms |
PvaNet | 1x224x224x3 | 43 ms | 16 ms |
RFCN | 1x800x600x3 | 501 ms | 180 ms |
SegNet | 1x224x224x3 | 183 ms | 65 ms |
ENet | 1x352x640x3 | 250 ms | 92 ms |
(AlexNet)FasterRCNN | 1x1240x375x3 | 51 ms | 18 ms |
LSTM | 16x128x20 | 94 ms | 34 ms |
海思只给提供了一个模型转换工具nnie_mapper,是把caffe模型转为nnie硬件支持的.wk的压缩模型文件。模型的原始值是float32表示的,而用8bit量化得到的是用int8来量化存储的,所以一般来说.wk模型的大小只有原始模型的四分之一,但是我转的模型却没有变小,而是变大了一点。
因为海思并没有提供nnie_mapper的源码,所以我需要查看该执行文件依赖哪些动态库:readelf -d nnie_mapper_12
来查看依赖哪些库,并对应 Hisvp 开发指南找到相应的版本。
GNU编译器集合(GCC)是C,C ++,Objective-C,Fortran,Ada,Go和D编程语言的编译器和库的集合。许多开源项目包括GNU工具和Linux内核都是用GCC编译的。
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.8 48 --slave /usr/bin/g++ g++ /usr/bin/g++-4.8
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-8 80 --slave /usr/bin/g++ g++ /usr/bin/g++-8
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-9 90 --slave /usr/bin/g++ g++ /usr/bin/g++-9
# 切换 gcc 版本, 选择4.8.5再进行后续编译操作
sudo update-alternatives --config gcc
下载地址:https://github.com/google/protobuf/releases 找3.5.1
编译安装:
下载地址:
OpenCV - https://opencv.org/
opencv_contrib - github
安装依赖:
编译安装:
tar -xvzf opencv-3.4.0.tar.gz
cd opencv-3.4.0
安装opencv_contrib【如果编译过程出现问题就不编译opencv_contrib即可】
mkdir build; mkdir install
cmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/x/x –D WITH_VTK=ON -D OPENCV_EXTRA_MODULES_PATH=/x/x/opencv_contrib-3.4.0/modules/ -D CUDA_NVCC_FLAGS="-std=c++11 --expt-relaxed-constexpr" -D WITH_NVCUVID=OFF -D BUILD_opencv_cudacodec=OFF -D ENABLE_CXX11=YES . . .. ..
make
make check
make install
CMAKE_INSTALL_PREFIX 中就是你需要的include lib bin
加入nnie_env.sh中,并source
# protobuf
export PATH=$PATH:/home/surui/Documents/software/protobuf-3.5.1/release/bin
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/surui/Documents/software/protobuf-3.5.1/release/lib
# OpenCV
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/surui/Documents/software/opencv-3.4.0/release/lib
注意
你的gcc的版本最好是4.8,我的是4.8.5,而且你的protobuf需要是在这个版本下编译的,否则会报错
undefined symbol:_ZN6google8protobuf8internal26fixed_address_empty_stringE
用命令:nm -s libprotobuf.so|grep _ZN6google8protobuf8internal26fixed_address_empty_stringE
会发现有这个符号,但是多了B5cxx11,这个是和编译程序的 gcc 程序有关系,由于 protobuf 的源码中含有c++程序,所以需要使用 gcc4.8.5 和 g++4.8.5 来编译 protobuf 才行。
模型转换命令:
nnie_mapper_12 model.cfg
model.cfg 文件介绍:
[prototxt_file] model.prototxt # caffe 的prototxt
[caffemodel_file] model.caffemodel # caffe 的model文件
[batch_num] 1 # [单张模式/多张模式]
[net_type] 0
[sparse_rate] 0 # 0 - 不稀疏处理 0.5 - 0.5稀疏
[compile_mode] 1 # 0 - 高速模式损失精度 1 - 高精度模式
[is_simulation] 0 # 0 - 芯片模式 1 - 仿真模式用于pc端
[log_level] 2
[instruction_name] save_model # 存储的NNIE模型文件名
[image_list] ./file_list.txt # 用于存储数据的决定路径,30张左右的样例数据用于量化模型
[image_type] 1 # 1 - 表示网络数据输入为 SVP_BLOB_TYPE_U8(普通的灰度图和RGB图)类型; 此时要求 image_list 配置是 RGB 图或者灰度图片的 list 文件;
[mean_file] ./mean.txt # 均值文件,用于数据的标准化,每行代表一个通道要减去的值
[norm_type] 5 # 0 - 不做预处理 5 - 减通道均值后再乘以 data_scale
[RGB_order] BGR
[data_scale] 1 # 0.00390625 = 1/ 256;1 就是不缩放
[internal_stride] 16 # 数据的维度必须是16的倍数,否则按16的倍数补全,默认为16,修改无效
https://zhuanlan.zhihu.com/p/67327779
https://blog.csdn.net/ywcpig/article/details/85260752