使用C++版本Mxnett进行预测的注意事项
现在越来越多的人选择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进行预测的注意事项的更多相关文章
- IOS中多版本,多设备类型支持注意事项
IOS系统从07年出来,到现在也有6年了,每年发布一次到两次新的设备,从iPhone1,iPhone2 ... iPhone4s再到最新的iPhone5.硬件在升级的过程中CPU的架构也可能发生变化, ...
- 基于vs2005以上版本Qt程序发布的注意事项(讲了manifest的问题)
最近发现了一个非常恼人的程序deployment的问题,估计大家有可能也会遇到,特此memo. 问题的出现我觉得主要还是微软搞的花头太多, 一个不知所谓的manifest文件让本来简单的程序发布变得困 ...
- spark1.2.0版本SparkSQL使用parquet类型注意事项
在Spark1.2.0版本中是用parquet存储类型时注意事项: sql语句: select * from order_created_dynamic_partition_parquet; 在spa ...
- 不同OpenCV版本和不同VS版本之间进行配置的注意事项
下面内容为不同系统和不同版本VS+不同版本OpenCV之间进行配置时的注意事项.本教程中开始提到如果VS版本和OpenCV版本相匹配的话,只要按上述步骤配置都是没有问题的.但是如果说版本不匹配的话,就 ...
- 绿色安装MySQL5.7版本----配置my.ini文件注意事项
前言 由于前段时间电脑重装,虽然很多软件不在C盘,但是由于很多注册表以及关联文件被删除,很多软件还需要重新配置甚至卸载重装. 使用MySQL时就遇到了这种情况,在修改配置文件无效的情况下选择了重新安装 ...
- 高版本jQuery设置checkbox状态注意事项
jQuery 1.9 以后, 使用 .attr(“checked”, true) 或 attr(“checked”, “checked”) 将无法正确设置 checkbox的状态, 同样的, 使用 ...
- 如何选择 SQL Server 数据库跟操作系统版本
简介: 今天老大提需求, 需要一台 Windows 服务器, 需要安装最新版的 SQL Server 数据库.额, 上次搞 Windows 服务器还是4年前的事. 一.啥也没查, 直接下载操作系统.做 ...
- Erda 1.1 版本发布|3 大亮点特性最新解读
来源|尔达 Erda 公众号 Erda v1.1 Changelog: https://github.com/erda-project/erda/blob/master/CHANGELOG/CHA ...
- Netty未来展望
作为<Netty权威指南(第2版)>的结尾章节,和读者朋友们一起展望下Netty的未来. 1应用范围 随着大数据.互联网和云计算的发展,传统的垂直架构逐渐将被分布式.弹性伸缩的新架构替代. ...
随机推荐
- CentOS7+CDH5.14.0安装CDH错误排查:该主机与 Cloudera Manager Server 失去联系的时间过长。 该主机未与 Host Monitor 建立联系
主机错误: 该主机与 Cloudera Manager Server 失去联系的时间过长. 该主机未与 Host Monitor 建立联系 解决办法: 首先查看该主机NTP服务是否启动:https:/ ...
- chip8模拟器的python3实现-1-CHIP8简介
打算编写一个NES模拟器,先从简单的chip8模拟器入手 1.CHIP-8简介 CHIP-8是一个解释型语言,由Joseph Weisbecker开发.最初CHIP-8在上个世纪70年代被使用在COS ...
- ROS零门槛学渣教程系列(一)——ubuntu安装
本教程使用虚拟机安装ubuntu 实验前准备:下载ubuntu系统镜像 本教程使用的是ubuntu14.04lts版本,有能力的读者可自行下载安装. 推荐使用本人制作的镜像,该镜像已安装好ROS.和配 ...
- git安装包解压后没有configure
今天在linux上安装git客户端,解压了tar包后,发现没有configure,无法安装.经查,原来是要先执行autoconf命令,执行后出现configure
- Django form验证
# 模版 class LoginForm(forms.Form): # 模版中的元素 user = forms.CharField(min_length=6,error_messages={" ...
- HTML5-桌面提醒功能
window.webkitNotifications.requestPermission(); statue = window.webkitNotifications.checkPermission( ...
- Jquery 数组操作大全【转载】
转载于:https://www.jb51.net/article/43164.htm 1. $.each(array, [callback]) 遍历[常用] 解释: 不同于例遍 jQuery 对象的 ...
- PYTHON基础入门(内置函数、推导式)学习
**内建函数**1.通过使用dir()函数可以列出所具备的方法 例:num = 10 dir(num) 例:myList = [1,2,3,4,5,6] dir(num)2.通过使用help()函数可 ...
- AJAX随笔1
[1] AJAX简介 > 全称: Asynchronous JavaScript And XML > 异步的JavaScript和XML > AJAX就是通过JavaSc ...
- C++标准库之右值引用相关:引用折叠
引用折叠 引用折叠出现的情况在于范型编程时. void f(T&& param); f(10); int x = 10; f(x); 这两者都可运行成功. 由于存在T&& ...