为什么加班的总是我:那个天天12点到岗的程序员,又准点下班陪女友了?!
作为我司头发储量前三的程序员
始终仗着头发多奋斗在加班的第一线
时时灵魂拷问自己
年轻人,你凭什么不加班?
虽然我没有女朋友
但是,我有代码呀
但我不明白的是,隔壁工位那个,到岗比我迟,下班比我早,天天准点儿下班接女朋友,工作还完成的不错的样子,当然,头发也还不错。除了长得比我显老,难道他有什么制胜法宝吗?趁着午休,以一礼拜咖啡为代价,我偷师了他的制胜法宝。
GET了秘诀,或许我也可以事业爱情双丰收了。T^T
直接集成NCNN的缺点
直接集成NCNN熬老少男颜哇,想当年我一边泪流满面地集成,一边想用女友的SK2给自己的脸补补(不,你没有,both SK2和女友),咋回事儿呢,为SqueezeNet接入NCNN,把相关的模型文件,NCNN的头文件和库,JNI调用,前处理和后处理相关业务逻辑等。把这些内容都放在SqueezeNet Sample工程里。这样简单直接的集成方法,问题也很明显,和业务耦合比较多,不具有通用性,前处理后处理都和SqueezeNcnn这个Sample有关,不能很方便地提供给其他业务组件使用。深入思考一下,如果我们把AI业务,作为一个一个单独的AI组件提供给业务的同学使用,会发生这样的情况:
每个组件都要依赖和包含NCNN的库,而且每个组件的开发同学,都要去熟悉NCNN的接口,写C的调用代码,写JNI。所以我们很自然地会想到要提取一个NCNN的组件出来,提取以后呢长得顺眼了很多,大概是这个样子。
AOE SDK里的NCNN组件
有了AOE SDK,我也可以一顿操作猛如虎了!在AOE开源SDK里,我们提供了NCNN组件,下面我们从4个方面来讲一讲NCNN组件:
1.NCNN组件的设计
2.对SqueezeNet Sample的改造
3.应用如何接入NCNN组件
4.对NCNN组件的一些思考
NCNN组件的设计
不懂NCNN的组件设计,即使一顿操作猛如虎,你可能最后也只有两块五。那它的组件是什么嘞?NCNN组件的设计理念是组件里不包含具体的业务逻辑,只包含对NCNN接口的封装和调用。具体的业务逻辑,由业务方在外部实现。在接口定义和设计上,我们参考了TF Lite的源码和接口设计。目前提供的对外调用接口,长这个样子:
// 加载模型和param void loadModelAndParam(...) // 初始化是否成功 boolean isLoadModelSuccess() // 输入rgba数据 void inputRgba(...) // 进行推理 void run(...) // 多输入多输出推理 void runForMultipleInputsOutputs(...) // 得到推理结果 Tensor getOutputTensor(...) // 关闭和清理内存 void close()
而机智骚年本人,用的是这个:
├── AndroidManifest.xml ├── cpp │ └── ncnn │ ├── c_api_internal.h │ ├── include │ ├── interpreter.cpp │ ├── Interpreter.h │ ├── jni_util.cpp │ ├── jni_utils.h │ ├── nativeinterpreterwrapper_jni.cpp │ ├── nativeinterpreterwrapper_jni.h │ ├── tensor_jni.cpp │ └── tensor_jni.h ├── java │ └── com │ └── didi │ └── aoe │ └── runtime │ └── ncnn │ ├── Interpreter.java │ ├── NativeInterpreterWrapper.java │ └── Tensor.java └── jniLibs ├── arm64-v8a │ └── libncnn.a └── armeabi-v7a └── libncnn.a
●Interpreter,提供给外部调用,提供模型加载,推理这些方法。
●NativeInterpreterWrapper是具体的实现类,里面对native进行调用。
●Tensor,主要是一些数据和native层的交互。
AOE NCNN用的好,任务完成早,奥秘在此。
1.支持多输入多输出。
2.使用ByteBuffer来提升效率。
3.使用Object作为输入和输出(实际支持了Bytebuffer和多维数据组)
光说不练假把式,AOE NCNN的实现过程,且听我细细道来。
如何支持多输入多输出
为了支持多输入和多输出,我们在Native层创建了一个Tensor对象的列表,每个Tensor对象里保存了相关的输入和输出数据。Native层的Tensor对象,通过tensor_jni提供给java层调用,java层维护这个指向native层tensor的“指针”地址。这样在有多输入和多输出的时候,只要拿到这个列表里的对应的Tensor,就可以就行数据的操作了。
ByteBuffer的使用
ByteBuffer,字节缓存区处理子节的,比传统的数组的效率要高。
DirectByteBuffer,使用的是堆外内存,省去了数据到内核的拷贝,因此效率比用ByteBuffer要高。
当然ByteBuffer的使用方法不是我们要说的重点,我们说说使用了ByteBuffer以后,给我们带来的好处:
1. 接口里的字节操作更加便捷,例如里面的putInt,getInt,putFloat,getFloat,flip等一系列接口,可以很方便的对数据进行操作。
2. 和native层做交互,使用DirectByteBuffer,提升了效率。我们可以简单理解为java层和native层可以直接对一块“共享”内存进行操作,减少了中间的字节的拷贝过程。
如何使用Object作为输入和输出
目前我们只支持了ByteBuffer和MultiDimensionalArray。在实际的操作过程中,如果是ByteBuffer,我们会判断是否是direct buffer,来进行不同的读写操作。如果是MultiDimensionalArray,我们会根据不同的数据类型(例如int, float等),维度等,来对数据进行读写操作。
对SqueezeNet Sample的改造
集成AOE NCNN组件以后,让SqueezeNet依赖NCNN Module,SqueezeNet Sample里面只包含了模型文件,前处理和后处理相关的业务逻辑,前处理和后处理可以用java,也可以用c来实现,由具体的业务实现来决定。新的代码结构变得非常简洁,目录如下:
├── AndroidManifest.xml ├── assets │ └── squeeze │ ├── model.config │ ├── squeezenet_v1.1.bin │ ├── squeezenet_v1.1.id.h │ ├── squeezenet_v1.1.param.bin │ └── synset_words.txt └── java └── com └── didi └── aoe └── features └── squeeze └── SqueezeInterpreter.java
↑ 本Sample也适用于其他的AI业务组件对NCNN组件的调用。
(牛逼就完事儿)
应用如何接入NCNN组件
对NCNN组件的接入,有两种方式
●直接接入
●通过AOE SDK接入
▲两种接入方式比较:
不BATTLE了,我单方面宣布,AOE SDK完胜!
对NCNN组件的总结和思考
通过对NCNN组件的封装,现在业务集成NCNN更加快捷方便了。之前我们一个新的业务集成NCNN,可能需要半天到一天的时间。使用AOE NCNN组件以后,可能只需要1-2小时的时间。当然NCNN组件目前还存在很多不完善的地方,我们对NCNN还需要去加深学习和理解。后面会通过不断的学习,持续的对NCNN组件进行改造和优化。
- - - - - - - - - - - - - - - - - - - - - - - - - - - - A o E - - - - - - - - - - - - - - - - - - - - - - - - - - - -
原创不易,经验宝贵,欢迎打赏!
(↑ ↑ ↑ 听说点击的人都准点儿下班了↑ ↑ ↑ )

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
拐点已至,云原生引领数字化转型升级
作者 | 易立 阿里云资深技术专家 本文整理自易立在 2019 携程技术峰会上发表的题目为《拐点已至,云原生引领数字化转型升级》的演讲。 关注“阿里巴巴云原生”公众号,回复关键词“转型”即可下载本文 PPT。 今天我跟大家分享的题目是“拐点已至,云原生引领数字化转型升级”。先做个简单的自我介绍,我叫易立,来自于阿里云容器平台,从 2015 年开始负责阿里云容器产品,之前在 IBM 工作 14 年,主要负责企业中间件和云计算的产品研发。 今天会跟大家分享我们对云原生领域的简单思考,以及我们对云原生发展四个趋势大概的介绍: 拥抱 Serverless – 极致弹性,无需运维; 服务网格 – 将服务治理能力与应用解耦,并下沉到基础设施层; 云原生应用管理标准化 – 构建高效、自动化和可信赖的应用交付体系; 计算无边界 – 实现云-边缘-IoT 设备
- 下一篇
这项智能制造技术,竟能为每条产线省下42000美元!
一个不起眼的瑕疵有多么可怕?我们常说,“千里之堤,溃于蚁穴”,并非耸人听闻之言。在高速公路事故统计中,70%的事故由轮胎引起,且在高速行驶下的生还率非常低。而在生产力大幅提升的当下,像这样的产品仅靠人工检测是很难做到的,这就需要运用物联网、人工智能等技术。 工业制造领域,瑕疵检测一直是生产过程中的重要一环。众所周知,工厂实际生产过程并不能保证生产出来的产品百分之百的完美,或者是产品是螺丝没有拧紧,或者是表面有细小的凹陷和划痕,或者是产品标签忘记粘贴……特别是在电子产品、汽车、航天航空等高科技产业中,如果因为一个不起眼的瑕疵导致安全事故的发生,轻则致使财产受到损失,重则甚至可以发生伤亡事故——无论如何,对于企业而言都是难以承受的伤痛。 为确保产品质量,以往工厂往往会耗费上千人力进行人工视觉检查,防止瑕疵产品流入市场。但在实际的工厂运营中
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- CentOS8编译安装MySQL8.0.19
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7
- Eclipse初始化配置,告别卡顿、闪退、编译时间过长
- Docker安装Oracle12C,快速搭建Oracle学习环境
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- Mario游戏-低调大师作品
- CentOS7编译安装Gcc9.2.0,解决mysql等软件编译问题
- CentOS7编译安装Cmake3.16.3,解决mysql等软件编译问题
- SpringBoot2更换Tomcat为Jetty,小型站点的福音