DL4J中文文档/分布式深度学习/介绍与入门
DL4J与Spark分布式深度学习
DL4J支持使用Apache Spark在CPU或GPU机器集群上进行神经网络训练。DL4J还支持分布式评估以及使用Spark的分布式推理。
DL4J的分布式训练实现
DL4J有两种分布式训练实现。
- 梯度共享,1.0.0-beta版本可用:基于Nikko Strom的论文,是一种异步SGD实现,在Spark+Aeron中实现量化和压缩更新
- 参数平均:一个同步SGD实现,带有一个完全用Spark实现的参数服务器。
用户被引导到取代参数平均实现的梯度共享实现。梯度共享实现导致更快的训练时间,并且实现为可伸缩和容错(从1.0.0-beta3开始)。为了完整起见,本页还将介绍参数平均方法。技术参考部分涵盖了实现的细节。
除了分布式训练之外,DL4J还允许用户进行分布式评估(包括同时进行多次评估)和分布式推理。请参阅Spark上的DL4J:操作指南 获取更多细节。
何时使用Spark训练神经网络
Spark并不总是训练神经网络最合适的工具。
你应该使用Spark训练的场景如下:
- 你有一组用于训练的机器集群(不仅仅是一台机器——这包括多GPU机器)
- 你需要多台机器来训练网络
- 你的网络大到足以证明有理由用分布式实现。
对于具有多个GPU或多个物理处理器的单台机器,用户应考虑使用DL4J的ParallelWrapper实现,如本示例所示。ParallelWrapper允许在具有多个核的单台机器上轻松进行网络的数据并行训练。与ParallelWrapper相比,Spark用于单机训练的开销更高。
类似地,如果你不需要Spark(更小的网络和/或数据集)-建议使用单机训练,这通常更容易设置。
对于一个足够大的网络:这里有一个粗略的指南。如果网络需要100ms或更长时间来执行一次迭代(每个小批次的拟合操作为100ms),则分布式训练应该工作良好,具有良好的可扩展性。在每次迭代为10ms时,我们可能期望性能与节点数量的次线性缩放。在每次迭代大约1ms或更低时,通信开销可能太大:集群上的训练可能不会比单台机器上的训练更快(或者甚至更慢)。为了并行性优于通信开销,用户应该考虑网络传输时间与计算时间的比率,并确保计算时间足够大,以掩盖分布式训练的额外开销。
设置与依赖
为了在GPU上运行训练,请确保你在pom文件中指定了正确的后端(GPU的nd4j-cuda-x.x相对于CPU的nd4j-native 后端),并且已经用适当的CUDA库设置了机器。请参阅Spark上的DL4J:如何指导 获取更多细节。
使用梯度共享实现包括以下依赖性:
<dependency>
<groupId>org.deeplearning4j</groupId>
<artifactId>dl4j-spark-parameterserver_${scala.binary.version}</artifactId>
<version>${dl4j.spark.version}</version>
</dependency>
image.gif
如果使用参数平均实现(同样,梯度共享实现应该是优选的),则包括:
<dependency>
<groupId>org.deeplearning4j</groupId>
<artifactId>dl4j-spark_${scala.binary.version}</artifactId>
<version>${dl4j.spark.version}</version>
</dependency>
image.gif
注意,${scala.binary.version}是一个Maven属性,值为2.10或2.11,应该与你正在使用的Spark版本匹配。
关键概念
以下是用户开始使用DL4J进行分布式训练时应该熟悉的关键类。
- TrainingMaster: 指定如何在实践中进行分布式训练。实现包括梯度共享(SharedTrainingMaster)或参数平均(ParameterAveragingTrainingMaster)
- SparkDl4jMultiLayer 与 SparkComputationGraph: 它们是DL4J中的MultiLayerNetwork和ComutationGraph类的包装器,支持与分布式训练相关的功能。为了训练,他们配置了一个TrainingMaster。
-
RDD<DataSet>
与RDD<MultiDataSet>
: 具有DL4J的DataSet或MultiDataSet类的Spark RDD定义训练数据(或评估数据)的源。注意,推荐的最佳实践是只对数据进行一次预处理,并将其保存到诸如HDFS之类的网络存储中。有关更多细节,请参考Spark上的DL4J:如何构建数据管道。
训练工作流程通常如下:
- 准备带有几个组件的训练代码:a.神经网络配置b.数据管道c.SparkDl4jMultiLayer/SparkComputationGraph加上Trainingmaster
- 创建 uber-JAR 文件(请参阅Spark上的DL4J:如何指导 获取更多细节)
- 确定Spark提交的参数(内存、节点数量等)
- 带着必要参数提交uber-JAR 到 Spark
极小的示例
下面的代码片段概述了所需的一般设置。API参考概述了各个类的详细用法。用户可以向Spark Submit提交一个uber jar,以便使用正确的选项执行。请参阅Spark DL4J:如何指导 获取更多细节。
梯度共享(首选实现)
JavaSparkContext sc = ...;
JavaRDD<DataSet> trainingData = ...;
//单节点上的模型设置。一个 MultiLayerConfiguration 或一个 ComputationGraphConfiguration
MultiLayerConfiguration model = ...;
//配置梯度共享实现所需的分布式训练
VoidConfiguration conf = VoidConfiguration.builder()
.unicastPort(40123) //工作机将使用于通信的端口。使用任意空闲的端口
.networkMask(“10.0.0.0/16”) //用于通信的网络掩码。示例100.0.0/24,或192.1680.0/16等
.controllerAddress("10.0.2.4") //主/驱动器IP
.build();
//创建TrainingMaster实例
TrainingMaster trainingMaster = new SharedTrainingMaster.Builder(conf)
.batchSizePerWorker(batchSizePerWorker) //训练批量大小
.updatesThreshold(1e-3) //更新量化/压缩阈值。见技术说明页
.workersPerNode(numWorkersPerNode) // numWorkersPerNode等于GPU的数量。对于CPU:numWorkersPerNode为1;CPU大核心numWorkersPerNode大于1
.meshBuildMode(MeshBuildMode.MESH) // 对于32个节点使用 MeshBuildMode.PLAIN
.build();
//创建SparkDl4jMultiLayer实例
SparkDl4jMultiLayer sparkNet = new SparkDl4jMultiLayer(sc, model, trainingMaster);
//执行训练:
for (int i = 0; i < numEpochs; i++) {
sparkNet.fit(trainingData);
}
image.gif
参数平均实现
JavaSparkContext sc = ...;
JavaRDD<DataSet> trainingData = ...;
//单节点上的模型设置。一个 MultiLayerConfiguration 或一个 ComputationGraphConfiguration
MultiLayerConfiguration model = ...;
//创建TrainingMaster 实例
int examplesPerDataSetObject = 1;
TrainingMaster trainingMaster = new ParameterAveragingTrainingMaster.Builder(examplesPerDataSetObject)
.(other configuration options)
.build();
//创建SparkDl4jMultiLayer实例并使用训练数据拟合网络
SparkDl4jMultiLayer sparkNetwork = new SparkDl4jMultiLayer(sc, model, trainingMaster);
//执行训练:
for (int i = 0; i < numEpochs; i++) {
sparkNet.fit(trainingData);
}
image.gif
进一步阅读
- Spark上的DL4J: 技术说明
- Spark上的DL4J: 操作指南
- Spark上的DL4J: 如何构建数据管道
- Spark上的DL4J: API 参考
- DL4J示例代码仓库包含一些可供用户使用作为参考的Spark示例。
翻译:风一样的男子
image如果您觉得我的文章给了您帮助,请为我买一杯饮料吧!以下是我的支付宝,意思一下我将非常感激!
image