在过去几年中,深度学习已经为各种应用程序获得了巨大的动力和普遍性 。其中包括图像和语音识别,无人驾驶汽车,自然语言处理等等。有趣的是,数十年来,大多数深度学习的数学概念都已为人所知。然而,只有通过最近的几项发展才能释放深度学习的全部潜力 。
以前,由于消失的梯度和过度拟合问题,很难训练人工神经网络。现在通过使用不同的激活函数, 正则化和大量训练数据来解决这两个问题。
今天,深度学习已经证明对几乎任何需要机器学习的任务都非常有效。但是,它特别适用于复杂的分层数据。其基础人工神经网络模拟高度非线性表示; 这些通常由多层以及非线性变换和定制架构组成。深度神经网络的典型表示如图1所示。
深度学习的成功为各种编程语言提供了广泛的框架和库。例子包括Caffee,Theano,Torch和Tensor Flow等。此博客文章旨在提供可用于编程语言R的不同深度学习包的概述和比较。我们比较不同数据集的性能和易用性。
R中的深度学习包
R编程语言因其易用性以及复杂的可视化和分析而在统计学家和数据挖掘者中获得了相当大的普及。随着深度学习时代的到来,R的深度学习支持从此开始增长,随着越来越多的软件包可用。本节概述了R中的深度学习,包括以下软件包:MXNetR,darch,deepnet,H2O和deepr。
首先,我们注意到底层学习算法因包而异。因此,表1显示了每个包中可用方法/体系结构的列表。
表1. R包中可用的深度学习方法列表。
包 | 可用的神经网络架构 |
---|---|
MXNetR | 前馈神经网络,卷积神经网络(CNN) |
darch | 受限制的玻尔兹曼机器,深信仰网络 |
DEEPNET | 前馈神经网络,限制Boltzmann机器,深信念网络,堆叠自动编码器 |
H2O | 前馈神经网络,深度自动编码器 |
deepr | 简化H2O和deepnet包中的一些功能 |
包“MXNetR”
MXNetR包是用C ++编写的MXNet库的接口。它包含前馈神经网络和卷积神经网络(CNN)(MXNetR 2016a)。它还允许人们构建自定义模型。该软件包分为两个版本:仅CPU或GPU版本。以前的CPU版本可以直接从R内部安装,而后者的GPU版本依赖于第三方库,如cuDNN,需要从源代码构建库(MXNetR 2016b)。
可以使用函数调用在MXNetR中构建前馈神经网络(多层感知器):
参数如下:
data
- 输入矩阵label
- 训练标签hidden_node
- 包含每个隐藏层中隐藏节点数的向量dropout
- [0,1]中的数字,包含从最后一个隐藏层到输出层的丢失率activation
- 单个字符串或包含激活函数名称的向量。有效值是{'relu'
,'sigmoid'
,'softrelu'
,'tanh'
}out_activation
- 包含输出激活函数名称的单个字符串。有效值是{'rmse'
,'sofrmax'
,'logistic'
}device
- 是否训练mx.cpu
(默认)或mx.gpu
...
- 其他参数传递给mx.model.FeedForward.create
函数mx.model.FeedForward.create
在内部使用mx.mpl
并采用以下参数:
symbol
- 神经网络的符号配置y
- 标签数组x
- 训练数据ctx
- 上下文,即设备(CPU / GPU)或设备列表(多个CPU或GPU)num.round
- 训练模型的迭代次数optimizer
- 字符串(默认为'sgd'
)initializer
- 参数的初始化方案eval.data
- 过程中使用的验证集eval.metric
- 对结果的评估功能epoch.end.callback
- 迭代结束时的回调batch.end.callback
- 当一个小批量迭代结束时回调array.batch.size
- 用于阵列训练的批量大小array.layout
-可以是{'auto'
,'colmajor'
,'rowmajor'
}kvstore
- 多个设备的同步方案
示例:
要在之后使用训练模型,我们只需要调用predict()
指定model
第一个参数和testset
第二个参数的函数:
该函数mx.mlp()
本质上是通过使用MXNetR的“符号”系统来定义神经网络的更灵活但更长的过程的代理。在符号定义中等效的先前网络将是:
最终创建网络体系结构时,MXNetR提供了一种使用以下函数调用以图形方式检查它的简单方法:
这里,参数是由符号表示的训练模型。第一个网络由mx.mlp()
第二个网络构成,第二个网络使用符号系统构建。
该定义从输入到输出逐层进行,同时还允许每个层分别使用不同数量的神经元和特定激活函数。其他选项可通过mx.symbol
以下方式获得:mx.symbol.Convolution
将卷积应用于输入,然后添加偏差。它可以创建卷积神经网络。相反mx.symbol.Deconvolution
,它通常与分割网络一起使用mx.symbol.UpSampling
,以便重建图像的逐像素分类。CNN中使用的另一种类型的层是mx.symbol.Pooling
; 这通过选择具有最高响应的信号来实质上减少数据。mx.symbol.Flatten
需要该层将卷积层和池化层链接到完全连接的网络。另外,mx.symbol.Dropout
可以用来应对过度拟合问题。它作为参数previous_layer
和fraction
被删除的输入的浮点值。
正如我们所看到的,MXNetR可用于快速设计具有该功能的标准多层感知器,mx.mlp()
或用于关于符号表示的更广泛的实验。
LeNet网络示例:
总而言之,MXNetR软件包非常灵活,同时支持多个CPU和多个GPU。它具有构建标准前馈网络的捷径,但也提供灵活的功能来构建更复杂的定制网络,如CNN LeNet。
包“darch”
darch包(darch 2015)实现了深层架构的训练,例如深层信念网络,它由分层预训练的受限玻尔兹曼机器组成。该软件包还需要反向传播以进行微调,并且在最新版本中,使预训练可选。
深度信仰网络的训练是通过darch()
功能进行的。
示例:
此函数采用几个参数,其中最重要的参数如下:
x
- 输入数据y
- 目标数据layers
- 包含一个整数的向量,用于每层中的神经元数量(包括输入和输出层)rbm.batchSize
- 预训练批量大小rbm.trainOutputLayer
- 预训练中使用的布尔值。如果为true,则也训练RBM的输出层rbm.numCD
- 执行对比分歧的完整步骤数rbm.numEpochs
- 预训练的时期数darch.batchSize
- 微调批量大小darch.fineTuneFunction
- 微调功能darch.dropoutInput
- 网络输入的丢失率darch.dropoutHidden
- 隐藏图层的辍学率darch.layerFunctionDefault
-为DBN默认激活功能,可用的选项包括{'sigmoidUnitDerivative'
,'binSigmoidUnit'
,'linearUnitDerivative'
,'linearUnit'
,'maxoutUnitDerivative'
,'sigmoidUnit'
,'softmaxUnitDerivative'
,'softmaxUnit'
,'tanSigmoidUnitDerivative'
,'tanSigmoidUnit'
}darch.stopErr
- 如果误差小于或等于阈值,则停止训练darch.numEpochs
- 用于微调的时期数darch.retainData
- boolean,表示在训练后将训练数据存储在darch实例中的天气
基于之前的参数,我们可以训练我们的模型得到一个对象darch
。我们稍后可以将其应用于测试数据集test.x
以进行预测。在这种情况下,附加参数type
指定预测的输出类型。例如,它可以为二进制向量和类标签‘raw’
提供概率。最后,在调用时进行如下预测:‘bin’
‘class’
predict()
总的来说,darch的基本用法非常简单。它只需要一个功能来训练网络。但另一方面,该方案仅限于深层信仰网络,这通常需要更广泛的训练。
包“deepnet”
deepnet (deepnet 2015)是一个相对较小但功能强大的软件包,具有多种架构可供选择。它可以使用函数训练前馈网络nn.train()
或初始化深度置信网络的权重dbn.dnn.train()
。此功能在内部用于rbm.train()
训练受限制的Boltzmann机器(也可单独使用)。此外,deepnet还可以处理堆叠的自动编码器sae.dnn.train()
。
示例(for nn.train()
):
可以设置随机生成的初始权重initW
和权重initB
。另外,hidden
控制的在隐藏层单元的数量,而activationfun
指定的隐藏层的激活功能(可以是‘sigm’
,‘linear’
或‘tanh’
),以及输出层的(可以是‘sigm’
,‘linear’
,‘softmax’
)。
作为替代方案,以下示例训练神经网络,其中权重由深信念网络(via dbn.dnn.train()
)初始化。差异主要在于训练受限制的Boltzmann机器的对比散度算法。它通过设置cd
,给出学习算法内的Gibbs采样的迭代次数。
类似地,可以从堆叠的自动编码器初始化权重。output
此示例使用的不是参数,而是sae_output
与以前相同。
最后,我们可以使用训练有素的网络来预测结果nn.predict()
。随后,我们可以在nn.test()
错误率的帮助下将预测转换为。第一次调用需要神经网络和相应的观察作为输入。第二个调用在进行预测时还需要正确的标签和阈值(默认值为0.5)。
总而言之,deepnet代表了一个带有一组有限参数的轻量级包; 但是,它提供了各种架构。
包“H2O”
H2O是一个开源软件平台,能够利用分布式计算机系统(H2O 2015)。它的核心是用Java编写的,需要最新版本的JVM和JDK,可以在https://www.java.com/en/download/找到。该软件包提供多种语言的接口,最初设计用作基于云的平台(Candel等人2015)。因此,通过调用h2o.init()
以下方式启动H2O :
该参数nthreads
指定将用于计算的核心数。值-1表示H2O将尝试使用系统上的所有可用内核,但默认值为2.此例程也可以使用参数ip
,port
以防H2O安装在其他计算机上。默认情况下,它使用IP地址127.0.0.1和端口54321.因此,可以在浏览器中找到地址“localhost:54321”以访问基于Web的界面。完成当前H2O实例的工作后,您需要通过以下方式断开连接:
示例:
所有训练操作均按以下方式执行h2o.deeplearning()
:
在H2O中传递数据的接口与其他包稍有不同:x
是包含具有训练数据的列的名称的向量,并且y
是具有所有名称的变量的名称。接下来的两个参数是training_frame
和validation_frame
H2O框架对象。它们可以通过调用创建h2o.uploadFile()
,它将目录路径作为参数并将csv文件加载到环境中。特定数据类的使用受分布式环境的驱动,因为数据应该在整个集群中可用。所述参数distribution
是一个字符串,并且可以采取的值‘bernoulli’
,‘multinomial’
,‘poisson’
,‘gamma’
,‘tweedie’
,‘laplace’
,‘huber’
或‘gaussian’
,而‘AUTO’
根据数据自动选择参数。以下参数指定activation
功能(可能的值是‘Tanh’
,‘TanhWithDropout’
,‘Rectifier’
,‘RectifierWithDropout’
,‘Maxout’
或‘MaxoutWithDropout’
)。该参数sparse
是一个表示高度零的布尔值,允许H2 =更有效地处理它。其余参数非常直观,与其他软件包没有太大差别。但是,有更多可用于微调,但可能没有必要更改它们,因为它们带有推荐的预定义值。
最后,我们可以使用h2o.predict()
以下签名进行预测:
H2O提供的另一个强大工具是网格搜索,用于优化超参数。可以为每个参数指定值集,然后通过找到最佳组合h2o.grid()
。
超参数优化
H2 =包将训练具有两种架构和不同L1正则化权重的四种不同模型。因此,可以轻松尝试多参数的多种组合,看看哪一种表现更好:
深度自动编码器
H2O还可以利用深度自动编码器。为了训练这样的模型,使用相同的函数h2o.deeplearning()
但是参数集略有不同
在这里,我们只使用训练数据,没有测试集和标签。我们需要深度自动编码器而不是前馈网络的事实由autoencoder
参数指定。和以前一样,我们可以选择不同层中应该有多少隐藏单位。如果我们使用一个整数值,我们将获得一个天真的自动编码器。
训练后,我们可以研究重建误差。我们通过特定的h2o.anomaly()
功能来计算它。
总的来说,H2O是一个高度用户友好的包,可用于训练前馈网络或深度自动编码器。它支持分布式计算并提供Web界面。
包“deeper”
深度包(deepr 2015)本身并没有实现任何深度学习算法,而是将其任务转发给H20。该包装最初是在CRAN尚未提供H2O包装时设计的。由于情况不再如此,我们将其排除在比较之外。我们还注意到它的功能train_rbm()
使用deepnet实现rbm
来训练具有一些额外输出的模型。
包的比较
本节比较不同指标的上述包。其中包括易用性,灵活性,易于安装,支持并行计算以及协助选择超参数。此外,我们测量三个常见数据集'Iris','MNIST'和'Forest Cover Type'的性能。我们希望我们的比较能够帮助从业者和研究人员选择他们喜欢的深度学习方案。
安装
安装通过CRAN提供的软件包通常非常简单和流畅。但是,某些软件包依赖于第三方库。例如,H2O需要最新版本的Java以及Java Development Kit。darch和MXNetR软件包允许使用GPU。为此,darch依赖于R package gputools,它仅在Linux和MacOS系统上受支持。默认情况下,MXNetR由于其对cuDNN的依赖而没有GPU支持,因为许可限制而无法将其包含在软件包中。因此,GPU版本的MXNetR需要Rtools和支持C ++ 11的现代编译器,以便使用CUDA SDK和cuDNN从源代码编译MXNet。
灵活性
在灵活性方面,MXNetR最有可能位居榜首。它允许人们尝试不同的体系结构,因为它采用分层方法定义网络,更不用说丰富多样的参数。我们认为,我们认为H2O和Darch都排在第二位。H20主要用于前馈网络和深度自动编码器,而darch主要关注受限制的Boltzmann机器和深度信任网络。两种封装都提供了广泛的调整参数。最后但并非最不重要的一点是,deepnet是一个相当轻量级的软件包,但是当想要使用不同的体系结构时,它可能是有益的。但是,我们不建议将其用于大型数据集的日常使用,因为其当前版本缺乏GPU支持,并且相对较小的参数集不允许进行最大程度的微调。
便于使用
H2O和MXNetR因其速度和易用性而脱颖而出。MXNetR几乎不需要准备数据来开始训练,而H2O通过使用as.h2o()
将数据转换为H2OFrame
对象的函数提供了非常直观的包装器。这两个包都提供了检查模型的其他工具。deepnet以单热编码矩阵的形式获取标签。这通常需要一些预处理,因为大多数数据集的类都是矢量格式。但是,它没有报告有关训练过程中进展的非常详细的信息。该软件包还缺少用于检查模型的其他工具。另一方面,darch具有非常好的和冗长的输出。
总的来说,我们将H2O或MXNetR视为此类别的获奖者,因为两者都很快并且在训练期间提供反馈。这允许人们快速调整参数并改善预测性能。
并行
在处理大量数据集时,深度学习很常见。因此,当包允许某种程度的并行化时,它可以提供巨大的帮助。表2比较了并行化的支持。它仅显示文档中明确声明的信息。
表2.并行化的比较。
包 | 多CPU | [多个] GPU | 簇 | 平台 |
---|---|---|---|---|
MXNetR | X | X | Linux的\ MacOS的\的Windows | |
darch | X | Linux的\ MAXOS | ||
H20 | X | X | Linux的\ MacOS的\的Windows | |
DEEPNET | 无信息 |
选择参数
另一个重要方面是超参数的选择。H2O软件包使用全自动的每神经元自适应学习速率来实现快速收敛。它还可以选择使用n次交叉验证,并提供h2o.grid()
网格搜索功能,以优化超参数和模型选择。
MXNetR在每次迭代后显示训练准确性。darch在每个纪元后显示错误。两者都允许在不等待收敛的情况下手动试验不同的超参数,因为在准确性没有提高的情况下可以提前终止训练阶段。相比之下,在训练完成之前,deepnet不会显示任何信息,这使得调整超参数非常具有挑战性。
性能和运行时
我们准备了一个非常简单的性能比较,以便为读者提供有关效率的信息。所有后续测量均在具有CPU Intel Core i7和GPU NVidia GeForce 750M,Windows OS的系统上进行。比较在三个数据集上进行:'MNIST' (LeCun等人2012),'Iris' (Fisher 1936)和'Forest Cover Type' (Blackard和Dean 1998)。详情见附录。
作为基线,我们使用H2O包中实现的随机森林算法。随机森林是一种集成学习方法,通过构建多个决策树来工作(维基百科2016b)。有趣的是,它已经证明了它能够在开箱即用的情况下实现高性能,而无需在很大程度上进行参数调整。
结果
测量结果显示在表3中,并且还分别在图2,3和4中针对'MNIST','Iris'和'Forest Cover Type'数据集可视化。
- 'MNIST'数据集。根据表3和图2,MXNetR和H2O在'MNIST'数据集上实现了运行时和预测性能之间的优越权衡。darch和deepnet需要相对较长的时间来训练网络,同时实现较低的准确性。
- 'Iris'数据集。在这里,我们再次看到MXNetR和H2O表现最佳。从图3中可以看出,deepnet具有最低的准确性,可能是因为它是一个如此微小的数据集,其中预训练具有误导性。因此,darch 100和darch 500/300通过反向传播进行训练,省略了训练前阶段。这由表中的*符号标记。
- 'Forest Cover Type'数据集。H2O和MXNetR显示出约67%的准确度,但这仍然比其余的包更好。我们注意到darch 100和darch 500/300的训练没有收敛,因此模型已被排除在此比较之外。
我们希望即使这种简单的性能比较也可以为从业者在选择他们喜欢的R包时提供有价值的见解。
注意:从图3和图4可以看出,随机森林可以比深度学习软件包表现更好。这有几个正当理由。首先,数据集太小,因为深度学习通常需要大数据或使用数据增强才能正常运行。其次,这些数据集中的数据由手工制作的特征组成,这些特征否定了深层体系结构从原始数据中学习这些特征的优势,因此传统方法可能就足够了。最后,我们选择非常相似(可能不是最有效)的架构来比较不同的实现。
表3. R中不同深度学习包的准确性和运行时间的比较。
*仅使用反向传播训练的模型(无预训练)。
型号/数据集 | MNIST | 鸢尾花 | 森林覆盖类型 | |||
---|---|---|---|---|---|---|
准确性 (%) | 运行时间(秒) | 准确性 (%) | 运行时间(秒) | 准确性 (%) | 运行时间(秒) | |
MXNetR(CPU) | 98.33 | 147.78 | 83.04 | 1.46 | 66.80 | 30.24 |
MXNetR(GPU) | 98.27 | 336.94 | 84.77 | 3.09 | 67.75 | 80.89 |
darch 100 | 92.09 | 1368.31 | 69.12 * | 1.71 | - | - |
darch 500/300 | 95.88 | 4706.23 | 54.78 * | 2.10 | - | - |
deepnet DBN | 97.85 | 6775.40 | 30.43 | 0.89 | 14.06 | 67.97 |
DNN | 97.05 | 2183.92 | 78.26 | 0.42 | 26.01 | 25.67 |
H2O | 98.08 | 543.14 | 89.56 | 0.53 | 67.36 | 5.78 |
随机森林 | 96.77 | 125.28 | 91.30 | 2.89 | 86.25 | 9.41 |
图2.“MNIST”数据集的运行时和精度的比较。
图3.“Iris”数据集的运行时和准确性的比较。
图4.“Forest Cover Type”数据集的运行时和准确性比较。
结论
作为本文的一部分,我们比较了R中的五个不同的包,以便深入学习:(1)当前版本的deepnet可能代表了可用架构方面最具差异性的包。但是,由于它的实现,它可能不是最快或最用户友好的选项。此外,它可能不会提供与其他一些软件包一样多的调整参数。(2)相反,H2O和MXNetR提供了高度用户友好的体验。两者都提供额外信息的输出,快速执行训练并获得不错的结果。H2O可能更适合集群环境,数据科学家可以将其用于简单管道中的数据挖掘和探索。当灵活性和原型设计更受关注时,MXNetR可能是最合适的选择。它提供了一个直观的符号工具,用于从头开始构建自定义网络架构。此外,它还通过利用多CPU / GPU功能在个人计算机上进行了优化。(3)darch提供有限但有针对性的功能,专注于深层信念网络。
总而言之,我们看到R对深度学习的支持正在顺利进行。最初,R提供的功能落后于其他编程语言。但是,情况已不再如此。使用H20和MXnetR,R用户可以轻松使用两个强大的工具。将来,我们希望看到更多的接口 - 例如Caffe或Torch。