简介
相信大家从玩转OpenAtom OpenHarmony(简称“OpenHarmony”)AI系列专题的其他文章中,已经拓展了OpenHarmony AI在智慧出行、智慧办公等多场景下的AI自动检测、识别和判断的新体验,对于OpenHarmony平台上的AI开发有了一定认识。
如果你已经有了一个AI创意,怎样训练出相关模型?怎样在你的OpenHarmony设备上部署你的AI模型?接下来以OpenHarmony Hi3516dv300小型系统为例,带领大家使用Hi3516dv300 NNIE硬件单元完成手势检测与分类功能。
NNIE是Neural Network Inference Engine的简称,是上海海思媒体SoC中专门针对神经网络特别是深度学习卷积神经网络进行加速处理的硬件单元,支持现有大部分的公开网络,如相关分类网络、检测网络、分割网络等。(详细资料见文末参考链接:《Hi3516dv300平台NNIE开发指南文档》)
开发流程
下面以手势分类这一需求为例,梳理一下相关AI需求在Hi3516dv300开发板端落地的开发步骤:
1) 数据采集:针对设想的手势场景,录制相关场景素材。其中必须考虑到样本的丰富性和可靠性;
2) 数据集制作和标注:对步骤1中的素材抽取生成数据集,同时还必须对数据集进行相应数据清洗和数据标注动作;
3) 算法模型设计:你可以参考相关开源算法模型,并针对于应用场景做相应修改。相关模型选择请参考《Hi3516dv300平台NNIE开发指南文档》3.3公开模型下载章节;本实例中,需要完成手势的检测和分类,其中对于手势检测选用了Yolov2模型,对于手势的分类则选用Resnet18模型;
4) 模型训练:利用算法模型和相应数据集训练出目标模型。模型训练可以部署在本地或者云平台上;
5) 模型转换:目前Hi3516dv300 NNIE配套软件及工具链仅支持Caffe框架,使用其他框架的网络模型需要转化为Caffe框架下的模型。所以必须有相关模型转换步骤;
6) 模型量化仿真:利用RuyiStudio的Runtime wk功能和仿真NNIE功能不断优化模型文件,最终生成部署所需的wukong文件(文件后缀为.wk) ;
7) 板端推理:通过Hi3516dv300摄像头获取的实时图片,加载相关WK文件来完成相关推理动作。(详细开发流程见参考文档:《分类网相关开发流程文档》)
板端推理关键代码
Hi3516dv300板端推理的关键代码,按照执行步骤分成如下三部分:
1) 实时图片获取
获取实时图片的前提需要保证Hi3516dv300相关视频输入VI(Video In)、视频处理子系统VPSS(Video Process Sub-System)、视频输出VO(Video Out)模块做好相应初始化动作和完成模块之间的绑定动作。(详细初始化流程见参考文档:《Hi3516dv300平台HiMPP媒体处理软件开发参考文档》)
ret = HI_MPI_VPSS_GetChnFrame(g_aicMediaInfo.vpssGrp, g_aicMediaInfo.vpssChn0, &frm, s32MilliSec); // 获取通道中一帧图像的数据 if (ret != 0) { ret = HI_MPI_VPSS_ReleaseChnFrame(g_aicMediaInfo.vpssGrp, g_aicMediaInfo.vpssChn0, &frm); // 如获取图像失败,需做图像释放操作 if (ret != HI_SUCCESS) {SAMPLE_PRT("Error(%#x),HI_MPI_VPSS_ReleaseChnFrame failed"}; } }
2) 模型文件加载
本实例中,需要完成手势的检测和分类,需要加载相关两个模型文件。
HI_S32 Yolo2HandDetectResnetClassifyLoad(uintptr_t* model){ SAMPLE_SVP_NNIE_CFG_S *self = NULL; ret = CnnCreate(&self, MODEL_FILE_GESTURE); // 加载手势相关分类模型 *model = ret < 0 ? 0 : (uintptr_t)self; HandDetectInit(); // 加载手势检测模型 SAMPLE_PRT("Load hand detect claasify model success\n"); return ret;}int CnnCreate(SAMPLE_SVP_NNIE_CFG_S **model, const char* modelFile){ s32Ret = SAMPLE_COMM_SVP_NNIE_LoadModel((char*)modelFile, &g_stCnnModel); // NNIE框架加载模型文件 s32Ret = SampleSvpNnieCnnParamInit(self, &g_stCnnNnieParam, &g_stCnnSoftwareParam); // 初始化cnn相关参数}int Yolo2Create(SAMPLE_SVP_NNIE_CFG_S **model, const char* modelFile){ s32Ret = SAMPLE_COMM_SVP_NNIE_LoadModel((char*)modelFile, &g_stCnnModel); // NNIE框架加载模型文件 s32Ret = SampleSvpNnieYolov2ParamInit(self, &g_stYolov2NnieParam, &g_stYolov2SoftwareParam); // 初始化Yolov2相关参数}
3) 输出推理结果
结果推理过程中,先判断是否检测到手势动作,随后对这个手势动作进行分类检测。
HI_S32 Yolo2HandDetectResnetClassifyCal(uintptr_t model, VIDEO_FRAME_INFO_S *srcFrm, VIDEO_FRAME_INFO_S *dstFrm){ ret = FrmToOrigImg((VIDEO_FRAME_INFO_S*)srcFrm, &img); objNum = HandDetectCal(&img, objs); // 检测网检测是否是手势 ret = ImgYuvCrop(&img, &imgIn, &cnnBoxs[biggestBoxIndex]); ret = CnnCalU8c1Img(self, &imgDst, numInfo, sizeof(numInfo) / sizeof((numInfo)[0]), &resLen); // 分类网检测具体手势 HandDetectFlag(numInfo[0]); // 具体手势类型消息打印}
文末小结
本文主要从开发流程和关键板端推理代码等方面介绍了,Hi3516dv300 NNIE AI能力开发的关键流程和细节。方便广大开发者更好地了解和掌握海思NNIE AI开发。OpenHarmony AI能力的丰富离不开广大开发者的参与和共建,也期待更多的开发者加入知识体系组,做出更多富有想象力的作品!
参考链接
OpenHarmony知识体系工作组
https://gitee.com/openharmony-sig/knowledge
Hi3516dv300平台NNIE开发指南文档
https://gitee.com/openharmony/device_soc_hisilicon/raw/OpenHarmony-3.2-Beta3/hi3516dv300/sdk_linux/sample/doc/HiSVP%20%E5%BC%80%E5%8F%91%E6%8C%87%E5%8D%97.pdf
Hi3516dv300平台NNIE相关API文档
https://gitee.com/openharmony/device_soc_hisilicon/raw/OpenHarmony-3.2-Beta3/hi3516dv300/sdk_linux/sample/doc/HiSVP%20API%20%E5%8F%82%E8%80%83.pdf
Hi3516dv300平台HiMPP媒体处理软件开发参考文档
https://gitee.com/openharmony/device_soc_hisilicon/raw/OpenHarmony-3.2-Beta3/hi3516dv300/sdk_linux/sample/doc/HiMPP%E5%AA%92%E4%BD%93%E5%A4%84%E7%90%86%E8%BD%AF%E4%BB%B6%20V4.0%20%E5%BC%80%E5%8F%91%E5%8F%82%E8%80%83.pdf
Hi3516dv300 AI实验文档
https://gitee.com/openharmony/device_soc_hisilicon/blob/OpenHarmony-3.2-Beta3/hi3516dv300/sdk_linux/sample/taurus/ai_sample/README.md
分类网相关开发流程文档
https://gitee.com/openharmony/device_soc_hisilicon/blob/OpenHarmony-3.2-Beta3/hi3516dv300/sdk_linux/sample/taurus/doc/4.2.3.%E5%88%86%E7%B1%BB%E7%BD%91.md