Spark +深度学习:如何使用SparkNet进行分布式深度神经网络训练

原文链接:http://www.dataguru.cn/article-11647-1.html

摘要:

现如今,深度学习是机器学习中最热门的一种方法,与此同时,它还在继续取得显著成果。深度神经网络在不断地被证实是一门既有用又具有创新性的学科技术。该技术已经证明了其在之前停滞不前的研究领域中取得重大进展的 …

分析

现如今,深度学习是机器学习中最热门的一种方法,与此同时,它还在继续取得显著成果。

深度神经网络在不断地被证实是一门既有用又具有创新性的学科技术。该技术已经证明了其在之前停滞不前的研究领域中取得重大进展的能力,并迫使一些任不得不去反问,它是否可能是机器学习的顶点。虽然不是魔术(但也可能是从魔鬼那获得的),但深度学习确实是一个复杂的学习领域,并且有时甚至会让最博学的人感到惊讶。

深度神经网络也可以花费宝贵的时间和资源来进行训练。以前的尝试是为了促进集群训练环境中的参数协调,而诸如Theano这样的主要框架旨在让它们的软件包在短期内充分利用分布式GPU集群。但是,如何利用现有的批处理分布式框架来训练这些网络呢?

诸如Hadoop或Spark这样的分布式数据处理框架,在过去十年中得到了广泛应用并获得成功。而最初的MapReduce范式及其派生的处理算法,衍生技术和支持工具已经成为现代数据科学和分析的主要内容,并且没有显示出控制的迹象。而在开放环境下,Apache Spark实现的普遍存在性可以为深度神经网络的大规模训练提供理想的工具,当然,前提是如果这样的框架确实能够被利用的话。

AMP实验室,而这就是我们介绍SparkNet的地方,加州大学伯克利分校AMP实验室的开发人员简单介绍了 “可扩展的分布式深度网络训练算法”是如何实现的。他们还指出它所具有的可能的卖点:它适用于诸如Spark这样的框架,并且可以在有限的带宽环境中进行有效的工作。而SparkNet是建立在Spark和Caffe之上的。

SparkNet概述
SparkNet最初是由Moritz,Nishihara,Stoica和Jordan(2015)在本文中引入的。它是一个是开源软件。除了可扩展的分布式深度神经网络训练算法的核心概念,SparkNet还包括一个接口,用于读取Spark的数据抽象——称为弹性分布式数据集(RDD),这是一个与Caffe深度学习框架进行交互的Scala接口(它是用C ++编写的)和一个轻量级张量库。
Spark +深度学习:如何使用SparkNet进行分布式深度神经网络训练
也许最重要的是,开发人员声称,通过将深度学习整合到现有的数据处理流程中,可以实现许多其他好处。诸如Spark之类的框架将允许通过单个系统进行清理,预处理和其他与数据有关的任务,并且数据集可以保存在整个处理过程中的内存中,从而消除昂贵的磁盘写入。

SparkNet的硬件要求是很低的。除此之外,SparkNet的并行随机梯度(SGD)算法要求节点间的通信达到最小。开发人员还强调,他们的目标不是要简单优于现有的计算框架,而是提供一个完全不同的范例,而这恰好是在一个受欢迎的的批处理框架(如Apache Spark)上实现的,而且其性能几乎和专业化深入学习框架类似,并且具有上述所提及之外的额外好处。

梯度下降并行化方案可以看到Spark工作节点之间的数据分割,并且在每一次迭代时,主节点向所有工作人员广播模型参数。每个工作人员在其数据子集上运行预定数量的SGD迭代,直到较大时间长度。而所得到的参数会被发送到主节点上,在那里它们将被平均转换为新的模型参数。

显然,这种方法可能需要在SGD发生之前进行重要的广播和收集参数,因此对架构进行调整是很有必要的。 SparkNet的作者在其论文中提出了这样的调整建议,并提供了实验结果。

虽然该文章仅侧重于梯度下降,但作者声称SparkNet可以与任何Caffe解算器一起工作。
Spark +深度学习:如何使用SparkNet进行分布式深度神经网络训练
Caffe是用C ++编写的,因此 wrapper 用于它与SparkNet之间的交互。而Java API是用来调用此C wrapper的。 虽然可以直接调用Java API,但建议你通过使用Scala CaffeNet类来使用它从而促进Spark操作(Spark本身是用Scala编写的)。 Caffe通过自定义JavaDataLayer从Spark RDD中读取数据。

使用SparkNet
为了能够正确实现SparkNet,你首先需要一个Spark集群。然后,SparkNet作业将通过spark-submit进行提交。

而你如果想要根据报告自行构建软件的话,你需要Scala构建工具(SBT)和CUDA版本7,以及上述提到的现有的Apache Spark群集。你将在SparkNet构建期间免费获得Caffe。点击(这里和这里)你将获得位于GitHub中的构建SparkNet的简单直接的说明。

模型是在Caffe NetParameter对象中进行定义的,而求解器是在Caffe SolverParameter对象中定义的。通过SparkNet的Scala接口,描述特定深度神经网络规范的NetParameter对象可以定义为如下代码(来自SparkNet repo):

val netParam = NetParam (“LeNet”,
RDDLayer(“data”, shape=List(batchsize, 1, 28, 28), None),
RDDLayer(“label”, shape=List(batchsize, 1), None),
ConvolutionLayer(“conv1”, List(“data”), kernel=(5,5),
numOutput=20),
PoolingLayer(“pool1”, List(“conv1”), pooling=Pooling.Max,
kernel=(2,2), stride=(2,2)),
ConvolutionLayer(“conv2”, List(“pool1”), kernel=(5,5),
numOutput=50),
PoolingLayer(“pool2”, List(“conv2”), pooling=Pooling.Max,
kernel=(2,2), stride=(2,2)),
InnerProductLayer(“ip1”, List(“pool2”), numOutput=500),
ReLULayer(“relu1”, List(“ip1”)),
InnerProductLayer(“ip2”, List(“relu1”), numOutput=10),
SoftmaxWithLoss(“loss”, List(“ip2”, “label”))
)

有关这些图层及其定义的更多信息,请参见Caffe Layer Catalog。当然,对于那些在Caffe上经验丰富的或者对神经网络极其了解的人来说,上述内容是很容易进行理解的。

以下是分布式训练示例的示例Scala代码(来自SparkNet论文):

var trainData = loadData(. . .)
var trainData = preprocess(trainData).cache()
var nets = trainData.foreachPartition(data => {
var net = Net(netParams)
net.setTrainingData(data)
net)
var weights = initialWeights(. . .)
for (i <- 1 to 1000) {
var broadcastWeights = broadcast(weights)
nets.map(net => net.setWeights(broadcastWeights.value))
weights = nets.map(net => {
net.train(50)
// an average of WeightCollection objects
net.getWeights()}).mean()
}

和任何优秀的深度学习项目一样,SparkNet包含了在CIFAR应用程序形式上类似于“Hello World”的实际机器学习设备。而让它运行是很简单的。首先你要得到CIFAR数据:

$ SPARKNET_HOME/caffe/data/cifar10/get_cifar10.sh

然后提交作业 spark-submit:

$ SPARK_HOME/bin/spark-submit --class apps.CifarApp
SparkNetPreview/target/scala-2.10/sparknetpreview-assembly-0.1-SNAPSHOT.jar 5

讨论

作为目前正在进行的一种小型但数量越来越多的集群深度学习方案之一,如果你决定用SparkNet来训练你的神经网络,那么你可能会很容易上手并掌握良好的手段,因为它是由负责其主要组成部分的实验室开发的( Spark和Caffe)。

如果你决定尝试一下,那么你应该记得SparkNet并没有和Spark(或任何其他分布式批处理系统)或Caffe(或任何其他深度学习框架)竞争;它的目标是提供一个替代范例,将神经网络的训练装配成更大的数据处理流程。如果这只是一个你想小试牛刀的示例,SparkNet是值得一试的。

应该指出的是,SparkNet不是Spark上深度网络训练的现有工具。HeteroSpark在今年3月的Spark Summit 2015上展示的是“用于深度学习算法的异构CPU / GPU Spark平台”。演示的幻灯片可以在这里,而点击视频可以进行查看。

就像越有名气,才越具有吸引力一样,一种称为 H2O’s Sparkling Water 在Spark-slash-deep-learning空间里活跃着。这个自称为 “杀手级应用程序”的Sparkling Water允许在Spark群集中进行可扩展的机器学习,包括深度学习。在“KDnuggets”文章中可以找到使用Sparkling Water打击犯罪的记录。Sparkling Water可以在H2O的GitHub页面上找到。

上一篇:Win10 Caffe 从零配置,支持Python接口


下一篇:caffe源码解析收藏博客