现在越来越多的人选择Mxnet作为深度学习框架,相应的中文社区非常活跃,而且后面推出的gluon以及gluoncv非常适合上手和实验,特别是gluoncv中提供了非常多、非常新的预训练model zoo,比如像yolov3这种~~不过网上(包括Mxnet社区、gluon论坛等等)大多是关于Python版本的话题,关于C++版本的资料却非常少,最近在用C++版本的mxnet,进行人脸检测和识别,踩到不少的坑,在这里总结一下。

1.C++版本的Mxnet需要进行手动编译,里面有不同的数学计算加速方式,比如MKL,MKLDNN或者openblas(前者主要针对Intel的cpu架构,后者是一个比较通用的线性代数优化库,MKLDNN针对神经网络进行优化)等等,编译完成之后可以使用里面的c_api,即#include <mxnet/c_predict_api.h>或者使用提供的cpp的api:#include "mxnet-cpp/MxNetCpp.h"。

2.如果手动编译过Mxnet会发现Mxnet实际上是好几个项目的集合,比如NNVM,mshadow,dmlc等等,后端引擎负责真正的计算部分,前端实现接口调用,而且作者花了大部分精力围绕在Python接口的编写上,所以关于Python方面的接口非常多,而像C、C++的接口真的很少,不过Mxnet是一个经常进行更新的项目,所以以后是否会完善这些拭目以待。

3.性能时间度量。以下:

(1)一定要注意mxnet前端语言可能会异步调用后端的计算结果,以Python为例,当你使用CPU对比较深的resnet模型进行一次预测,有时发现耗仅仅数毫秒,而在后面的asnumpy时却使用了上百毫秒。避免这种情况出现的最好方式就是使用mxnet.ndarray.waitall(),强制等待前面的操作执行完成;

(2)很多操作第一次都会比较耗时,比如load参数到内存,甚至像opencv中的resize有时第一次也会比较耗时,所以如果想公平的统计某一时段的时间开销,最好是先手动执行一次,然后跑多个loop取平均值进行比较。有些同学拿imread一次预测然后统计时间,这样的话相当于把load参数等相关开销都计算在内了,这是不适合的;

(3)关于batch操作。不止训练阶段有batch操作,预测(predict或者inference)也有,比如做人脸识别,需要把检测出来的多个人脸的bounding box的图像分别抠出来然后组成一个batch,这时候识别网络的输入就是batch_num x channel x high x width。为什么需要进行batch操作?假如我们使用GPU,很明显可以进行cuda并行计算大大加快处理速度;如果使用CPU的话某些数学优化库也会让这个速度有一定提升,不过相比较而言不是非常明显;使用batch操作非常需要注意的是一定要考虑内存是否足够,实际处理的时候要评估一下最大的batch数目,否则很容易out of memory;

4.关于Mxnet C/C++的预测,一般用MXPredCreate创建识别引擎PredictorHandle,然后使用MXPredSetInput设置输入,用MXPredForward进行预测,一定要注意的是创建的PredictorHandle在使用完之后一定别忘调用MXPredFree释放,否则跑多次内存会泄漏的非常快。另外要注意C/C++提供的api中,预测的时候MXPredSetInput设置的参数维度是固定的,比如当你的batch数变化的时候PredictorHandle也需要改变,为了feed不同的输入,可以用MXPredReshape重新改变batch_num x channel x high x width的输入形状,而不需要每次重新load参数再调MXPredCreate,因为MXPredCreate的开销非常大,相比较而言MXPredReshape的开销小一些。但MXPredReshape也并不是一点开销没有,当你需要识别的人脸数的batch一直在变,频繁的reshape形状毫无疑问开销就会显得比较大,这样就有一个问题:怎么在使用loop进行识别(也就是对于每个人脸都丢进网络里,输入是1 x channel x high x width识别完一个再接着下一个)和batch方式(输入是batch_num x channel x high x width)之间进行权衡?我觉得一方面要考虑使用的网络在使用batch时到底能提升多大,一方面也需要考虑MXPredReshape本身的开销,比如我们可以设置一个batch数的阈值,当大于这个值的时候进行MXPredReshape,否则直接循环进行预测。

使用C++版本Mxnett进行预测的注意事项的更多相关文章

  1. IOS中多版本,多设备类型支持注意事项

    IOS系统从07年出来,到现在也有6年了,每年发布一次到两次新的设备,从iPhone1,iPhone2 ... iPhone4s再到最新的iPhone5.硬件在升级的过程中CPU的架构也可能发生变化, ...

  2. 基于vs2005以上版本Qt程序发布的注意事项(讲了manifest的问题)

    最近发现了一个非常恼人的程序deployment的问题,估计大家有可能也会遇到,特此memo. 问题的出现我觉得主要还是微软搞的花头太多, 一个不知所谓的manifest文件让本来简单的程序发布变得困 ...

  3. spark1.2.0版本SparkSQL使用parquet类型注意事项

    在Spark1.2.0版本中是用parquet存储类型时注意事项: sql语句: select * from order_created_dynamic_partition_parquet; 在spa ...

  4. 不同OpenCV版本和不同VS版本之间进行配置的注意事项

    下面内容为不同系统和不同版本VS+不同版本OpenCV之间进行配置时的注意事项.本教程中开始提到如果VS版本和OpenCV版本相匹配的话,只要按上述步骤配置都是没有问题的.但是如果说版本不匹配的话,就 ...

  5. 绿色安装MySQL5.7版本----配置my.ini文件注意事项

    前言 由于前段时间电脑重装,虽然很多软件不在C盘,但是由于很多注册表以及关联文件被删除,很多软件还需要重新配置甚至卸载重装. 使用MySQL时就遇到了这种情况,在修改配置文件无效的情况下选择了重新安装 ...

  6. 高版本jQuery设置checkbox状态注意事项

    jQuery 1.9 以后, 使用 .attr(“checked”, true) 或  attr(“checked”, “checked”) 将无法正确设置 checkbox的状态, 同样的, 使用 ...

  7. 如何选择 SQL Server 数据库跟操作系统版本

    简介: 今天老大提需求, 需要一台 Windows 服务器, 需要安装最新版的 SQL Server 数据库.额, 上次搞 Windows 服务器还是4年前的事. 一.啥也没查, 直接下载操作系统.做 ...

  8. Erda 1.1 版本发布|3 大亮点特性最新解读

    来源|尔达 Erda 公众号 ​ Erda v1.1 Changelog: https://github.com/erda-project/erda/blob/master/CHANGELOG/CHA ...

  9. Netty未来展望

    作为<Netty权威指南(第2版)>的结尾章节,和读者朋友们一起展望下Netty的未来. 1应用范围 随着大数据.互联网和云计算的发展,传统的垂直架构逐渐将被分布式.弹性伸缩的新架构替代. ...

随机推荐

  1. python—集合

    ps:非空即真,非0即真(空,0都返回False) pwd=input('pwd:').strip() if pwd: #三种判断为空的方法(直接判断就可以) # if pwd!='': # if l ...

  2. es6对象的扩展

    对象(object)是 JavaScript 最重要的数据结构之一. object 在es6中新增了很多便利的方法 在es6中允许直接写入变量和方法的名称直接作为对象的属性 let x =1 ,y=2 ...

  3. CMD运行JAVA出现编码GBK的不可映射字符处理方法?

    方法一: (将notepad编辑器的编码方式改为ANSI后再进行程序代码的编译,将之前乱码的汉字删除重新输入正常的汉字) 1.notepad编辑器默认编码方式为UTF-8时,CMD里面执行javac ...

  4. WebSocket 实现链接 群聊(low low low 版本)

    py 文件: """ 下载 gevent-websocket 0.10.1 基于Flask + geventWebSocket 建立连接,发送消息,实现群消息功能. &q ...

  5. C#多线程--信号量(Semaphore)[z]

    百度百科:Semaphore,是负责协调各个线程, 以保证它们能够正确.合理的使用公共资源.也是操作系统中用于控制进程同步互斥的量. Semaphore常用的方法有两个WaitOne()和Releas ...

  6. vue-cli 2.x脚手架build目录中的webpack.base.conf.js配置文件

    此文章用来解释vue-cli脚手架build目录中的webpack.base.conf.js配置文件,适用于vue-cli 2.x版本 此配置文件是vue开发环境的wepack相关配置文件,主要用来处 ...

  7. Collection<T> 的一个坑

    当前所在的公司偏好使用 Collection<T>(System.Collections.ObjectModel), 这货比起List<T>不仅少了很多实用方法, 而且还有一个 ...

  8. 服务管理之rsync

    目录 rsync 1. rsync简介 2. rsync特性 4. rsync命令 5. rsync+inotify rsync 1. rsync简介 rsync是linux系统下的数据镜像备份工具. ...

  9. Java发送手机短信(附代码和解析,亲测有效,简便易操作)

    这个方法用的是中国网建SMS短信通相关依赖进行操作的~~ 很简单,仅需要三步,第二部代码直接复制,不需要修改,第三部中的用户名和密钥修改成自己的即可 <1> 首先需要导入三个jar包 &l ...

  10. 从信息论的角度分析DNN的工作原理

    在前面的文章里,使用神经网络的任意函数拟合性结合了一点黎曼几何的坐标系变化的知识,解释了神经网络是怎样根据输入x,计算出每个分类下的能量Ei(x)的,再之后使用能量模型推算出了概率,从而展示了理论上可 ...