算法加载
在ARM+Movidius VPU 目标识别调试笔记(一)一文中,我们通过对Ncsdk的分析,已经成功搭建了其开发环境,并且能成功运行简单的HelloWorld程序了。
那么我们下一步工作就是要分析清楚Ncsdk是如果操作来实现算法加速的。
首先我们还是根据官方demo来分析一下。
获取App Zoo
首先我们从github上获取Ncsdk App Zoo,这里面有很多Caffe和tensorflow的demo app,github项目链接在此。源码下载命令为:
git clone -b ncsdk2 https://github.com/movidius/ncappzoo.git
App Zoo 源码获取之后,我们看到如下图图一所示的目录结构:
我们梳理一下上图中几个目录
apps: 一些demo程序的源码
caffe/tensorflow: 这两个目录分别存放基于caffe和tensorflow的计算图
data:运行demo的一些图形库
我们可以直接在apps路径中找C/C++的官方demo,找遍这二十几个例程,只有hello_ncs_cpp和multistick_cpp唯二的例程使用C/C++实现的。hello_ncs_cpp前面已经说过,那么只剩下multistick_cpp可以供我们学习学习C/C++下的api调用方法。那么我们直接来 multistick.cpp 这个文件来分析算法预测过程。
算法预测
这个例程使用两个VPU设备来运行了两张深度学习的计算图,第一张是googlenet.graph,第二张是squeezenet.graph,分别使用这两个网络来对nps_electric_guitar.png和nps_baseball.png两张图片进行image classifier 分类。
GoogLeNet和SqueezeNet两个深度学习网络的算法模型都在图一所示的caffe文件夹下面,我们可以看到这两张网络计算图graph都是通过Makefile编译出来的,但是由于我使用的是tensorflow框架,对caffe没有过多的了解,所以这里并没有深入Makefile的编译过程,此处不做延伸。
另外,在每个文件加中都有一个run.py的python3脚本,它是用来校验和测试这两个网络的性能,运行完成之后,具体的性能参数对比如下表一所述:
Net Name | GoogLeNet | SqueezeNet |
---|---|---|
SHAVE Number | 12 | 12 |
Inference time | 94.02 ms | 46.51 ms |
Bandwidth | 579.31 MB/sec | 701.56 MB/sec |
Input Tensor | [224, 224, 3] | [227, 227, 3] |
Layer Number | 22 | 10 |
从上表中可以看出来,GoogLeNet网络预测的时间为94ms,SqueezeNet网络预测的时间为64ms;GoogLeNet输入层张量的维度为[224, 224, 3],而SqueezeNet的输入层张量为[227, 227, 3]
下面来看看代码实现算法预测的过程吧,如下:
// 第一步,打开设备
if (!OpenOneNCS(0, &devHandle1))
{
// couldn't open first NCS device
// TODO
}
// 第二步,加载计算图
if (!LoadGraphToNCS(devHandle1, GOOGLENET_GRAPH_FILE_NAME, &graphHandleGoogleNet))
{
// TODO
}
// 第三步,获取输入输出张量描述符
// Read tensor descriptors for Googlenet
struct ncTensorDescriptor_t inputTdGooglenet;
struct ncTensorDescriptor_t outputTdGooglenet;
length = sizeof(struct ncTensorDescriptor_t);
ncGraphGetOption(graphHandleGoogleNet, NC_RO_GRAPH_INPUT_TENSOR_DESCRIPTORS, &inputTdGooglenet, &length);
ncGraphGetOption(graphHandleGoogleNet, NC_RO_GRAPH_OUTPUT_TENSOR_DESCRIPTORS, &output