现在越来越多的人选择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. logistics回归理解

    多元回归方程:假设有一个因变量y和一组自变量x1, x2, x3, ... , xn,其中y为连续变量,我们可以拟合一个线性方程: y =β0 +β1*x1 +β2*x2 +β3*x3 +...+βn ...

  2. leedcode算法解题思路

    1.两数之和 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标. 你可以假设每种输入只会对应一个答案.但是,你不能重复利用这个 ...

  3. VBA 生成XML(转)

    需要引用连个库,Microsoft ADO Ext. 6.0 for DDL and Security, Miscrosoft  ActiveX Data Objects 2.7 Library . ...

  4. PHP整理--PHP语句流程

    PHP跟JS一样是从上往下的执行语句:同样的PHP也有if语句.循环.数组和函数. 一.条件语句   if..else...    swich  (1)多条if语句 $name=30; if($nam ...

  5. 在MyEclipse中搭建spring-boot+mybatis+freemarker框架

    一.创建项目 1.右键-->New-->Project... 2.选中Maven Project,点击next 3.选中第一个 4.添写Group Id,Artifact Id,选择Com ...

  6. JS的作用域链

    JavaScript词法性质作用域 简而言之就是,在JavaScript中,函数的作用域在编译时期就已经确定下来了,而不是取决于他的执行位置 var num = 10; function method ...

  7. DecimalFormat 的用法

    DecimalFormat 是 NumberFormat 的一个具体子类,用于格式化十进制数字. DecimalFormat 是 NumberFormat 的一个具体子类,用于格式化十进制数字.Dec ...

  8. H5新特性---Web Worker---Web Stroage

    今天的目标 3.1:h5新特性八--Web Worker---代码就3行 程序:program 存储在外存(磁盘)中代码 进程:Process/Task 将程序调用内存中,分配空间 线程:Thread ...

  9. JQUERY-修改-API-事件绑定

    正课: 1. 修改: 2. 按节点间关系查找: 3. 添加,删除,克隆,替换: 4. 事件绑定: 1. 修改: 内容: html片段: .html(["html片段"])      ...

  10. h5页面关于复制某段文字

    上次的项目有一段内容是点击复制按钮 然后复制一段文字,此段方法我才用的是range.selectNodeContents方法,range对象的SelectNodeContents方法将于range对象 ...