AI

DL4J中文文档/分布式深度学习/介绍与入门

2018-11-26  本文已影响204人  hello风一样的男子

DL4J与Spark分布式深度学习

DL4J支持使用Apache Spark在CPU或GPU机器集群上进行神经网络训练。DL4J还支持分布式评估以及使用Spark的分布式推理。

DL4J的分布式训练实现

DL4J有两种分布式训练实现。

用户被引导到取代参数平均实现的梯度共享实现。梯度共享实现导致更快的训练时间,并且实现为可伸缩和容错(从1.0.0-beta3开始)。为了完整起见,本页还将介绍参数平均方法。技术参考部分涵盖了实现的细节。
除了分布式训练之外,DL4J还允许用户进行分布式评估(包括同时进行多次评估)和分布式推理。请参阅Spark上的DL4J:操作指南 获取更多细节。

何时使用Spark训练神经网络

Spark并不总是训练神经网络最合适的工具。
你应该使用Spark训练的场景如下:

  1. 你有一组用于训练的机器集群(不仅仅是一台机器——这包括多GPU机器)
  2. 你需要多台机器来训练网络
  3. 你的网络大到足以证明有理由用分布式实现。

对于具有多个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进行分布式训练时应该熟悉的关键类。

训练工作流程通常如下:

  1. 准备带有几个组件的训练代码:a.神经网络配置b.数据管道c.SparkDl4jMultiLayer/SparkComputationGraph加上Trainingmaster
  2. 创建 uber-JAR 文件(请参阅Spark上的DL4J:如何指导 获取更多细节)
  3. 确定Spark提交的参数(内存、节点数量等)
  4. 带着必要参数提交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

进一步阅读

翻译:风一样的男子

image

如果您觉得我的文章给了您帮助,请为我买一杯饮料吧!以下是我的支付宝,意思一下我将非常感激!

image
上一篇下一篇

猜你喜欢

热点阅读