IVE(IntelligentVideoEngine)是上海海思媒体处理芯片智能分析系统中的硬件加速模块。用户基于IVE开发智能分析方案可以加速智能分析,降低CPU占用。当前IVE提供的算子可以支撑开发视频诊断、周界防范等智能分析方案。
IVE模块提供了创建任务和查询任务的基本接口。该部分接口较多,详细API使用请参考源码的device/soc/hisilicon/hi3516dv300/sdk_linux/sample/doc中的《HiIVE API 参考.pdf》第2章API参考内容,支持的API接口如下表所示:
API | Function |
---|---|
HI_MPI_IVE_DMA | 创建直接内存访问任务。 |
HI_MPI_IVE_Filter | 创建5x5模板滤波任务,通过配置不同的模板系数,可以实现不同的滤波。 |
HI_MPI_IVE_CSC | 创建色彩空间转换任务,可实现YUV2RGB\YUV2HSV\YUV2LAB\RGB2YUV的色彩空间转换。 |
HI_MPI_IVE_FilterAndCSC | 创建5x5模板滤波和YUV2RGB色彩空间转换复合任务,通过一次创建完成两种功能。 |
HI_MPI_IVE_Sobel | 创建5x5模板Sobel-like梯度计算 |
HI_MPI_IVE_MagAndAng | 创建5x5模板梯度幅值与幅角计算任务。 |
HI_MPI_IVE_Dilate | 创建二值图像5x5模板膨胀任务。 |
HI_MPI_IVE_Erode | 创建二值图像5x5模板腐蚀任务。 |
HI_MPI_IVE_Thresh | 创建灰度图像阈值化任务。 |
HI_MPI_IVE_And | 创建两二值图像相与任务。 |
HI_MPI_IVE_Sub | 创建两灰度图像相减任务。 |
HI_MPI_IVE_Or | 创建两二值图像相或任务。 |
HI_MPI_IVE_Integ | 创建灰度图像的积分图计算任务。 |
HI_MPI_IVE_Hist | 创建灰度图像的直方图统计任务。 |
HI_MPI_IVE_Thresh_S16 | 创建S16数据到8bit数据的阈值化任务。 |
HI_MPI_IVE_Thresh_U16 | 创建U16数据到U8数据的阈值化任务。 |
HI_MPI_IVE_16BitTo8Bit | 创建16bit图像数据到8bit图像数据的线性转化任务。 |
HI_MPI_IVE_OrdStatFilter | 创建3x3模板顺序统计量滤波任务,可进行Median、Max、Min滤波。 |
HI_MPI_IVE_Map | 创建Map(映射赋值)任务,对源图像中的每个像素,查找Map查找表中的值,赋予目标图像相应像素查找表中的值,支持U8C1U8C1映射 |
HI_MPI_IVE_Map | 创建Map(映射赋值)任务,对源图像中的每个像素,查找Map查找表中的值,赋予目标图像相应像素查找表中的值,支持U8C1U8C1、U8C1U16C1、U8C1S16C1 3种模式的映射 |
HI_MPI_IVE_EqualizeHist | 创建灰度图像的直方图均衡化计算任务。 |
HI_MPI_IVE_Add | 创建两灰度图像的加权加计算任务。 |
HI_MPI_IVE_Xor | 创建两二值图的异或计算任务。 |
HI_MPI_IVE_NCC | 创建两相同分辨率灰度图像的归一化互相关系数计算任务。 |
HI_MPI_IVE_CCL | 创建二值图像的连通区域标记任务。 |
HI_MPI_IVE_GMM | 创建GMM背景建模任务,支持灰度图、RGB_PACKAGE图像的GMM背景建模,高斯模型个数为3或者5。 |
HI_MPI_IVE_GMM2 | 创建GMM背景建模任务,支持1-5个高斯模型,支持灰度图和RGB_PACKAGE图输入,支持全局及像素级别的灵敏度系数以及前景模型时长更新系数。 |
HI_MPI_IVE_CannyHysEdge | 灰度图的Canny边缘提取的前半部:求梯度、计算梯度幅值幅角、磁滞阈值化及非极大抑制。 |
HI_MPI_IVE_CannyEdge | 灰度图的Canny边缘提取的后半部:连接边缘点,形成Canny边缘图。 |
HI_MPI_IVE_LBP | 创建LBP计算任务。 |
HI_MPI_IVE_NormGrad | 创建归一化梯度计算任务,梯度分量均归一化到S8。 |
HI_MPI_IVE_LKOpticalFlow | 创建单层LK光流计算任务。 |
HI_MPI_IVE_LKOpticalFlowPyr | 创建多层金字塔LK光流计算任务。 |
HI_MPI_IVE_STCandiCorner | 灰度图像Shi-Tomasi-like角点计算的前半部:计算候选角点。 |
HI_MPI_IVE_STCorner | 灰度图像Shi-Tomasi-like角点计算的后半部:按规则挑选角点。 |
HI_MPI_IVE_SAD | 计算两幅图像按4x4\8x8\16x16分块的16 bit\8 bit SAD图像,以及对SAD进行阈值化输出。 |
HI_MPI_IVE_Resize | 创建图像缩放任务,支持bilinear、area插值缩放,支持多张U8C1\U8C3_PLANAR图像同时输入做一种类型的缩放。 |
HI_MPI_IVE_Resize2 | 创建图像缩放任务,支持bilinear插值缩放,支持多张U8C1图像同时缩放。 |
HI_MPI_IVE_GradFg | 根据背景图像和当前帧图像的梯度信息计算梯度前景图像。 |
HI_MPI_IVE_MatchBgModel | 基于Codebook演进的背景模型匹配。 |
HI_MPI_IVE_UpdateBgModel | 基于Codebook演进的背景模型更新,对背景模型的内部状态进行更新。 |
HI_MPI_IVE_ANN_MLP_LoadModel | 读取ANN_MLP模型文件,初始化模型数据。 |
HI_MPI_IVE_ANN_MLP_UnloadModel | 去初始化ANN模型数据。 |
HI_MPI_IVE_ANN_MLP_Predict | 创建单个样本ANN_MLP预测任务。 |
HI_MPI_IVE_ANN_MLP_Predict | 创建同一模型多个样本ANN_MLP预测任务。 |
HI_MPI_IVE_SVM_LoadModel | 读取SVM模型文件,初始化模型数据。 |
HI_MPI_IVE_SVM_UnloadModel | 去初始化SVM模型数据。 |
HI_MPI_IVE_SVM_Predict | 创建单个样本SVM预测任务。 |
HI_MPI_IVE_SVM_Predict | 创建同一模型的多个样本SVM预测任务。 |
HI_MPI_IVE_CNN_LoadModel | 读取CNN模型文件,初始化CNN模型数据。 |
HI_MPI_IVE_CNN_UnloadModel | 去初始化CNN模型数据。 |
HI_MPI_IVE_CNN_Predict | 创建一个CNN模型的单个或多个样本预测任务,并输出特征向量。 |
HI_MPI_IVE_CNN_GetResult | 接收CNN_Predict结果,执行Softmax运算来预测每个样本图像的类别,并输出置信度最高的类别(Rank-1)以及对应的置信度。 |
HI_MPI_IVE_PerspTrans | 根据输入源图的区域位置和点对信息做相应的透视变换。 |
HI_MPI_IVE_KCF_GetMemSize | 获取需要创建目标对象数的内存大小。 |
HI_MPI_IVE_KCF_CreateObjList | 创建目标链表。 |
HI_MPI_IVE_KCF_DestroyObjList | 销毁目标链表。 |
HI_MPI_IVE_KCF_CreateGaussPeak | 创建高斯峰值。 |
HI_MPI_IVE_KCF_CreateCosWin | 创建汉宁窗。 |
HI_MPI_IVE_KCF_GetTrainObj | 获取需要训练的目标对象。 |
HI_MPI_IVE_KCF_Process | 提交目标给硬件处理。 |
HI_MPI_IVE_KCF_GetObjBbox | 获取目标区域跟踪结果信息。 |
HI_MPI_IVE_KCF_JudgeObjBboxTrackState | 判断目标区域跟踪状态。 |
HI_MPI_IVE_KCF_ObjUpdate | 更新目标信息。 |
HI_MPI_IVE_Hog | 计算给定区域的HOG(Histogram of Oriented Gradient)特征。 |
HI_MPI_IVE_Query | 查询已创建任务完成情况。 |
关于IVE部分的Proc调试方法请参考源码的device/soc/hisilicon/hi3516dv300/sdk_linux/sample/doc中的《HiIVE API 参考.pdf》第5章Proc调试信息即可。
在编译sample_ive_main.c之前,需要确保已经执行了 3.2.1章节的整编Taurus代码,以及3.2.2章节的Taurus镜像烧录的步骤,由于sample_ive_kcf.c适配的sensor是vpss0 chn0输出1080P,chn1 输出PIC_CIF分辨率,但是我们的摄像头是IMX335_4M,当使用4M或5M时序时,会因为规格限制出现报错,所以我们需要修改vpss0 chn1输出输出1080P,chn12输出PIC_CIF,就可以正常输出图像。
以下截图可在device/soc/hisilicon/hi3516dv300/sdk_linux/sample/platform/svp/ive/sample/sample_ive_kcf.c文件中找到
s32Ret = HI_MPI_VPSS_ReleaseChnFrame(s32VpssGrp, 2, &stExtFrmInfo); // 第1682行,将第二个参数修改为2
s32Ret = HI_MPI_VPSS_GetChnFrame(0, 1, &astVideoFrame[0], s32MilliSec); // 第1704行,将第二个参数改为1
s32Ret = HI_MPI_VPSS_GetChnFrame(0, 2, &astVideoFrame[1], s32MilliSec); // 第1721行,将第二个参数改为2
s32Ret = HI_MPI_VPSS_ReleaseChnFrame(0, 1, &astVideoFrame[0]); // 第1737行,将第二个参数改为1
(HI_VOID)HI_MPI_VPSS_ReleaseChnFrame(0, 1, &pstQueueNode->stFrameInfo); // 第2047行,将第二个参数改为1
(HI_VOID)HI_MPI_VPSS_ReleaseChnFrame(0, 2, &pstIveKcfInfo->astFrameInfo[1]); // 第2059行,将第二个参数改为2
(HI_VOID)HI_MPI_VPSS_ReleaseChnFrame(0, 1, &pstQueueNode->stFrameInfo); // 第2074行,将第二个参数改为1
# 将SAMPLE_IVE_Kcf()函数中的2345-2347行,从
for (i = 0; i < SAMPLE_IVE_KCF_VPSS_MAX_CHN; i++) {
astVpssChnAttr[i].u32Width = astSize[i + 1].u32Width;
astVpssChnAttr[i].u32Height = astSize[i + 1].u32Height;
# 改成
for (i = 1; i < SAMPLE_IVE_KCF_VPSS_MAX_CHN + 1; i++) {
astVpssChnAttr[i].u32Width = astSize[i].u32Width;
astVpssChnAttr[i].u32Height = astSize[i].u32Height;
由于我的显示器是只支持1080P60帧,所以需要修改device/soc/hisilicon/hi3516dv300/sdk_linux/sample/platform/common/sample_comm_vo.c文件中SAMPLE_COMM_VO_GetDefConfig()函数的VO 输出配置,这个请根据自己的显示器支持的参数进行配置。
pstVoConfig->enIntfSync = VO_OUTPUT_1080P60; // 第483行的VO_OUTPUT_1080P30; 改成 VO_OUTPUT_1080P60;
在单编sample_ive_main.c前,需修改目录下的一处依赖,进入//device/soc/hisilicon/hi3516dv300/sdk_linux目录下,通过修改BUILD.gn,在deps下面新增target,"sample/platform/svp/ive:hi3516dv300_ive_sample"
,如下图所示:
单编 ive sample
方式一:使用Makefile的方式进行单编(速度会快很多)
cd /home/openharmony/sdk_linux/sample/build
make ive_clean && make ive
方式二:使用OpenHarmony的BUILD.gn方式进行单编(速度较慢)
hb set # 选择 ipcamera_hispark_taurus_linux
hb build -T device/soc/hisilicon/hi3516dv300/sdk_linux/sample/platform/svp/ive:hi3516dv300_ive_sample
方式一:使用SD卡进行资料文件的拷贝
mount -t vfat /dev/mmcblk1p1 /mnt
# 其中/dev/mmcblk1p1需要根据实际块设备号修改
方式二:使用NFS挂载的方式进行资料文件的拷贝
mount -o nolock,addr=192.168.200.1 -t nfs 192.168.200.1:/d/nfs /mnt
cp /mnt/ohos_ive_demo /userdata
cp /mnt/data /userdata -rf
cp /mnt/*.so /usr/lib/
chmod 777 /userdata/ohos_ive_demo
cd /userdata
./ohos_ive_demo 7
基于SDK sample的GMM2高斯背景建模对yuv格式的场景流进行背景建模,
示例代码参考在device/soc/hisilicon/hi3516dv300/sdk_linux/sample/platform/svp/ive/sample路径下的sample_ive_gmm2.c
分析sample_ive_gmm2.c中的HI_VOID SAMPLE_IVE_Gmm2(HI_VOID);对该接口的解读如下图所示:
运行的主入口在device/soc/hisilicon/hi3516dv300/sdk_linux/sample/platform/svp/ive/中sample_ive_main.c文件中,如下图所示:
关于GMM2算子的其他细节,自行查阅device/soc/hisilicon/hi3516dv300/sdk_linux/sample/platform/svp/ive/sample/sample_ive_gmm2.c代码即可。
在编译sample_ive_main.c之前,需要确保已经执行了 3.2.1章节的整编Taurus代码,以及3.2.2章节的Taurus镜像烧录的步骤,在单编sample_ive_main.c前,需修改目录下的一处依赖,进入//device/soc/hisilicon/hi3516dv300/sdk_linux目录下,通过修改BUILD.gn,在deps下面新增target,"sample/platform/svp/ive:hi3516dv300_ive_sample"
,如下图所示:
单编 ive sample
方式一:使用Makefile的方式进行单编(速度会快很多)
cd /home/openharmony/sdk_linux/sample/build
make ive_clean && make ive
方式二:使用OpenHarmony的BUILD.gn方式进行单编(速度较慢)
hb set # 选择 ipcamera_hispark_taurus_linux
hb build -T device/soc/hisilicon/hi3516dv300/sdk_linux/sample/platform/svp/ive:hi3516dv300_ive_sample
方式一:使用SD卡进行资料文件的拷贝
mount -t vfat /dev/mmcblk1p1 /mnt
# 其中/dev/mmcblk1p1需要根据实际块设备号修改
方式二:使用NFS挂载的方式进行资料文件的拷贝
mount -o nolock,addr=192.168.200.1 -t nfs 192.168.200.1:/d/nfs /mnt
cp /mnt/ohos_ive_demo /userdata
cp /mnt/data /userdata -rf
cp /mnt/*.so /usr/lib/
chmod 777 /userdata/ohos_ive_demo
cd /userdata
./ohos_ive_demo 3
将bg_352x288_sp400.yuv和fg_352x288_sp400.yuv通过nfs或者SD卡挂载的方式,拷贝到本地,通过YUVPlayer即可查看效果,关于YUVPlayer自行到网上下载即可。
GMM2处理效果如下图所示:
SDK sample移动侦测(Motion Detection)代码路径存放在device/soc/hisilicon/hi3516dv300/sdk_linux/sample/platform/svp/ive/sample路径下的sample_ive_md.c中,如下图所示:
运行的主入口在device/soc/hisilicon/hi3516dv300/sdk_linux/sample/platform/svp/ive路径下的sample_ive_main.c文件中,如下图所示:
关于MD算子的其他细节,自行查阅device/soc/hisilicon/hi3516dv300/sdk_linux/sample/platform/svp/ive/sample/sample_ive_md.c代码即可。
在编译sample_ive_main.c之前,需要确保已经执行了 3.2.1章节的整编Taurus代码,以及3.2.2章节的Taurus镜像烧录的步骤,由于我的显示器是只支持1080P60帧,所以需要修改device/soc/hisilicon/hi3516dv300/sdk_linux/sample/platform/svp/common/目录下的sample_comm_ive.c的SAMPLE_COMM_IVE_StartVo()函数中的VO 输出配置,这个请根据自己的显示器支持的参数进行配置。
stVoPubAttr.enIntfSync = VO_OUTPUT_1080P60; // 第823行的VO_OUTPUT_1080P30; 改成 VO_OUTPUT_1080P60;
在单编sample_ive_main.c前,需修改目录下的一处依赖,进入//device/soc/hisilicon/hi3516dv300/sdk_linux目录下,通过修改BUILD.gn,在deps下面新增target,"sample/platform/svp/ive:hi3516dv300_ive_sample"
,如下图所示:
单编 ive sample
方式一:使用Makefile的方式进行单编(速度会快很多)
cd /home/openharmony/sdk_linux/sample/build
make ive_clean && make ive
方式二:使用OpenHarmony的BUILD.gn方式进行单编(速度较慢)
hb set # 选择 ipcamera_hispark_taurus_linux
hb build -T device/soc/hisilicon/hi3516dv300/sdk_linux/sample/platform/svp/ive:hi3516dv300_ive_sample
方式一:使用SD卡进行资料文件的拷贝
mount -t vfat /dev/mmcblk1p1 /mnt
# 其中/dev/mmcblk1p1需要根据实际块设备号修改
方式二:使用NFS挂载的方式进行资料文件的拷贝
mount -o nolock,addr=192.168.200.1 -t nfs 192.168.200.1:/d/nfs /mnt
cp /mnt/ohos_ive_demo /userdata
cp /mnt/data /userdata -rf
cp /mnt/*.so /usr/lib/
chmod 777 /userdata/ohos_ive_demo
cd /userdata
./ohos_ive_demo 1
若运行正常,即可进行目标的移动检测,如下图所示:
在编译sample_ive_main.c之前,需要确保已经执行了 3.2.1章节的整编Taurus代码,以及3.2.2章节的Taurus镜像烧录的步骤,在单编sample_ive_main.c前,需修改目录下的一处依赖,进入//device/soc/hisilicon/hi3516dv300/sdk_linux目录下,通过修改BUILD.gn,在deps下面新增target,"sample/platform/svp/ive:hi3516dv300_ive_sample"
,如下图所示:
单编 ive sample
方式一:使用Makefile的方式进行单编(速度会快很多)
cd /home/openharmony/sdk_linux/sample/build
make ive_clean && make ive
方式二:使用OpenHarmony的BUILD.gn方式进行单编(速度较慢)
hb set # 选择 ipcamera_hispark_taurus_linux
hb build -T device/soc/hisilicon/hi3516dv300/sdk_linux/sample/platform/svp/ive:hi3516dv300_ive_sample
方式一:使用SD卡进行资料文件的拷贝
mount -t vfat /dev/mmcblk1p1 /mnt
# 其中/dev/mmcblk1p1需要根据实际块设备号修改
方式二:使用NFS挂载的方式进行资料文件的拷贝
mount -o nolock,addr=192.168.200.1 -t nfs 192.168.200.1:/d/nfs /mnt
cp /mnt/ohos_ive_demo /userdata
cp /mnt/data /userdata -rf
cp /mnt/*.so /usr/lib/
chmod 777 /userdata/ohos_ive_demo
cd /userdata
./ohos_ive_demo 2 0
通过IVE加速过得色彩空间转换算子可以提高软件在板端运行效率,充分利用硬件资源来为软件服务,color_space_convert中定义了如下空间转换算子,可参考源码的device/soc/hisilicon/hi3516dv300/sdk_linux/sample/taurus/color_space_convert/smp中的smp_color_space_convert.h,如下图所示:
详细讲解下各算子的用法。
以下算子的实现都可以在device/soc/hisilicon/hi3516dv300/sdk_linux/sample/taurus/color_space_convert/smp/smp_color_space_convert.c中找到
SAMPLE_IVE_OrigImgToFrm
功能:ive image to video frame.
具体实现方式如下:
SAMPLE_IVE_FrmToOrigImg
功能:video frame to ive image.
具体实现方式如下:
SAMPLE_IVE_FrmToU8c1Img
功能:video YUV frame to ive image (U8C1)
具体实现方式如下:
SAMPLE_IVE_FrmToRgbImg_ImgRgbToYuv
具体实现方式如下:
功能:ive image RGB to YUV
SAMPLE_IVE_FrmToRgbImg_ImgRgbToBgr
功能:ive image RGB to BGR
具体实现方式如下:
color_space_convert sample基于OpenHarmony 小型系统开发,以Taurus套件为例,color_space_convert sample 介绍了常用色彩空间转换算子的具体实现过程。
//device/soc/hisilicon/hi3516dv300/sdk_linux/sample/taurus/color_space_convert
├── BUILD.gn # 编译ohos color_space_convert sample需要的gn文件
├── sample_color_space_convert_main.c # ohos color_space_convert sample主函数入口
└── smp
├── smp_color_space_convert.c # ohos color_space_convert sample业务代码
└── smp_color_space_convert.h # ohos color_space_convert sample业务代码所需的头文件
"sample/taurus/color_space_convert:hi3516dv300_color_space_convert_sample"
,如下图所示:单编 color_space_convert sample
方式一:使用Makefile的方式进行单编(速度会快很多)
cd /home/openharmony/sdk_linux/sample/build
make color_space_convert_clean && make color_space_convert
方式二:使用OpenHarmony的BUILD.gn方式进行单编(速度较慢)
hb set # 选择 ipcamera_hispark_taurus_linux
hb build -T device/soc/hisilicon/hi3516dv300/sdk_linux/sample/taurus/color_space_convert:hi3516dv300_color_space_convert_sample
方式一:使用SD卡进行资料文件的拷贝
首先需要自己准备一张SD卡
步骤1:将编译后生成的可执行文件拷贝到SD卡中。
步骤2:将device\soc\hisilicon\hi3516dv300\sdk_linux\out\lib\目录下的libvb_server.so和 libmpp_vbs.so拷贝至SD卡中
步骤3:将device/soc/hisilicon/hi3516dv300/sdk_linux/sample/taurus/data/目录下的 UsePic_1920_1080_420.yuv文件拷贝至SD卡中。
mount -t vfat /dev/mmcblk1p1 /mnt
# 其中/dev/mmcblk1p1需要根据实际块设备号修改
方式二:使用NFS挂载的方式进行资料文件的拷贝
首先需要自己准备一根网线
步骤1:参考博客链接中的内容,进行nfs的环境搭建
步骤2:将编译后生成的可执行文件拷贝到Windows的nfs共享路径下
步骤3:将device\soc\hisilicon\hi3516dv300\sdk_linux\out\lib\目录下的libvb_server.so和 libmpp_vbs.so拷贝至Windows的nfs共享路径下
步骤4:将device/soc/hisilicon/hi3516dv300/sdk_linux/sample/taurus/data/目录下的 UsePic_1920_1080_420.yuv文件拷贝至Windows的nfs共享路径下。
mount -o nolock,addr=192.168.200.1 -t nfs 192.168.200.1:/d/nfs /mnt
mkdir -p /userdata/data/input/color_convert_img/
mkdir -p /userdata/data/output/color_convert_res/
cp /mnt/ohos_color_space_convert_demo /
cp /mnt/*.so /usr/lib/
cp /mnt/UsePic_1920_1080_420.yuv /userdata/data/input/color_convert_img/
chmod 777 ohos_color_space_convert_demo
1) ive image to video frame
./ohos_color_space_convert_demo 0
2) video frame to ive image
./ohos_color_space_convert_demo 1
3) video YUV frame to ive image (U8C1)
在开发板的终端执行下面的命令,即可完成video YUV frame to ive image (U8C1)的转换,如下图所示:
./ohos_color_space_convert_demo 2
4) YUV video frame to RGB ive image - ive image RGB to YUV
./ohos_color_space_convert_demo 3
5) YUV video frame to RGB ive image - ive image RGB to BGR
./ohos_color_space_convert_demo 4
神经网络种类很多,本章节重点介绍卷积神经网络。
卷积神经网络(Convolutional Neural Networks, CNN)是一类包含卷积计算且具有深度结构的前馈神经网络(Feedforward Neural Networks),是深度学习(deep learning)的代表算法之一 。卷积神经网络具有表征学习(representation learning)能力,能够按其阶层结构对输入信息进行平移不变分类(shift-invariant classification),因此也被称为“平移不变人工神经网络(Shift-Invariant Artificial Neural Networks, SIANN)”。
对卷积神经网络的研究始于二十世纪80至90年代,时间延迟网络和LeNet-5是最早出现的卷积神经网络;在二十一世纪后,随着深度学习理论的提出和数值计算设备的改进,卷积神经网络得到了快速发展,并被应用于计算机视觉、自然语言处理等领域 。
卷积神经网络仿造生物的视知觉(visual perception)机制构建,可以进行监督学习和非监督学习,其隐含层内的卷积核参数共享和层间连接的稀疏性使得卷积神经网络能够以较小的计算量对格点化(grid-like topology)特征,例如像素和音频进行学习、有稳定的效果且对数据没有额外的特征工程(feature engineering)要求。
NNIE是Neural Network Inference Engine的简称,是上海海思媒体SoC中专门针对神经网络特别是深度学习卷积神经网络进行加速处理的硬件单元,支持现有大部分的公开网络,如Alexnet、VGG16、Googlenet、Resnet18、Resnet50等分类网络,FasterR-CNN、YOLO、SSD、RFCN等检测网络,以及SegNet、FCN等场景分割网络。用户基于NNIE开发智能分析方案,降低CPU占用。
目前NNIE配套软件及工具链仅支持Caffe框架,使用其他框架的网络模型需要转化为Caffe框架下的模型。
NNIE模块提供了创建任务和查询任务的基本接口。
l HI_MPI_SVP_NNIE_LoadModel:从用户事先加载到buf中的模型中解析出网络模型。
l HI_MPI_SVP_NNIE_GetTskBufSize:获取给定网络任务各段辅助内存大小。
l HI_MPI_SVP_NNIE_Forward:多节点输入输出的CNN类型网络预测。
l HI_MPI_SVP_NNIE_ForwardWithBbox:多个节点feature map输入。
l HI_MPI_SVP_NNIE_UnloadModel:卸载模型。
l HI_MPI_SVP_NNIE_Query:查询任务是否完成。
l HI_MPI_SVP_NNIE_AddTskBuf:记录TskBuf地址信息。
l HI_MPI_SVP_NNIE_RemoveTskBuf:移除TskBuf地址信息。
NNIE API接口中参数的数据类型类型,请查阅源码的device/soc/hisilicon/hi3516dv300/sdk_linux/sample/doc中的《HiSVP API 参考.pdf》中的2.4 数据类型和数据结构内容,如下图所示:
注:本章节提到的错误码,请查阅源码的device/soc/hisilicon/hi3516dv300/sdk_linux/sample/doc中的《HiSVP API 参考.pdf》操作手册中对应的错误码内容。
接下来对NNIE API接口进行详细描述。
【描述】
【语法】
【参数】
【返回值】
【需求】
头文件:hi_comm_svp.h、hi_nnie.h、mpi_nnie.h
库文件:libnnie.a(PC上模拟用nniefc1.1.lib\nnieit1.1.lib)
【注意】
用户需要保证pstModelBuf中的地址所指向的内存中存储的模型数据的完整性和正确性。
用户需要保证pstModelBuf中的地址所指向的内存只有当所存储的模型不再使用后才能被释放,并且在释放之前内存中的数据不能被修改。
用户需要保证解析获得的pstModel里的内容不能被修改。
【描述】
【语法】
【参数】
【返回值】
【需求】
头文件:hi_comm_svp.h、hi_nnie.h、mpi_nnie.h
库文件:libnnie.a(PC上模拟用nniefc1.1.lib\nnieit1.1.lib)
【注意】
针对单线程运行一个网络模型,用户开辟tskBuf可以根据网络段的运行关系来选择以下两种方案:
1)NNIE→非NNIE→NNIE→非NNIE,类似这种NNIE、非NNIE(CPU或者DSP等)间隔的网络,用户可以选择开辟一个分段au32TskBufSize[]中的最大值,每个段可以复用这段内存;
2)NNIE→NNIE→非NNIE→NNIE→非NNIE,类似这种存在N个NNIE连续顺序执行段的网络,连续的NNIE段不能复用tskBuf,按照最省内存原则可以选择开辟满足这N个连续NNIE段的其中N-1个size和最小的tskBuf以及剩余所有段中最大的一片tskBuf,具体按文中示例,可以选择开辟“NNIE→NNIE”中较小size的tskBuf,后面“非NNIE→NNIE→非NNIE”中可以复用最大size这片taskBuf;
多线程运行同一个网络模型,每个线程需要各自独立的tskBuf,开辟的方式可以参考“针对单线程运行一个网络模型”的情况。
【描述】
【语法】
【参数】
【返回值】
【需求】
头文件:hi_comm_svp.h、hi_nnie.h、mpi_nnie.h
库文件:libnnie.a(PC上模拟用nniefc1.1.lib\nnieit1.1.lib)
【注意】
用户需要保证pstModel->stBase中的地址所指向的内存中数据的完整性和正确性。
用户需要保证pstModel结构体中的内容与pstModel->stBase中的地址所指向的内存中的数据是同一个模型文件解析获得的。
网络段类型为SVP_NNIE_NET_TYPE_RECURRENT类型时,用户需要保证类型为SVP_BLOB_TYPE_SEQ_S32的输入输出blob中虚拟地址virt_addr_step及其指向内存大小的正确性。
U8图像输入只支持1通道(灰度图)和3通道(RGB图);
多个Blob输入输出时,配合编译器输出的dot描述文件生成的dot图示,可以看到Blob跟层的对应关系。
NNIE_Forward支持的多节点输入输出网络示意图如下图所示:
【描述】
【语法】
【参数】
【返回值】
【需求】
头文件:hi_comm_svp.h、hi_nnie.h、mpi_nnie.h
库文件:libnnie.a(PC上模拟用nniefc1.1.lib\nnieit1.1.lib)
【注意】
【描述】
【语法】
【参数】
【返回值】
【需求】
头文件:hi_comm_svp.h、hi_nnie.h、mpi_nnie.h
库文件:libnnie.a(PC上模拟用nniefc1.1.lib\nnieit1.1.lib)
【注意】
【描述】
【语法】
【参数】
【返回值】
【需求】
头文件:hi_comm_svp.h、hi_nnie.h、mpi_nnie.h
库文件:libnnie.a(PC上模拟用nniefc1.1.lib\nnieit1.1.lib)
【注意】
记录TskBuf地址信息,用于减少内核态内存映射次数,提升效率。
TskBuf地址信息的记录是通过链表进行管理,链表长度默认值为32,链表长度可通过模块参数nnie_max_tskbuf_num进行配置。
若没有调用HI_MPI_SVP_NNIE_AddTskBuf预先把TskBuf地址信息记录到系统,那么之后调用Forward/ForwardWithBbox每次都会Map/Unmap操作TskBuf内核态虚拟地址,效率会比较低。
必须与HI_MPI_SVP_NNIE_RemoveTskBuf成对匹配使用。
建议先把Forward/ForwardWithBbox用到的TskBuf地址信息调用此接口记录到系统。当不再使用时调用HI_MPI_SVP_NNIE_RemoveTskBuf把TskBuf地址信息移除。只需要在初始化时把TskBuf地址信息记录,后续可以直接使用,直到不再使用时才移除。
pstTskBuf->u64VirAddr不使用,不做参数异常检查。
pstTskBuf->u32Size不能为0。
TskBuf内存由用户释放,记录的TskBuf要在移除后才能被释放。
HI_MPI_SVP_NNIE_RemoveTskBuf
【描述】
移除TskBuf地址信息。
【语法】
HI_S32 HI_MPI_SVP_NNIE_RemoveTskBuf(const SVP_MEM_INFO_S *pstTskBuf);
【参数】
【返回值】
【需求】
头文件:hi_comm_svp.h、hi_nnie.h、mpi_nnie.h
库文件:libnnie.a(PC上模拟用nniefc1.1.lib\nnieit1.1.lib)
【注意】
如果TskBuf不再使用,需要将记录的TskBuf地址信息从链表中移除。
必须与HI_MPI_SVP_NNIE_AddTskBuf成对匹配使用。
pstTskBuf->u64VirAddr不使用,不做参数异常检查。
pstTskBuf->u32Size不能为0。
TskBuf内存由用户释放,记录的TskBuf要在移除后才能被释放。
开发者将RuyiStudio工具量化后生成的wk模型文件通过插件进行加载,并部署到芯片端的Flash或DDR里面,通过NNIE加速器进行推理,NNIE板测推理逻辑图如下:
![](pic/019NNIE 推理逻辑图.png)
一般来讲,训练出一个神经网络模型,做成端到端模型并可视化需要经过视频录制、数据集制作和标注、模型训练(本地)、模型转换(模型-caffe)、模型量化、仿真、板端推理可视化。本章节以垃圾分类为例,重点介绍分类网(resnet18),从视频录制、数据集制作和标注、模型训练、模型转换来展开论述。
训练流程图如下:
步骤1:参考本文5.5.5章节store_sample操作指导的步骤进行视频的录制。
步骤2:将录制好的视频按类整理(这里自行创建目录即可),可参考下图:
本文档以垃圾分类训练图片为例进行指导和说明。本文录制了20种垃圾样例视频,具体垃圾样本如下表所示:
垃圾性质 | 种类 | 具体样本 |
---|---|---|
厨余垃圾 | 6 | 蘑菇、葱、茄子、西瓜皮、蛋壳、鱼骨 |
有害垃圾 | 4 | 废旧电池、过期化妆品、医用纱布、创可贴 |
可回收垃圾 | 6 | 易拉罐、旧手提包、牛奶盒、牙刷、旧架子、旧玩偶 |
其他垃圾 | 4 | 盘子、砖块、坏马桶、烟蒂 |
视频录制注意事项:
录制视频时保证训练的可靠性,素材全部在镜头之内,防止素材跑出镜头的情况
可以选不同的背景色来录制,如白色、绿色等,本次示例选择白色和绿色背景色来录制
对垃圾分类样本进行视频码流采集,采集过程中可通过镜头平移和旋转的方法来录制,增加样本的多样性
处理录制好的视频:
本次录制的样例视频为.h264格式,分辨率为1920*1080,实际使用时,建议将h264格式转成通用mp4格式的视频,可使用格式工厂或者其他工具进行格式转换。格式工厂的具体转换步骤可参考《使用格式工厂将H264文件转成mp4文件》。
步骤1:搭建FFmpeg环境:
步骤2:制作数据集
ffmpeg –i xxx.mp4 –r 1 –y xxx_%06d.png # xxx为你视频文件的名字
步骤3:数据清洗
步骤4:数据标注
分类网除正常的分类目标外,最后还需添加一类作为背景集,背景集选择常用背景,防止误报,上图21_Other_background为背景集。
对垃圾分类样本图片随机分组分别作为训练数据集及验证数据集(注:分组过程中可对图片进行随机采样,也可以对码流样本随机采样,尝试构建多样性验证集以有效评估分类模型),建议对采样数据10%用作验证集即可。
在模型训练测和后端推理测需要19201080进行缩放和裁剪,resize为256256,crop为224*224。
(注意:如果您使用的是海思提供的训练服务器,此5.3.2.3.4小节可以跳过,按照海思提供的训练服务器的训练指导文档操作即可)
**注意:需要开发者提前把自己训练服务器中的NVIDIA驱动、CUDA、cuDNN等软件安装好,作者使用的训练服务器相关软硬件参数如下表所示,如果您的训练服务器与作者的不一致,参考本章节的内容操作可能会遇到一些未知的问题,需要开发者自行解决**
名称 | 软件版本号 |
---|---|
Ubuntu | 18.04 |
NVIDIA显卡驱动 | Tesla T4 / 4张显卡 |
python | 3.6 |
CUDA | 11.3 |
cuDNN | 8.2.1.32 |
软件包安装
本章节所有的环境都是在本地训练服务器中进行安装。
步骤1:Anaconda安装
wget https://repo.anaconda.com/archive/Anaconda3-2020.02-Linux-x86_64.sh
bash Anaconda3-2020.02-Linux-x86_64.sh
Do you accept the license terms? [yes|no]
时,输入yes,然后按回车键即可继续安装source ~/.bashrc
conda --version
conda config --add channels http://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/
conda config --add channels http://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main/
conda config --set show_channel_urls yes
步骤2:安装open-mmlab和python
conda create -n open-mmlab python=3.6
步骤3:激活虚拟环境
# 进入open-mmlab虚拟环境
conda activate open-mmlab
# 激活虚拟环境
conda activate base
# 退出虚拟环境
conda deactivate
# 进入open-mmlab虚拟环境
conda activate open-mmlab
注意以下软件包和环境的安装均需要在open-mmlab虚拟环境下进行
步骤4:安装跟CUDA版本对应的torch
https://download.pytorch.org/whl/cu100/torch_stable.html
# 更新pip
python -m pip install -i https://repo.huaweicloud.com/repository/pypi/simple --upgrade pip
pip config set global.index-url https://repo.huaweicloud.com/repository/pypi/simple
# 下载torch软件包
wget https://download.pytorch.org/whl/cu113/torch-1.10.2%2Bcu113-cp36-cp36m-linux_x86_64.whl
# 给torch软件包,添加可执行权限
chmod 777 torch-1.10.2+cu113-cp36-cp36m-linux_x86_64.whl
# 安装torch软件包
pip install torch-1.10.2+cu113-cp36-cp36m-linux_x86_64.whl
步骤5:安装跟CUDA版本对应的是torchversion 0.11.3
# 下载torchversion软件包
wget https://download.pytorch.org/whl/cu113/torchvision-0.11.3%2Bcu113-cp36-cp36m-linux_x86_64.whl
# 给torchversion软件包,添加可执行权限
chmod 777 torchvision-0.11.3+cu113-cp36-cp36m-linux_x86_64.whl
# 安装torchversion软件包
pip install torchvision-0.11.3+cu113-cp36-cp36m-linux_x86_64.whl
步骤6:安装mmcv包
pip install mmcv==1.5.0
代码下载
步骤1:下载mmclassification代码到本地服务器
在训练服务器的命令行终端,执行下面的命令,下载mmclassification-0.11版本的软件包,然后进行解压
# 下载mmclassification-0.11版本的软件包
wget https://github.com/open-mmlab/mmclassification/archive/refs/tags/v0.11.0.tar.gz
# 解压mmclassification-0.11版本的软件包
tar -zxvf v0.11.0.tar.gz
mv mmclassification-0.11.0 mmclassification
步骤2:安装mmclassfication所需环境和库
cd mmclassification
pip install -e .
至此环境搭建结束。
步骤1:本地训练素材的准备
本地训练素材准备请参考5.3.2.3分类网(resnet18)章节中的5.3.2.3.2视频录制和5.3.2.3.3数据集制作和标注章节中的内容,这里不再详细阐述。
在训练服务器的命令行终端,执行下面的命令,创建一个data文件夹,用于存放后面训练需要的数据集,如下图所示
# 创建data目录
cd ~
mkdir data
然后通过MobaXterm、xshell、tftp等工具,将需要训练的数据集放在这个data目录下,关于如何使用工具将Windows的数据集上传至服务器,这里就不再赘述,请开发者自行百度。如下图所示,将我们制作的数据集上传到data/trash_classify/dataset/ 目录下(路径自定义即可)。
步骤2:根据数据集修改代码
mmclassification/configs/_base_/datasets
目录下,按照下图所示进行修改,包括mean、std、resize、crop、data_prefix确认修改,这个务必配置对,否则影响模型训练的效果。cd ~/mmclassification/configs/_base_/datasets
vim imagenet_bs32.py
mmclassification/configs/_base_/models
目录下resnet18.py,按下图修改即可:cd ../models
vim resnet18.py
步骤3:开始模型训练
# 进入到mmclassification目录下
cd ~/mmclassification/
# 开始进行模型训练
bash ./tools/dist_train.sh configs/resnet/resnet18_b32x8_imagenet.py 2 --work-dir ./ckpt
# 对上述命令阐述如下:
# dist_train.sh – 训练sh脚本
# configs/resnet/resnet18_b32x8_imagenet.py – 训练依赖的配置
# 2 – GPU个数,因为本文使用的训练服务器有四个GPU,这个GPU的个数需要根据开发者自己训练服务器的配置来具体设置
# --work-dir ./ckp – 模型存放的路径
(注意:如果您使用的是海思提供的训练服务器,此5.3.2.3.5小节可以跳过,按照海思提供的训练服务器的训练指导文档操作即可)
目前 NNIE 配套软件及工具链仅支持以 Caffe1.0 框架,使用其他框架的网络模型需要转化为Caffe框架下的模型,具体转换过程如下。
(1)环境搭建
模型转换需要依赖torch和torchvison,我们选择版本为python 版本为 3.6,CUDA 11.3 对应的 torch 版本为 1.10.2,torchvision 版本为 0.11.3
在训练服务器的命令行终端,执行下面的命令,安装依赖软件
pip install google -i https://pypi.tuna.tsinghua.edu.cn/simple some-package
pip install protobuf -i https://pypi.tuna.tsinghua.edu.cn/simple some-package
(2)下载pytorch_to_caffe_master
https://www.123pan.com/s/iiMUVv-8YFLh
在训练服务器的命令行终端,执行下面的命令,对pytorch_to_caffe_master压缩包进行解压
tar -zxvf pytorch_to_caffe_master.tgz
(3)修改代码
cd ~/pytorch_to_caffe_master
vim example/resnet_pytorch_2_caffe.py
(4)模型转换及结果生成
python example/resnet_pytorch_2_caffe.py
至此,模型转换已经完成。
(1)prototxt网络层适配
模型prototxt网络层适配之前,请确保模型训练和模型转换的步骤均已完成。
一般来讲,pytorch2caffe自动生成的.prototxt网络需要进行手动修改,以保证量化成正确的wk模型,需要根据特定的网络特定的环境来进行修改。本文以resnet18网络训练垃圾分类生成的prototxt网络进行讲解。
首先将5.3.2.3.5 PytorchCaffe 方案章节中模型转换后生成的resnet18.prototxt网络文件,通过工具打开,这里选用Ultra Edit或者Notepad++均可。
观察pth转caffe运行日志,若出现pooling参数不对齐的问题,需要先将pooling参数对齐,如下图所示:
解决方案:
注:请仔细检查如下layer层中是否有bottom: “view_blob1”,若无参考下图手工加上。
至此,.prototxt已经修改完毕,请保证上述每一步都修改正确,否则影响模型量化和推理结果。
Netscope是个支持prototxt格式描述的神经网络结构的在线可视工具,它可以用来可视化Caffe结构里prototxt格式的网络结构,使用起来也较为简单,在google浏览器打开如下网址:
http://ethereon.github.io/netscope/#/editor
将适配好的.prototxt代码放到相应位置,按Shift+Enter之后,即可显示网络层级,如下图所示:
Netscope可帮助开发着可视化网络层级,判断网络层是否正确。
定义:量化的过程将caffe模型转换成可以在海思芯片上执行的wk文件,同时将float类型数据转换成int8/int16类型的数据。
相关nnie_mapper配置概念请阅读源码的device/soc/hisilicon/hi3516dv300/sdk_linux/sample/doc中《HiSVP 开发指南.pdf》3.5.2章节配置文件说明,如下图所示:
接下来以垃圾分类sample为例,通过RuyiStudio工具将转换好的caffemodel和prototxt量化成wk文件。
注:以下所有路径建议采用纯英文命名,防止出现编码解析错误,为提高转换速度,加载路径层级越短越好
(1)mean.txt制作
(2)imagelist.txt制作
由于Ruyi工具量化模型的过程中,blob1中需要加载image_list所需的文件,这里需要提前制作好。
我们在素材集里面截取典型的图片,约10张左右即可,建议宽高大于256*256,如下图sample_photo文件夹所示:
imagelist.txt里面需要添加sample_photo文件加图片的本地绝对路径,如下图所示:
(3)RuyiStudio量化wk模型
NNIE新建工程完成的前提下,右键.cfg文件-Open With-Mapper Configuration Editor打开.cfg文件,如下图所示:
需仔细配置.cfg里面的每一个参数,勾选Relative path。
首先配置Input_Setting
Mapper Setting配置:
本模型为CNN模型,compile_mode选择Low-bandwidth,log_level默认选择Not print,align_bytes选择16,batch_num输入1,sparse_rate输入0即可,gfpq_param_file为空即可,若使用其他模型,需根据模型实际参数进行配置。
Dynamic Parameters配置:
image_typex:需根据实际来选择,本实例为YUV420SP
image_list:加载制作生成的imageList.txt,一般十张左右图片,imageList.txt填写图片的绝对路径
RGB_order:本实例为RGB,需根据实际来选择
nor_type:本实例选择channel mean_value_with_data_scale,其他网络根据实际来选择
data_scale=1/(0.5*255)=1/std=0.0078431372549019607843137254902,注:data_scale精度越高越好
std来源于mmclassification_master/configs/base/datasets/imagenet_bs32.py
mean_file:加载制作生成的mean.txt即可
所有的参数都配置正确后,接下来进行量化,运行代码,点击如下图所示的标志:
至此,模型的量化已经阐述完毕。
接下来对该cnn数字识别的sample进行讲解,如下图所示:
运行的主入口在device/soc/hisilicon/hi3516dv300/sdk_linux/sample/platform/svp/nnie中sample_nnie_main.c文件中,如下图所示:
在编译sample_nnie_main.c之前,需要确保已经执行了 3.2.1章节的整编Taurus代码,以及3.2.2章节的Taurus镜像烧录的步骤,
在单编sample_nnie_main.c前,需修改目录下的一处依赖,进入//device/soc/hisilicon/hi3516dv300/sdk_linux目录下,通过修改BUILD.gn,在deps下面新增target,"sample/platform/svp/nnie:hi3516dv300_nnie_sample"
,如下图所示:
单编nnie_sample
步骤一:使用Makefile的方式进行单编(速度会快很多)
cd /home/openharmony/sdk_linux/sample/build
make nnie_clean && make nnie
步骤二:使用OpenHarmony的BUILD.gn方式进行单编(速度较慢)
hb set # 选择 ipcamera_hispark_taurus_linux
hb build -T device/soc/hisilicon/hi3516dv300/sdk_linux/sample/platform/svp/nnie:hi3516dv300_nnie_sample
编译成功后,即可在out/hispark_taurus/ipcamera_hispark_taurus_linux/rootfs/bin目录下,生成 ohos_nnie_demo可执行文件,如下图所示:
方式一:使用SD卡进行资料文件的拷贝
mount -t vfat /dev/mmcblk1p1 /mnt
# 其中/dev/mmcblk1p1需要根据实际块设备号修改
方式二:使用NFS挂载的方式进行资料文件的拷贝
mount -o nolock,addr=192.168.200.1 -t nfs 192.168.200.1:/d/nfs /mnt
cp /mnt/ohos_nnie_demo /userdata
cp /mnt/*.so /usr/lib/
cp /mnt/data /userdata -rf
chmod 777 /userdata/ohos_nnie_demo
cd /userdata
./ohos_nnie_demo 4
分析log可以看出,识别到的值为0,符合输入图片的逻辑。
注:当然也可以对自己转换出来的分类网cnn模型,替换现有的wk模型,并选择一张图片进行推理验证,思路跟该sample类似。
检测网作为人工智能训练的常用网络,NNIE支持的检测网有FasterRcnn、SSD、Yolov1、Yolov2、Yolov3、RFCN等,本文采用darknet框架,以Yolov2网络为例,来对检测网进行阐述。
数据集制作可以采用开源的数据或者自研数据集,若采用自研数据集,视频录制的方法、数据集的制作请参考 本文4.2.2.3.2章节和4.2.2.3.3章节的内容,这里不再赘述。
本文公开数据集为例,讲述如何进行检测网的数据集制作和标注,具体步骤请参考《hand_dataset开源数据集的处理及标注》。
若是自己的数据集,可通过labelme开源工具进行标注,将标注生成的.json格式或者其他格式通过脚本转成dartnet框架支持的数据集标注方式,进行训练即可,该方式参考开源代码自行实现即可。
(注意:如果您使用的是海思提供的训练服务器,此5.3.2.4.2 小节可以跳过,按照海思提供的训练服务器的训练指导文档操作即可)
(1)训练环境搭建
注意:以下软件包和环境的安装均需要在open-mmlab虚拟环境下进行,如果不知道如何进入open-mmlab的虚拟环境,请参考5.3.2.3.4.1小节的步骤三
https://www.123pan.com/s/iiMUVv-pIFLh
cd ~
unzip darknet-master.zip
cd darknet-master
make clean && make
(2)模型训练
# test_dataset为测试数据
# training_dataset为训练数据
# JPEGImages目录下是需要进行训练的数据集图片
# labels目录下的txt是JPEGImages目录下对应图片所标注的labels
# list目录下的hand_train.txt文件中保存的是JPEGImages目录下所有图片的绝对路径。
# 注意:所有的txt文件都必须是linux格式的,可以使用 dos2unix 工具进行文件格式的转换
# 使用方法: dos2unix filename (如果还不知道如何使用,可上网咨询度娘)
# classes:为指定类别数量,手部检测模型为1,其他模型需根据实际场景进行填写
# train:指定训练数据list的路径
# valid:指定测试数据list的路径
# names:指定类别的名字
# backup:指定训练后权重的保存路径
注:以上训练指令路径需在Linux环境下进行修改,并确保 ~/darknet-master/cfg/下的 resnet18.cfg已经参考resnet18.cfg网络修改正确。可参考 https://netron.app/ 查看网络结构和参数,部分网络结构截图如下图所示:
./darknet detector train hand.data cfg/resnet18.cfg -gpus 0,1,2,3
# darknet为可执行文件
# detector为必选参数,直接沿用即可
# train指定当前模式为训练模式,测试时候需要改成test或者valid。
# hand.data是一个文件,文件中指定了训练中数据、类别、模型存储路径等信息。
# resnet18.cfg是一个文件,文件中指定了训练的模型。
# -gpus 0,1,2,3 是指使用编号为0,1,2,3的这4个GPU进行训练,如果您的训练服务器只有一张显卡,那这个参数可以去掉。
对终端输出的一个截图做如下解释:
由于检测网训练时间较长,请耐心等待。
(3)模型结果
训练成功后,即可在~/darknet-master/backup 目录下查看.weights文件,若出现resnet18_final.weights表示最终训练完成,如下图所示:
步骤2:将刚下载到windows的resnet18_final.weights模型文件,通过samba映射的方式上传到你Ubuntu docker的/root/darknet2caffe/目录下
步骤3:执行下面的命令,将darknet模型转换为caffe模型。
# 转换命令遵循:
# python cfg[in] weights[in] prototxt[out] caffemodel[out]
# 本文转换命令如下:
python3.8 darknet2caffe.py resnet18.cfg resnet18_final.weights resnet18.prototxt resnet18.caffemodel
如下图所示:
注:nnie_mapper配置概念请阅读源码的device/soc/hisilicon/hi3516dv300/sdk_linux/sample/doc中《HiSVP 开发指南.pdf》3.5.2章节配置文件说明
注:关于模型量化imageList.txt制作,请仔细参考5.3.2.3.7章节内容
其中:本模型image_type为YVU420SP,RGB_order为RGB,norm_type选择data_scale
data_scale = 1/255=0.0039215686274509803921568627451
点击转换按钮,稍等片刻,即可完成转换,如下图所示:
转换成功后,如下图所示:
接下来对该yolov2的sample进行讲解,如下图所示:
运行的主入口在device/soc/hisilicon/hi3516dv300/sdk_linux/sample/platform/svp/nnie中sample_nnie_main.c文件中,如下图所示:
在编译sample_nnie_main.c之前,需要确保已经执行了 3.2.1章节的整编Taurus代码,以及3.2.2章节的Taurus镜像烧录的步骤,
在单编sample_nnie_main.c前,需修改目录下的一处依赖,进入//device/soc/hisilicon/hi3516dv300/sdk_linux目录下,通过修改BUILD.gn,在deps下面新增target,"sample/platform/svp/nnie:hi3516dv300_nnie_sample"
,如下图所示:
单编nnie_sample
步骤一:使用Makefile的方式进行单编(速度会快很多)
cd /home/openharmony/sdk_linux/sample/build
make nnie_clean && make nnie
步骤二:使用OpenHarmony的BUILD.gn方式进行单编(速度较慢)
hb set # 选择 ipcamera_hispark_taurus_linux
hb build -T device/soc/hisilicon/hi3516dv300/sdk_linux/sample/platform/svp/nnie:hi3516dv300_nnie_sample
方式一:使用SD卡进行资料文件的拷贝
mount -t vfat /dev/mmcblk1p1 /mnt
# 其中/dev/mmcblk1p1需要根据实际块设备号修改
方式二:使用NFS挂载的方式进行资料文件的拷贝
mount -o nolock,addr=192.168.200.1 -t nfs 192.168.200.1:/d/nfs /mnt
cp /mnt/ohos_nnie_demo /userdata
cp /mnt/*.so /usr/lib/
cp /mnt/data /userdata -rf
chmod 777 /userdata/ohos_nnie_demo
cd /userdata
./ohos_nnie_demo 7
分析log可以看出,识别到的class的值为1,符合输入车的图片内容。
注:当然也可以对自己转换出来的yolov2检测网wk模型,替换现有的wk模型,并选择一张图片进行推理验证,思路跟该sample类似。
接下来对该Segnet的sample进行讲解,如下图所示:
运行的主入口在device/soc/hisilicon/hi3516dv300/sdk_linux/sample/platform/svp/nnie中sample_nnie_main.c文件中,如下图所示:
在编译sample_nnie_main.c之前,需要确保已经执行了 3.2.1章节的整编Taurus代码,以及3.2.2章节的Taurus镜像烧录的步骤,
在单编sample_nnie_main.c前,需修改目录下的一处依赖,进入//device/soc/hisilicon/hi3516dv300/sdk_linux目录下,通过修改BUILD.gn,在deps下面新增target,"sample/platform/svp/nnie:hi3516dv300_nnie_sample"
,如下图所示:
单编nnie_sample
步骤一:使用Makefile的方式进行单编(速度会快很多)
cd /home/openharmony/sdk_linux/sample/build
make nnie_clean && make nnie
步骤二:使用OpenHarmony的BUILD.gn方式进行单编(速度较慢)
hb set # 选择 ipcamera_hispark_taurus_linux
hb build -T device/soc/hisilicon/hi3516dv300/sdk_linux/sample/platform/svp/nnie:hi3516dv300_nnie_sample
方式一:使用SD卡进行资料文件的拷贝
mount -t vfat /dev/mmcblk1p1 /mnt
# 其中/dev/mmcblk1p1需要根据实际块设备号修改
方式二:使用NFS挂载的方式进行资料文件的拷贝
mount -o nolock,addr=192.168.200.1 -t nfs 192.168.200.1:/d/nfs /mnt
cp /mnt/ohos_nnie_demo /userdata
cp /mnt/*.so /usr/lib/
cp /mnt/data /userdata -rf
chmod 777 /userdata/ohos_nnie_demo
cd /userdata
./ohos_nnie_demo 1
在介绍Non-support层处理方式之前,先介绍下一个网络层的分类,一个网络的层可分为如下3类:
标准层:NNIE支持的Caffe标准层,如Convolution、Pooling层等;
扩展层:NNIE支持的公开但非Caffe标准层,分为2种:
一种是基于Caffe框架进行自定义扩展的层,比如Faster RCNN中的ROIPooling层、SSD中Normalize层、RFCN中的PSROIPooling层,SegNet中的UpSample层等;
另外一种是来源于其他深度学习框架的自定义层,比如YOLOv2中Passthrough层等;
Non-support层:NNIE不支持的层,比如Caffe中专用于Tranning的层、其他非Caffe框架中的一些层或者用户自定义的私有层等。
当网络中存在Non-support层时,需要将网络进行切分,不支持的部分由用户使用CPU 或者DSP等方式实现,统称为非NNIE方式。由此整个网络会出现NNIE->非NNIE- >NNIE… 的分段执行方式。
nnie_mapper将NNIE的Non-support层分为两种,“Proposal”层和“Custom”层:
(1)Proposal层输出的是矩形信息(Bbox,即Bounding box);Proposal自定义层格 式如下,包含name\type\bottom\top等关键字段参数,type必须为 “Proposal”,支持任意多个的bottom,但是top只有一个。
layer {
name: "proposal"
type: "Proposal"
bottom: "rpn_cls_prob_reshape"
bottom: "rpn_bbox_pred"
top: "rois"
}
Proposal层还支持以下参数的解析,但不产生实际的效果。
(2)Custom层输出的是tensor(feature map、vector);Custom自定义层格式如下,仅包含name\type\bottom\top\ custom_param\shape\dim关键字段,type 必须为“Custom”,支持任意多个top\bottom,custom_param中的shape信息 是描述top输出的形状,如果有多个输出,则按top顺序书写多个shape。用户原有其他的参数字段需删除。
layer {
name: "custom1"
type: "Custom"
bottom: "conv1"
bottom: "conv2"
bottom: "pooling1"
top: "custom1_1"
top: "custom1_2"
custom_param
{
shape {
dim: 1
dim: 256
dim: 64
dim: 64
}
shape {
dim: 1
dim: 128
dim: 128
dim: 128
}
}
}
在nnie_mapper对网络模型进行转化之前,用户需根据上述特性将Non-support层 修改为“Proposal”层或者“Custom”层,具体修改方式参考源码的device/soc/hisilicon/hi3516dv300/sdk_linux/sample/doc中《HiSVP 开发指南.pdf》中“3.2 Prototxt要求”。
以RFCN网络为例进行阐述
RFCN跟Faster RCNN类似,RPN部分的Proposal层(Bbox_transform、Argsort、NMS 等操作)输出的是Bounding Box信息,由此网络被分为5段NNIE:
第1段(NNIE执行),卷积部分,包含RPN前面的部分;
第2段(非NNIE执行),Proposal部分,生成矩形框信息;
第3段(NNIE执行),左边的PsRoiPooling部分以及后续的Pooling等,得到矩形框调整值;
第4段(NNIE执行),右边的PsRoiPooling部分以及后续的Pooling等,得到矩形框置信度;
第5段(非NNIE执行),结果获取部分,由3、4段得到的矩形框调整值和置信度经过bbox_transfom、argsort、NMS、ClipBox等步骤获取最终的矩形框和置信度信息。
RFCN 网络 mapper 自动分段示意图,如下图所示:
类似Faster RCNN,考虑将Reshape->Softmax->Reshape->Proposal一起又CPU执行,RFCN 自定义分段示意图如下图所示:
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。