英文 中文 登录

MXNet

    今日:48| 主题:40
收藏本版
发表新帖

(1)结合R与GPU加速深度学习

[复制链接]
Summer 发表于 2017-6-1 17:16:12
117 0
近年来,深度学习可谓是机器学习方向的明星概念,不同的模型分别在图像处理与自然语言处理等任务中取得了前所未有的好成绩。在实际的应用中,大家除了关心模型的准确度,还常常希望能比较快速地完成模型的训练。一个常用的加速手段便是将模型放在GPU上进行训练。然而由于种种原因,R语言似乎缺少一个能够在GPU上训练深度学习模型的程序包。


DMLC(Distributed (Deep) Machine Learning Community)是由一群极客发起的组织,主要目标是提供快速高质量的开源机器学习工具。近来流行的boosting模型xgboost便是出自这个组织。最近DMLC开源了一个深度学习工具mxnet,这个工具含有R,python,julia等语言的接口。本文以R接口为主,向大家介绍这个工具的性能与使用方法。

一、五分钟入门指南

在这一节里,我们在一个样例数据上介绍mxnet的基本使用方法。目前mxnet还没有登录CRAN的计划,所以安装方法要稍微复杂一些。

  • 如果你是Windows/Mac用户,那么可以通过下面的代码安装预编译的版本。这个版本会每周进行预编译,不过为了保证兼容性,只能使用CPU训练模型。
  1. install.packages("drat", repos="https://cran.rstudio.com")
  2. drat:::addRepo("dmlc")
  3. install.packages("mxnet")
复制代码
  • 如果你是Linux用户或者想尝试GPU版本,请参考这个链接里的详细编译教程在本地进行编译。

安装完毕之后,我们就可以开始训练模型了,下面两个小节分别介绍两种不同的训练神经网络的方法。

二分类模型与mx.mlp

首先,我们准备一份数据,并进行简单的预处理:
  1. require(mlbench)
  2. require(mxnet)
  3. data(Sonar, package="mlbench")
  4. Sonar[,61] = as.numeric(Sonar[,61])-1
  5. train.ind = c(1:50, 100:150)
  6. train.x = data.matrix(Sonar[train.ind, 1:60])
  7. train.y = Sonar[train.ind, 61]
  8. test.x = data.matrix(Sonar[-train.ind, 1:60])
  9. test.y = Sonar[-train.ind, 61]
复制代码
我们借用mlbench包中的一个二分类数据,并且将它分成训练集和测试集。mxnet提供了一个训练多层神经网络的函数mx.mlp,我们额可以通过它来训练一个神经网络模型。下面是mx.mlp中的部分参数:

  • 训练数据与预测变量
  • 每个隐藏层的大小
  • 输出层的结点数
  • 激活函数类型
  • 损失函数类型
  • 进行训练的硬件(CPU还是GPU)
  • 其他传给mx.model.FeedForward.create的高级参数

了解了大致参数后,我们就可以理解并让R运行下面的代码进行训练了。
  1. mx.set.seed(0)
  2. model <- mx.mlp(train.x, train.y, hidden_node=10, out_node=2,      out_activation="softmax", num.round=20, array.batch.size=15, learning.rate=0.07, momentum=0.9, eval.metric=mx.metric.accuracy)
复制代码
  1. ## Auto detect layout of input matrix, use rowmajor..
  2. ## Start training with 1 devices
  3. ## [1] Train-accuracy=0.488888888888889
  4. ## [2] Train-accuracy=0.514285714285714
  5. ## [3] Train-accuracy=0.514285714285714

  6. ...

  7. ## [18] Train-accuracy=0.838095238095238
  8. ## [19] Train-accuracy=0.838095238095238
  9. ## [20] Train-accuracy=0.838095238095238
复制代码
这里要注意使用mx.set.seed而不是R自带的set.seed函数来控制随机数。因为mxnet的训练过程可能会运行在不同的运算硬件上,我们需要一个足够快的随机数生成器来管理整个随机数生成的过程。模型训练好之后,我们可以很简单地进行预测:
  1. preds = predict(model, test.x)
复制代码
  1. ## Auto detect layout of input matrix, use rowmajor..
复制代码
  1. pred.label = max.col(t(preds))-1
  2. table(pred.label, test.y)
复制代码
  1. ##           test.y
  2. ## pred.label  0  1
  3. ##          0 24 14
  4. ##          1 36 33
复制代码
如果进行的是多分类预测,mxnet的输出格式是类数X样本数。

回归模型与自定义神经网络

mx.mlp接口固然很方便,但是神经网络的一大特点便是它的灵活性,不同的结构可能有着完全不同的特性。mxnet的亮点之一便是它赋予了用户极大的自由度,从而可以任意定义需要的神经网络结构。我们在这一节用一个简单的回归任务介绍相关的语法。

首先,我们仍然要准备好一份数据。
  1. data(BostonHousing, package="mlbench")

  2. train.ind = seq(1, 506, 3)
  3. train.x = data.matrix(BostonHousing[train.ind, -14])
  4. train.y = BostonHousing[train.ind, 14]
  5. test.x = data.matrix(BostonHousing[-train.ind, -14])
  6. test.y = BostonHousing[-train.ind, 14]
复制代码
mxnet提供了一个叫做“Symbol”的系统,从而使我们可以定义结点之间的连接方式与激活函数等参数。下面是一个定义没有隐藏层神经网络的简单例子:
  1. # 定义输入数据
  2. data <- mx.symbol.Variable("data")
  3. # 完整连接的隐藏层
  4. # data: 输入源
  5. # num_hidden: 该层的节点数
  6. fc1 <- mx.symbol.FullyConnected(data, num_hidden=1)

  7. # 针对回归任务,定义损失函数
  8. lro <- mx.symbol.LinearRegressionOutput(fc1)
复制代码
在神经网络中,回归与分类的差别主要在于输出层的损失函数。这里我们使用了平方误差来训练模型。希望能更进一步了解Symbol的读者可以继续阅读这份以代码为主的文档。

定义了神经网络之后,我们便可以使用mx.model.FeedForward.create进行训练了。
  1. mx.set.seed(0)
  2. model <- mx.model.FeedForward.create(lro, X=train.x, y=train.y, ctx=mx.cpu(), num.round=50, array.batch.size=20, learning.rate=2e-6, momentum=0.9, eval.metric=mx.metric.rmse)
复制代码
  1. ## Auto detect layout of input matrix, use rowmajor..
  2. ## Start training with 1 devices
  3. ## [1] Train-rmse=16.063282524034
  4. ## [2] Train-rmse=12.2792375712573
  5. ## [3] Train-rmse=11.1984634005885

  6. ...

  7. ## [48] Train-rmse=8.26890902770415
  8. ## [49] Train-rmse=8.25728089053853
  9. ## [50] Train-rmse=8.24580511500735
复制代码
这里我们还针对回归任务修改了eval.metric参数。目前我们提供的评价函数包括”accuracy”,”rmse”,”mae” 和 “rmsle”,用户也可以针对需要自定义评价函数,例如:
  1. demo.metric.mae <- mx.metric.custom("mae", function(label, pred) {
  2.   res <- mean(abs(label-pred))
  3.   return(res)
  4. })
复制代码
  1. mx.set.seed(0)
  2. model <- mx.model.FeedForward.create(lro, X=train.x, y=train.y, ctx=mx.cpu(), num.round=50, array.batch.size=20, learning.rate=2e-6, momentum=0.9, eval.metric=demo.metric.mae)
复制代码
  1. ## Auto detect layout of input matrix, use rowmajor..
  2. ## Start training with 1 devices
  3. ## [1] Train-mae=13.1889538083225
  4. ## [2] Train-mae=9.81431959337658
  5. ## [3] Train-mae=9.21576419870059

  6. ...

  7. ## [48] Train-mae=6.41731406417158
  8. ## [49] Train-mae=6.41011292926139
  9. ## [50] Train-mae=6.40312503493494
复制代码
至此,你已经掌握了基本的mxnet使用方法。接下来,我们将介绍更好玩的应用。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复

使用道具 举报

*滑动验证:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

热帖滚动

推荐阅读

阅读排行

扫描二维码 关注我们官方微信 RDMA知识一手掌握

联系我们

点击发送邮件

   HPC Advisory Council 版权所有   京ICP备17021631号-1

QQ- Archiver-手机版- RDMAWorld.com