作者:吴书卫
本文整理自TalkingData T11大数据大会中吴书卫博士的演讲。
主持人:我们或多或少听到很多智能的东西,比如AlphaGo、智能驾驶汽车,这里面都蕴含着一个东西,就是这两年非常火热的机器学习的分支深度学习(Deep Learning)。提到Deep Learning的话,大家可能都知道今年Google开源的TensorFlow,像Caffe等等,有越来越多深度学习的框架在产生。
对于广大IT人士来讲,或者对于广大的程序员来讲,普通深度学习的框架还是稍有门槛。那有没有比较简单的呢?尤其是像我是C++转Java,有没有比较好的深度学习的框架让我们用呢?答案是Yes。今天非常有幸地请到了在Java时代支持Java做深度学习的公司Skymind,他们开源了一个产品叫Deeplearning4j,这个是为广大Java程序员,让我们能够使用深度学习的能力去探索数据,去孕育智能。
Skymind公司创始人Adam Gibson 是位很年轻的计算机科学家,生于1989年。他在硅谷的Zipfian Academy (现在称为 GalvanizeU)教机器学习的期间,接触到了硅谷的几位知名的专研深度学习的数据科学家,他们涉及到的其中一个项目就是谷歌大脑。Adam Gibson由此意识到了深度学习惊人的能力。
但是那时只有谷歌能将深度学习应用到实际项目中。当然当时也有其他的深度学习框架,比如Caffe 和 Theano,但是这些只供研究使用,并没有真正的运用到企业当中去。2013年的时候,他创立了开源框架Deeplearning4j和ND4J。Deeplearning4j是用Java和Scala编写的开源深度学习库,可与Hadoop以及Spark集成,即插即用,方便开发者在APP中快速集成深度学习功能。这里我会讲讲Deeplearning4j如何帮助大家将深度学习使用到生产环境中。
我们都知道,现在深度学习在机器学习领域是一个很热门的概念,不过经过各种媒体的转载播报,这个概念也逐渐变得有些神话的感觉:例如,人们可能认为,深度学习是像人脑一样,拥有像人一样的智慧,将来也可能会毁灭世界。而我们都错了,它是模拟人脑的神经结构,并没有像人一样的智慧,但是呢,比较现有的算法,这种模拟技术却大大提高了计算的精准度与准确率。
深度学习有许多种不同的实现形式,根据需要解决的问题、应用领域,它也有不同的名字,例如Convolutional Neural Networks、Deep Belief Networks、Restricted Boltzmann Machines、Deep Boltzmann Machines、Recursive Autoencoders、Deep Representation等等。不过究其本质来讲,都是类似的深度神经网络模型。
深度学习这样一种神经网络模型在以前就出现过了,但是为什么在经历过一次没落之后,到现在又重新进入人们的视线当中呢?这是因为在十几年前的硬件条件下,对高层次多节点神经网络的建模,时间复杂度,几乎是无法接受的。在很多应用当中,实际用到的是一些深度较浅的网络,虽然这种模型在这些应用当中,取得了非常好的效果,但由于这种时间上的不可接受性,限制了实际应用的推广。而到了现在,计算机硬件的水平与之前已经不同了,因此神经网络这样一种模型便又进入了人们的视线当中。
2012年6月,纽约时报报导了Google Brain这个项目,吸引了公众的广泛关注。这个项目是由著名的在Standford的机器学习教授Andrew Ng和在大规模计算机系统方面的世界顶尖专家Jeff Dean共同主导,用16000个CPU Core的并行计算平台训练一种称为 “深层神经网络”Deep Neural Networks。
从Google Brain这个项目中,我们可以看到,神经网络这种模型对于计算量的要求是极其巨大的,为了保证算法实时性,需要使用大量的CPU来进行并行计算。
当然,深度学习现在备受关注的另外一个原因,当然是因为在某些场景下,这种算法模式识别的精度,超过了绝大多数目前已有的算法。
为什么说Caffe、Theano这些只是供研究使用呢?因为这些工具或框架,都是用Pyhton编写出来的。而在现实社会,所有的大数据系统,工具,比如Hadoop, Spark, Flink, Mesos, Cassandra,Kafka等 都是由Java编写的。换言之,你如果你想要把Caffe, Theno, Tensor Flow这些由Python 编写的的深度学习框架,融入这些大数据系统,你必须 想办法解决 Python 与 Java (在每个工具之间)的链接。每一次,每个工具的更新,都必须把相应的链接也更新。这是相当费劲的,也是非常不实际的,会产生出很多意想不到的问题(整合问题)。所以,要解决这个问题,就需要把深度学习框架用 Java 编写出来。需要编写一个可以融入大数据系统或企业的框架,同时拥有像谷歌或更先进的深度学习框架 – 让其他大小型企业也可以受惠。Deeplearning4j 也因此诞生了。Deeplearning4j不只是考虑到大数据使用的编程语言,同时我们也考虑到数据的传递,处理,以及将模型训练出来之后,该如何运用的问题。
首先,我们想要知道的是,数据科学家在企业里部署深度学习或使用机器学习时,总会遇到的问题:
首要的问题就是以数据为质心的模式(Data Gravity)。一旦你把数据放在某个地方,那么那个地方就会拥有非常多的程序或应用。程序和应用围绕数据服务,就像各大行星围绕太阳运转一样。
一般的情况下,因为使用的编辑语言不通(大数据=Java,深度学习=Python),所以数据科学家都把数据从大数据系统抽取出来,并把它安放在另一个电脑或服务器,然后再进行数据处理,使用数据训练深度学习模型。这个情况导致整个深度学习模型训练流程复杂化。
如果要移动 1 GB的数据,很简单。
如果要移动 500 GB 的数据,有点麻烦。
如果要移动100TB 以上的数据,那时就会产生很多的coefficient of friction, 就是摩擦系数。
所以,大多数的企业,都是在Hadoop上运行所有些程序和应用。换句话说,如果你必须把数据移来移去的,那么你就没有拥有一个合适的大数据架构。
第二个,就是系统整合的问题。 这是我们常常会遇到的问题。我的一个同事有一次需要帮美国的一个保险公司做数据分析。他们有一个Hadoop系统,这是好事。对方表示需要使用机器学习来做Twitter分类,当然因为Twitter分类分析一直以来是最好的用例。
开始时是用 TF-IDF 来做一个分类。TF-IDF就是term frequency–inverse document frequency,是一种用于信息检索与数据挖掘的常用加权技术。TF-IDF 基本上就是要把每个文字都向量化,然后我们发现这其实是非常难的一件事。为什么呢?因为我们可以开发一个工具来做数据的抽取,转载,装载,但是向量化呢,完全不行。而这只是针对文字,还没考虑到 图片和视频。Hadoop可以采集你的图片、视频,但是要怎么将其变成一个有用的文件呢?一直以来,所有的机器学习工具只能接受他们自己特定的一个格式。所以,我们必须改善机器学习工具。他们需要它可以接受更多的格式,可以接受不同的数据。
这些传统的机器学习架构还必须要有并行迭代算法架构。但是很多机器学习工具还没有这种架构。很多时候并不是他们不想要并行迭代算法架构,而是他们是否需要这种架构,考虑到企业会不会并且值得不值得投钱在这种架构上。因为机器学习能处理的数据实在有限,所以拥有并行迭代算法架构的机器学习工具是很少的。
这些就是数据科学家遇到的问题。
所以,我们认为,使用深度学习,最理想的方案是,不管拥你有大数据,或小数据,我们都应该可以很方便的部署深度学习。
另外就是我们不应花费太多的时间在处理数据、数据向量化的或ETL上。我们必须要专注于开发更多更好的深度学习模型,把这些模型运用到我们的应用上,让我们能更好的分析这些数据,为企业带来更多的盈利。
好,这里我们可以看到,当你在处理海量数据的时候,其实,就像我刚才所说的,很多时候,我们都把时间花费在清理,整理数据上,而不是在建立模型。除了清理和整理数据,其余的时间我们都花费在收集数据集,然后挖掘数据的特征。我们很少将我们的时间应用在优化算法和其他相关的事情上。
所以,大多数的数据工程师其实只用了少数的数据来建立模型。因为,当你处理10GB的数据时,你可能不会发费太长时间。但是,当我们讲到大数据,我们是在说上百或上千TB的数据,想象一下,你们的工作量有多大。公司会不会聘请上万个工程师去处理这些数据,只为了要建立一个机器学习模型。这是不可能的。
同时,我们也要避免,当我们把深度学习模型训练好之后,部署到生产线上的问题,我们需要一个稳定的工具来运行深度学习模型。我们不想要一直为转化器而烦恼。
下面我们再讲讲Deeplearning4j,我们就是考虑到企业在部署深度学习时面对到的种种的问题而设计的。我们一直都称Deeplearning4j 为 大数据里的 “Hadoop”。
在这系列的工具里,Deeplearning4j 是我们深度学习主要的深度学习框架,它是由Java编写 ,里面含有了几乎所有深度学习算法,包裹Reinforce Learning,就是那个最近在国内很红的 AlphaGo所使用的神经网络。
DataVec 是向所有数据库,数据源沟通的工具。
ND4j是用Java编写的numpy,是一个科学计算引擎,目前美国的航空NASA也依赖ND4J来为他们训练和运行机器学习模型。
最后是 Arbiter, 它是在你调模及优化机器学习时的主要工具,帮助检测和评估你的模型。
DataVec 在Deeplearning4j 系列工具里扮演着一个非常重要的角色,它帮我们解决了数据处理的问题。主要工作就是把所有的数据转化成机器学习可以了解的语言。
它在Spark上运行,使用输入输出的格式,就好像Hadoop里的Map Reduce一样。支持大多数的文件格式,比如CSV、文本、音频、视频和图像。然后最主要的是它是开源的,所以你也可以加入你的数据输入格式,让它来帮你处理你的数据。使用DataVec,能解决数据输出,隔离,清理,转换,格式化,和向量化的繁琐的问题。
ND4J,就像我刚才所说的,是由Java编写的科学计算引擎。
一直来,为什么Python会那么受欢迎呢,主要因为它很像Matlab,比如有像NDArray这样的东西。而且一直以来,有很多科学计算引擎的代码都是由Python编写的,然后它可以直接链接到C代码,那就是Numpy。而Java没有这样的一个东西。所以,我们也决定要开发这样的一个东西,但是是由Java编写出来,然后ND4J 就这样诞生了。
你们现在可能想到的是,如果是用Java编写,那么怎么链接到GPU集群上呢?因为GPU用的是C代码。所以,这个解决方案就是JavaCPP。JavaCPP就是Java里的Cyton。它是ND4J里的一个工具,也是一个伟大的发明。主要的任务是搭建Java到Object-C的桥梁。有了JavaCPP你可以像其他Java对象一样来使用Object-C对象。
ND4J的另一个好处,是可以更好的储存图像,可以把很大的图像直接送到GPU的内存。换句话说,我们可以更好的使用Java来储存图像。来完成这所有工作,我们使用的是Off Heap Memory。Off Heap Memory 的目的是不再依赖Java内存。把数据从数据库抽取出来再运行是很慢的,但是把数据放到内存上直接运行是很快的。所以这使我们在整体运行起来会更加快。
顺便一提的是,这功能不只是支持 CUDA 和 CuDNN,同时也支持CPU的 OpenMP, OpenBlas或MKL和 SIMD。然后重要的是ND4J 也是开源的。
最后 也是最主要的 就是 Deeplearnig4j 深度学习框架可让数据科学家轻松的在 Hadoop 大数据系统上使用深度学习建模和运行模型。
Deeplearning4j深度学习框架非常方便,可以即插即用,不需要很多的配置。它拥有分布式、多线程以及普通的单线程深度学习框架。而神经网络可通过iterative reduce 来平行训练,兼容于 Java, Scala 和 Clojure。通过它与Open Stack的整合,使Deeplearning4j成为首个适应以微服务架构的深度学习框架。Deeplearning4j 也是一个开源平台。
当你把deeplearning4j系列的工具运用起来,你就可以很简单的在大数据系统上训练模型。这里可以看到的是使用Deeplearning4j系列工具训练模型的流程。
首先,由DataVec对接数据源,比如Haddop的HDFS,然后在由DataVec 把这些数据转换成机器学习可以接受的语言。他的过程就是数据 提取,转换然后加载,然后再把它们向量化。把这些数据送到Deeplearning4j去建模。在建模的时候,ND4J 让 Deeplearning4j 可以充分利用 GPU 与 CPU 的资源来快速建立模型,然后通过 Arbiter 把这些模型都调到最优化。最后,我们便得到了一个完整的,最优化的深度学习模型。
当你要运用这些模型时,因为我们所有的工具,模型都是由Java编写,所以不需要特意编写一个对接的工具。你可以很简单的使用 Kafka 来对接数据源与 Deeplearnin4j。Deeplearning4j 除了可以用来建模以外,同时也可以用来运行模型。然后把这些使用模型分析出来的结果和预测,送到 WEB 层 和 应用上。因为Deeplearning4j 是使用 ND4J,所以同时也可以充分的利用GPU和CPU的资源,在大数据系统下快速的运行这些模型。
所以,这就是我给你们在生产环境上部署深度学习的解决方案。
通过 Deeplearning4j 系列的工具,你可以在同一个集群上 建模,以及运行模型。也可以完全把GPU融入到集群中快速的训练模型。所以,为了要使用深度学习,你可以不需要有很大的投资,不需要去建立新的集群;可以在原有的集群,Hadoop系统上,使用深度学习。
小结deeplearning4j系列工具已被在美国、欧洲等国家的企业使用。这套深度学习框架不只是收到了各界企业的肯定,其背后的商业支持机构,Skymind也在陆续把这框架弄得更完善,更稳定,让更多的企业可以受惠。
吴书卫,Skymind亚太地区的负责人。
End.