引言:你可能对使用spark服务比较感兴趣。spark已经提供了很多功能,也有一个好用的界面,而且背后有强大的社区,开发者十分活跃,这也是人们对spark寄予厚望的原因。深度学习是当前正在进行中的spark项目之一。本文我们将介绍一些spark能用的深度学习框架。 本文选自《spark:大数据集群计算的生产实践》。
深度学习因其高准确率及通用性,成为机器学习中最受关注的领域。这种算法在2011—2012年期间出现,并超过了很多竞争对手。最开始,深度学习在音频及图像识别方面取得了成功。此外,像机器翻译之类的自然语言处理或者画图也能使用深度学习算法来完成。深度学习是自1980年以来就开始被使用的一种神经网络。神经网络被看作能进行普适近似(universal approximation)的一种机器。换句话说,这种网络能模仿任何其他函数。例如,深度学习算法能创建一个识别动物图片的函数:给一张动物的图片,它能分辨出图片上的动物是一只猫还是一只狗。深度学习可以看作是组合了许多神经网络的一种深度结构。
与其他已有的机器学习算法相比,深度学习需要大量参数及训练数据。这也是我们介绍能在spark上运行的深度学习框架的原因。要想在企业环境中稳定地进行深度学习的训练,必须要有一个可靠而快速的分布式引擎。
spark被视为目前最适合运行深度学习算法的平台,是因为:
基于内存的处理架构对于使用机器学习的迭代计算,特别是深度学习,十分适合。
spark的几个生态系统如mllib及tachyon对于开发深度学习模型很有用。
本文我们将介绍一些spark能用的深度学习框架。这些框架和深度学习一样,都是比较新的库。很可能你在使用它们的过程中遇到一些bug或者缺少一些操作工具,但是报告问题(issue)及发送补丁将会使它更加成熟。
1.首先需要从h2o网站下载最新的sparking-water。
2.把它指向spark的安装目录。
3.启动sparkling-shell,这个接口与spark-shell类似。
sparkling-water源码中包含几个例子。不幸的是,有些例子在spark 1.5.2版本上无法正常运行。深度学习的demo也有相同的问题。你得等待这些问题被解决,或者自己写几个能在spark运行的补丁。
deeplearning4j是由skymind开发的,skymind是一家致力于为企业进行商业化深度学习的公司。deeplearning4j框架是创建来在hadoop及spark上运行的。这个设计用于商业环境而不是许多深度学习框架及库目前所大量应用的研究领域。skymind是主要的支持者,但deeplearning4j是开源软件,因此也欢迎大家提交补丁。deeplearning4j框架中实现了如下算法:
受限玻尔兹曼机(restricted boltzmann machine)
卷积神经网络(convolutional neural network)
循环神经网络(recurrent neural network)
递归自编码器(recursive autoencoder)
深度信念网络(deep-belief network)
深度自编码器(deep autoencoder)
栈式降噪自编码(stacked denoising autoencoder)
这里要注意的是,这些模型能在细粒度级别进行配置。你可以设置隐藏的层数、每个神经元的激活函数以及迭代的次数。deeplearning4j提供了不同种类的网络实现及灵活的模型参数。skymind也开发了许多工具,对于更稳定地运行机器学习算法很有帮助。下面列出了其中的一些工具。
-- csv
--原始文本格式(推文、文档)
--图像(图片、图画)
--定制文件格式(例如mnist)
由于canova主要是用java编写的,所以它能运行在所有的jvm平台上。因此,可以在spark集群上使用它。即使你不做机器学习,canova对你的机器学习任务可能也会有所裨益。
编译类位于target目录下,但是可以通过bin/run-example脚本运行这些例子。当前有三种类型的例子:
ml.javairisclassfication——鸢尾花(iris flower)数据集分类。
ml.javalfwclassfication——lfw人脸数据库分类。
ml.javamnistclassfication——mnist手写数据分类。
差不多可以开始运行训练进程了。你需要注意的最后一点是spark executor及driver的内存大小,因为 mnist数据集和它的训练模型将会很大。它们要用到大量内存,因此我们建议你提前修改bin/run-example脚本中设置的内存大小。可以通过如下命令修改bin/run-example脚本的最后一行:
现在开始训练:
为了指定本地spark的master配置,我们已经在bin/run-example脚本的前面设置了master环境变量。这种训练需要花一些时间,由你的环境及机器规格决定。这个例子运行了一种叫作“卷积神经网络”的神经网络。其参数细节是通过multilayerconfiguration类设置的。由于deeplearning4j有一个java接口,就算你不习惯spark的scala语言也没关系,它是很容易引入的。下面简单解释一下这个例子中的卷积神经网络参数。
seed——此神经网络会使用像初始网络参数这样的随机参数,这个种子就用于产生这些参数。有了这个种子参数,在开发机器学习模型的过程中更容易进行测试与调试。
batchsize——像递度下降之类的迭代算法,在更新模型之前会汇总一些更新值,batchsize指定进行更新值计算的样本数。
iterations——由一个迭代进程保持模型参数的更新。这个参数决定了此迭代处理的次数。通常来说,迭代越长,收敛的概率越高。
optimizationalgo——运行前述的迭代进程,必须用到几种方法。随机梯度下降(stochastic gradient
descent,sgd)是目前为止最先进的方法,这种方法相对来讲不会落入局部最小值,还能持续搜索全局最小值。
layer——它是深度学习算法的核心配置。这个深度学习神经网络有几个名为layer的网络组。这个参数决定了在每一层中使用哪种类型的层。例如,在卷积神经网络的案例中,convolutionlayer被用于从输入的图像中提取出特征。这个层能学习一个给定的图片有哪种类型的特征。在一开始就放置这个层,将改善整个神经网络预测的精确性。每个层也能用给定的参数进行配置。
上图展现了神经网络的通用结构。由于convolutionallayer也是一种神经网络,两种网络的部件基本上是相同的。神经网络有一个输入(x)及输出(y)。它们都是向量格式的数据。在上图中,输入为一个四维向量,而输出也是一个四维向量。输出向量y是怎样计算出来的呢?每层都有一个参数矩阵。在本例中,它们用w表示。x与w相乘得到下一个向量。为了增强这个模型的表达,这个向量被传给某个非线性激活函数(σ),例如逻辑sigmoid函数(logistic sigmoid function)、softmax函数。使用这个非线性函数,神经网络就能逼近任意类型的函数。然后用z与另一个参数矩阵w相乘,并再次应用激活函数σ 。
你可以看到convolutionlayer的每个配置。nin及nout是输入向量vector(x)及输出向量vector(z)的维度。activation是这个层的激活函数,由逻辑sigmoid函数与修正线性单元所选择。根据你的问题,输入及输出的维度能被立即确定。其他参数应当通过网格搜索来优化,这一点将在后面讲述。
backprop——反向传播(backpropagation)是目前用于更新模型参数(w)最先进的方法。因此,这个参数应当总是true。
pretrain——由于有预训练(pretraining),多层网络能从输入数据提取出特征,获得经过优化的初始参数。也推荐把它设为true。
sparknet的架构很简单。sparknet负责分布式处理,而核心的学习过程则委托给caffe框架。sparknet通过java native访问caffee框架提供的c api。caffee是用c++实现的,caffe的c包装器写在sparknet的libcaffe目录下。所以sparknet的整体代码库相对较小。java代码(caffelibrary.java)进一步包装了这个库。为了在scala世界里使用caffelibrary,caffe还提供了caffenet。下图展现了caffenet的层级。
如果你熟悉scala,那么开发sparknet的应用程序时只需要考虑caffenet。而且你也可以使用spark rdd。它是通过一个javadatalayer c++代码的包装器来实现的。除此之外,sparknet能加载caffe格式的模型文件。这个扩展通常是通过.prototxt来设置的:
替换模型的输入,你可以在spark上训练自己的数据。sparknet还提供了实用程序:
想及时获得更多精彩文章,可在微信中搜索“博文视点”或者扫描下方二维码并关注。