首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

大数据与人工智能工具MXNet

我理解的大数据与算法

在开始建立这个公号的时候,取名叫大数据开发者,主要是想分享一些自己在从事数据处理工作过程中积累的技术,同时也分享一下自己对于大数据技术的理解。而由于目前工作重心的变动,在未来一段时间,这里将集中注意力在算法、深度学习与CV领域论文解读与代码复现这几个方面。

可能你会疑惑怎么突然从大数据技术(简单来说是Hadoop家族)转到算法和深度学习上来,乍一看感觉跳变有点剧烈。其实不然,在上一份工作中我对大数据的理解还停留在使用MapReduce,技能栈也限制在Hadoop/Hive/HBase/Spark这样的工具上,以为当熟练掌握了HDFS/Kafka-streaming等的语法和API,那么就成为了一名很好的大数据开发者了。实则不然,好的数据开发者不应该将自己限制为一个API调用人员,而是需要去思考数据背后的价值,发现数据的关系,找到适合于当前数据量级的好的处理方法,这整个过程都是数据驱动,不断迭代的,此时算法和深度学习的工具就可以发挥威力了。

深度学习框架对比

过去这一年,我们团队专注在CV方向,在项目中会涉及到Caffe,Tensorflow,PyTorch和MXNet四个工具,可以说四者各有优劣。

Caffe是由贾扬清博士在Berkeley时候开发的,是最早流行起来的深度学习工具,特点是网络模型和参数配置都依赖protobuf文件,编写简单,运行效率高,但是扩展不易,同时当网络深度加深,模型复杂后,模型配置文件可能会变得难以维护,还有一点则是现在官方也没有继续维护master分支了,遇到问题只能自己解决了。

而Tensorflow因为背靠Google这棵大树,因此刚一开源就受到了极大关注,开发者也迅速上涨,不过可能由于是大公司出品的缘故,代码也是层层封装,如果想要从细节处研究源码的话需要花费较大的时间精力。同时Tensorflow的性能也是广受大家诟病,如果不做限制,它总是一启动就吃光机器的所有资源,这可能也是Google这种量级的公司从不需要担心资源不足所导致。另外Tensorflow主要也是为了服务G家自己的TPU,所以像我们这种财力不足,对性能和资源又很敏感的小团队,就只能望洋兴叹了。

相比之下,PyTorch无论在性能还是易用性上都是很不错的,同时和Torch共用了很大一部分的C/C++的后端库,使得Torch的很多东西可以很方便的移植过来。毕竟Torch在学术界使用广泛,很多论文的一手实现给的也是Torch的实现。除此之外,PyTorch又由Facebook来支撑和维护,所以不会有太大的稳定性顾虑。这里再多提一句,最近Caffe2的代码合入PyTorch,也就是Caffe2+PyTorch=PyTorch 1.0,使得PyTorch吸收了Caffe2强大的后端优势,兼具了快速的开发效率和较高的执行效率。

最后就是我们自己项目中最常用的MXNet,它最大的特点是兼具命令式编程的灵活性和申明式编程的执行效率。对于不熟悉深度学习的朋友来说,这里涉及到两个很重要的概念,命令式编程和申明式编程。

所谓命令式编程,就是普通程序员都熟知的编程范式。它的每一步都按照我们预先输入的指令严格执行,可以很方便和精确的控制每一步的数据流动和逻辑运算,这就仿佛一个懒人,你说一句就他动一下,不下指令就坚决不动,通常我们使用的编程语言C/C++/python等都符合命令式编程。而与之对应的申明式编程,则是提供一整套针对具体应用的迷你语言。既用户只需要声明要做什么,而具体执行则由系统完成,用户是提前指定了整个流程中的数据流动方式,就好像是设计师画了一张跑车的设计图纸,而具体的跑车制造和出厂则交给执行系统,Caffe和Tensorflow都是使用申明式编程的例子。申明式编程对于传统的程序员来说会稍微有点难于接受,这也是我一开始接触深度学习时候花了很多时间来跨过的一道坎。

另外,MXNet的代码也非常简洁,非常符合代码即注释的风格,在它的python wrapper包里,总共也只有100多个文件,涵盖其全部功能,所以我们可以很容易的hack到源码中实现各种自己想要的操作,有极强的扩展能力。

MXNet简介

下面就结合MXNet的python源码包来简单介绍一下MXNet这个黑科技吧。下图展示了MXNet的python接口包所包含的代码,其中主要包含ndarray、symbol、gluon、module包和一些基础文件。

1)MXNet的命令式编程优点由NDArray这个接口来桥接(上图中ndarray对应的相关代码),NDArray理解为一个高维度的Tensor,在定义的时候可以指定这块Tensor所在的硬件介质是CPU还是某块GPU。

下面代码就在0号卡上申明了一个2x3的Tensor并计算它与常量相乘的计算结果,并用numpy打印结果。

2)MXNet的申明式编程接口则通过Symbol来体现,通过提前申明计算图来完成计算流程的构建,最终的输出由输入符号,通常是mxnet.sym.Variable(‘data’)经过一系列的操作子来得到。这些中间的操作可以是简单的矩阵运算,如矩阵乘法、矩阵加法等,也可以是复杂神经网路中间的某些层,如卷积层,池化层。当输入和中间的操作固定之后,我们就得到了一张关于数据流动的图纸,在神经网络中向前计算输出的过程叫forward,求导并获取各个权重梯度的过程则称为backward。整个执行过程中后端引擎系统会分析这个图纸中数据的流向,从而优化其中的步骤,最大化执行效率。

上图的代码就是首先申明了一个输入变量data,并经过一个卷积层和一个Relu激活层得到结果net。

上面的代码则是首先申明了两个输入变量a和b,并申明他们输出c是经过a+b得到,然后通过将输出符号c与数据(a:2x3的全1矩阵,b:2x3的全1矩阵)和设备(cpu)绑定,得到一个执行器(这个过程就好像照着汽车的设计图纸造出汽车),在调用forward()的时候就计算出了实际的输出(2x3的全为2的矩阵)。

如果照着同样的图纸,绑定的输入的数据变了(a:1x1的值为1的向量,b:1x1的值为1的向量),则经过同样的加法操作,得到的输出也就是新数据的计算结果。

如此,我们则只用画一次图纸,却可以针对不同的数据得到不同的模型。这也恰是深度学习的魅力所在,通常“一招鲜,吃遍天”,当你找到了一个好的模型,可以同步提升CV领域检测/分割/分类等多种任务的性能,甚至是实现从文本,到语音到视觉的跨领域扩展。

3)MXNet中多设备之间的数据交互则是通过KVStore来完成,它提供一个分布式的key-value存储来进行数据交换。我们可以把它简单理解为一个包含变量数据的字典,它有两个主要函数,a)push:将key-value对 从一个设备push进存储,b)pull:将某个key的值从存储中pull出来。此外,KVStore还接受自定义的更新(update)函数来控制收到的值如何写入到存储中。并且KVStore提供数种包含最终一致性模型和顺序一致性模型在内的数据一致性模型。

总结

MXNet的初步介绍大致就是这样,总结起来,MXNet通过结合命令式编程和申明式编程相结合,使得它既有灵活性,易于调试,同时又具有极好的执行性能,强烈推荐之。

  • 发表于:
  • 原文链接http://kuaibao.qq.com/s/20180506G104J100?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券