乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      嚴(yán)酷的魔王: mxnet:結(jié)合R與GPU加速深度學(xué)習(xí) | 統(tǒng)計(jì)之都 (中國(guó)統(tǒng)計(jì)學(xué)門戶網(wǎng)站,免費(fèi)統(tǒng)計(jì)學(xué)服務(wù)平臺(tái))

       無(wú)名小卒917 2017-01-18

      近年來(lái),深度學(xué)習(xí)可謂是機(jī)器學(xué)習(xí)方向的明星概念,不同的模型分別在圖像處理與自然語(yǔ)言處理等任務(wù)中取得了前所未有的好成績(jī)。在實(shí)際的應(yīng)用中,大家除了關(guān)心模型的準(zhǔn)確度,還常常希望能比較快速地完成模型的訓(xùn)練。一個(gè)常用的加速手段便是將模型放在GPU上進(jìn)行訓(xùn)練。然而由于種種原因,R語(yǔ)言似乎缺少一個(gè)能夠在GPU上訓(xùn)練深度學(xué)習(xí)模型的程序包。

      DMLC(Distributed (Deep) Machine Learning Community)是由一群極客發(fā)起的組織,主要目標(biāo)是提供快速高質(zhì)量的開(kāi)源機(jī)器學(xué)習(xí)工具。近來(lái)流行的boosting模型xgboost便是出自這個(gè)組織。最近DMLC開(kāi)源了一個(gè)深度學(xué)習(xí)工具mxnet,這個(gè)工具含有R,python,julia等語(yǔ)言的接口。本文以R接口為主,向大家介紹這個(gè)工具的性能與使用方法。

      一、五分鐘入門指南

      在這一節(jié)里,我們?cè)谝粋€(gè)樣例數(shù)據(jù)上介紹mxnet的基本使用方法。目前mxnet還沒(méi)有登錄CRAN的計(jì)劃,所以安裝方法要稍微復(fù)雜一些。

      • 如果你是Windows/Mac用戶,那么可以通過(guò)下面的代碼安裝預(yù)編譯的版本。這個(gè)版本會(huì)每周進(jìn)行預(yù)編譯,不過(guò)為了保證兼容性,只能使用CPU訓(xùn)練模型。
      install.packages("drat", repos="https://cran.")
      drat:::addRepo("dmlc")
      install.packages("mxnet")
      • 如果你是Linux用戶或者想嘗試GPU版本,請(qǐng)參考這個(gè)鏈接里的詳細(xì)編譯教程在本地進(jìn)行編譯。

      安裝完畢之后,我們就可以開(kāi)始訓(xùn)練模型了,下面兩個(gè)小節(jié)分別介紹兩種不同的訓(xùn)練神經(jīng)網(wǎng)絡(luò)的方法。

      二分類模型與mx.mlp

      首先,我們準(zhǔn)備一份數(shù)據(jù),并進(jìn)行簡(jiǎn)單的預(yù)處理:

      require(mlbench)
      require(mxnet)
      data(Sonar, package="mlbench")
      Sonar[,61] = as.numeric(Sonar[,61])-1
      train.ind = c(1:50, 100:150)
      train.x = data.matrix(Sonar[train.ind, 1:60])
      train.y = Sonar[train.ind, 61]
      test.x = data.matrix(Sonar[-train.ind, 1:60])
      test.y = Sonar[-train.ind, 61]

      我們借用mlbench包中的一個(gè)二分類數(shù)據(jù),并且將它分成訓(xùn)練集和測(cè)試集。mxnet提供了一個(gè)訓(xùn)練多層神經(jīng)網(wǎng)絡(luò)的函數(shù)mx.mlp,我們額可以通過(guò)它來(lái)訓(xùn)練一個(gè)神經(jīng)網(wǎng)絡(luò)模型。下面是mx.mlp中的部分參數(shù):

      • 訓(xùn)練數(shù)據(jù)與預(yù)測(cè)變量
      • 每個(gè)隱藏層的大小
      • 輸出層的結(jié)點(diǎn)數(shù)
      • 激活函數(shù)類型
      • 損失函數(shù)類型
      • 進(jìn)行訓(xùn)練的硬件(CPU還是GPU)
      • 其他傳給mx.model.FeedForward.create的高級(jí)參數(shù)

      了解了大致參數(shù)后,我們就可以理解并讓R運(yùn)行下面的代碼進(jìn)行訓(xùn)練了。

      mx.set.seed(0)
      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)
      ## Auto detect layout of input matrix, use rowmajor..
      ## Start training with 1 devices
      ## [1] Train-accuracy=0.488888888888889
      ## [2] Train-accuracy=0.514285714285714
      ## [3] Train-accuracy=0.514285714285714
      
      ...
      
      ## [18] Train-accuracy=0.838095238095238
      ## [19] Train-accuracy=0.838095238095238
      ## [20] Train-accuracy=0.838095238095238

      這里要注意使用mx.set.seed而不是R自帶的set.seed函數(shù)來(lái)控制隨機(jī)數(shù)。因?yàn)閙xnet的訓(xùn)練過(guò)程可能會(huì)運(yùn)行在不同的運(yùn)算硬件上,我們需要一個(gè)足夠快的隨機(jī)數(shù)生成器來(lái)管理整個(gè)隨機(jī)數(shù)生成的過(guò)程。模型訓(xùn)練好之后,我們可以很簡(jiǎn)單地進(jìn)行預(yù)測(cè):

      preds = predict(model, test.x)
      
      ## Auto detect layout of input matrix, use rowmajor..
      
      pred.label = max.col(t(preds))-1
      table(pred.label, test.y)
      
      ##           test.y
      ## pred.label  0  1
      ##          0 24 14
      ##          1 36 33

      如果進(jìn)行的是多分類預(yù)測(cè),mxnet的輸出格式是類數(shù)X樣本數(shù)。

      回歸模型與自定義神經(jīng)網(wǎng)絡(luò)

      mx.mlp接口固然很方便,但是神經(jīng)網(wǎng)絡(luò)的一大特點(diǎn)便是它的靈活性,不同的結(jié)構(gòu)可能有著完全不同的特性。mxnet的亮點(diǎn)之一便是它賦予了用戶極大的自由度,從而可以任意定義需要的神經(jīng)網(wǎng)絡(luò)結(jié)構(gòu)。我們?cè)谶@一節(jié)用一個(gè)簡(jiǎn)單的回歸任務(wù)介紹相關(guān)的語(yǔ)法。

      首先,我們?nèi)匀灰獪?zhǔn)備好一份數(shù)據(jù)。

      data(BostonHousing, package="mlbench")
      
      train.ind = seq(1, 506, 3)
      train.x = data.matrix(BostonHousing[train.ind, -14])
      train.y = BostonHousing[train.ind, 14]
      test.x = data.matrix(BostonHousing[-train.ind, -14])
      test.y = BostonHousing[-train.ind, 14]

      mxnet提供了一個(gè)叫做“Symbol”的系統(tǒng),從而使我們可以定義結(jié)點(diǎn)之間的連接方式與激活函數(shù)等參數(shù)。下面是一個(gè)定義沒(méi)有隱藏層神經(jīng)網(wǎng)絡(luò)的簡(jiǎn)單例子:

      # 定義輸入數(shù)據(jù)
      data <- mx.symbol.Variable("data")
      # 完整連接的隱藏層
      # data: 輸入源
      # num_hidden: 該層的節(jié)點(diǎn)數(shù)
      fc1 <- mx.symbol.FullyConnected(data, num_hidden=1)
      
      # 針對(duì)回歸任務(wù),定義損失函數(shù)
      lro <- mx.symbol.LinearRegressionOutput(fc1)

      在神經(jīng)網(wǎng)絡(luò)中,回歸與分類的差別主要在于輸出層的損失函數(shù)。這里我們使用了平方誤差來(lái)訓(xùn)練模型。希望能更進(jìn)一步了解Symbol的讀者可以繼續(xù)閱讀這份以代碼為主的文檔。

      定義了神經(jīng)網(wǎng)絡(luò)之后,我們便可以使用mx.model.FeedForward.create進(jìn)行訓(xùn)練了。

      mx.set.seed(0)
      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)
      
      ## Auto detect layout of input matrix, use rowmajor..
      ## Start training with 1 devices
      ## [1] Train-rmse=16.063282524034
      ## [2] Train-rmse=12.2792375712573
      ## [3] Train-rmse=11.1984634005885
      
      ...
      
      ## [48] Train-rmse=8.26890902770415
      ## [49] Train-rmse=8.25728089053853
      ## [50] Train-rmse=8.24580511500735

      這里我們還針對(duì)回歸任務(wù)修改了eval.metric參數(shù)。目前我們提供的評(píng)價(jià)函數(shù)包括”accuracy”,”rmse”,”mae” 和 “rmsle”,用戶也可以針對(duì)需要自定義評(píng)價(jià)函數(shù),例如:

      demo.metric.mae <- mx.metric.custom("mae", function(label, pred) {
        res <- mean(abs(label-pred))
        return(res)
      })
      mx.set.seed(0)
      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)
      
      ## Auto detect layout of input matrix, use rowmajor..
      ## Start training with 1 devices
      ## [1] Train-mae=13.1889538083225
      ## [2] Train-mae=9.81431959337658
      ## [3] Train-mae=9.21576419870059
      
      ...
      
      ## [48] Train-mae=6.41731406417158
      ## [49] Train-mae=6.41011292926139
      ## [50] Train-mae=6.40312503493494

      至此,你已經(jīng)掌握了基本的mxnet使用方法。接下來(lái),我們將介紹更好玩的應(yīng)用。

      二、手寫數(shù)字競(jìng)賽

      在這一節(jié)里,我們以Kaggle上的手寫數(shù)字?jǐn)?shù)據(jù)集(MNIST)競(jìng)賽為例子,介紹如何通過(guò)mxnet定義一個(gè)強(qiáng)大的神經(jīng)網(wǎng)絡(luò),并在GPU上快速訓(xùn)練模型。

      第一步,我們從Kaggle上下載數(shù)據(jù),并將它們放入data/文件夾中。然后我們讀入數(shù)據(jù),并做一些預(yù)處理工作。

      require(mxnet)
      train <- read.csv('data/train.csv', header=TRUE) 
      test <- read.csv('data/test.csv', header=TRUE) 
      train <- data.matrix(train) 
      test <- data.matrix(test) 
      
      train.x <- train[,-1] 
      train.y <- train[,1]
      
      train.x <- t(train.x/255)
      test <- t(test/255)

      最后兩行預(yù)處理的作用有兩個(gè):

      • 原始灰度圖片數(shù)值處在[0,255]之間,我們將其變換到[0,1]之間。
      • mxnet接受 像素X圖片 的輸入格式,所以我們對(duì)輸入矩陣進(jìn)行了轉(zhuǎn)置。

      接下來(lái)我們定義一個(gè)特別的神經(jīng)網(wǎng)絡(luò)結(jié)構(gòu):LeNet。這是Yann LeCun提出用于識(shí)別手寫數(shù)字的結(jié)構(gòu),也是最早的卷積神經(jīng)網(wǎng)絡(luò)之一。同樣的,我們使用Symbol語(yǔ)法來(lái)定義,不過(guò)這次結(jié)構(gòu)會(huì)比較復(fù)雜。

      # input
      data <- mx.symbol.Variable('data')
      # first conv
      conv1 <- mx.symbol.Convolution(data=data, kernel=c(5,5), num_filter=20)
      tanh1 <- mx.symbol.Activation(data=conv1, act_type="tanh")
      pool1 <- mx.symbol.Pooling(data=tanh1, pool_type="max",
                                kernel=c(2,2), stride=c(2,2))
      # second conv
      conv2 <- mx.symbol.Convolution(data=pool1, kernel=c(5,5), num_filter=50)
      tanh2 <- mx.symbol.Activation(data=conv2, act_type="tanh")
      pool2 <- mx.symbol.Pooling(data=tanh2, pool_type="max",
                                kernel=c(2,2), stride=c(2,2))
      # first fullc
      flatten <- mx.symbol.Flatten(data=pool2)
      fc1 <- mx.symbol.FullyConnected(data=flatten, num_hidden=500)
      tanh3 <- mx.symbol.Activation(data=fc1, act_type="tanh")
      # second fullc
      fc2 <- mx.symbol.FullyConnected(data=tanh3, num_hidden=10)
      # loss
      lenet <- mx.symbol.SoftmaxOutput(data=fc2)

      為了讓輸入數(shù)據(jù)的格式能對(duì)應(yīng)LeNet,我們要將數(shù)據(jù)變成R中的array格式:

      train.array <- train.x
      dim(train.array) <- c(28, 28, 1, ncol(train.x))
      test.array <- test
      dim(test.array) <- c(28, 28, 1, ncol(test))

      接下來(lái)我們將要分別使用CPU和GPU來(lái)訓(xùn)練這個(gè)模型,從而展現(xiàn)不同的訓(xùn)練效率。

      n.gpu <- 1
      device.cpu <- mx.cpu()
      device.gpu <- lapply(0:(n.gpu-1), function(i) {
        mx.gpu(i)
      })

      我們可以將GPU的每個(gè)核以list的格式傳遞進(jìn)去,如果有BLAS等自帶矩陣運(yùn)算并行的庫(kù)存在,則沒(méi)必要對(duì)CPU這么做了。

      我們先在CPU上進(jìn)行訓(xùn)練,這次我們只進(jìn)行一次迭代:

      mx.set.seed(0)
      tic <- proc.time()
      model <- mx.model.FeedForward.create(lenet, X=train.array, y=train.y, ctx=device.cpu, num.round=1, array.batch.size=100, learning.rate=0.05, momentum=0.9, wd=0.00001, eval.metric=mx.metric.accuracy, epoch.end.callback=mx.callback.log.train.metric(100))
      
      ## Start training with 1 devices
      ## Batch [100] Train-accuracy=0.1066
      ## Batch [200] Train-accuracy=0.16495
      ## Batch [300] Train-accuracy=0.401766666666667
      ## Batch [400] Train-accuracy=0.537675
      ## [1] Train-accuracy=0.557136038186157
      
      print(proc.time() - tic)
      
      ##    user  system elapsed
      ## 130.030 204.976  83.821

      在CPU上訓(xùn)練一次迭代一共花了83秒。接下來(lái)我們?cè)贕PU上訓(xùn)練5次迭代:

      mx.set.seed(0)
      tic <- proc.time()
      model <- mx.model.FeedForward.create(lenet, X=train.array, y=train.y, ctx=device.gpu, num.round=5, array.batch.size=100, learning.rate=0.05, momentum=0.9, wd=0.00001, eval.metric=mx.metric.accuracy, epoch.end.callback=mx.callback.log.train.metric(100))
      
      ## Start training with 1 devices
      ## Batch [100] Train-accuracy=0.1066
      ## Batch [200] Train-accuracy=0.1596
      ## Batch [300] Train-accuracy=0.3983
      ## Batch [400] Train-accuracy=0.533975
      ## [1] Train-accuracy=0.553532219570405
      ## Batch [100] Train-accuracy=0.958
      ## Batch [200] Train-accuracy=0.96155
      ## Batch [300] Train-accuracy=0.966100000000001
      ## Batch [400] Train-accuracy=0.968550000000003
      ## [2] Train-accuracy=0.969071428571432
      ## Batch [100] Train-accuracy=0.977
      ## Batch [200] Train-accuracy=0.97715
      ## Batch [300] Train-accuracy=0.979566666666668
      ## Batch [400] Train-accuracy=0.980900000000003
      ## [3] Train-accuracy=0.981309523809527
      ## Batch [100] Train-accuracy=0.9853
      ## Batch [200] Train-accuracy=0.985899999999999
      ## Batch [300] Train-accuracy=0.986966666666668
      ## Batch [400] Train-accuracy=0.988150000000002
      ## [4] Train-accuracy=0.988452380952384
      ## Batch [100] Train-accuracy=0.990199999999999
      ## Batch [200] Train-accuracy=0.98995
      ## Batch [300] Train-accuracy=0.990600000000001
      ## Batch [400] Train-accuracy=0.991325000000002
      ## [5] Train-accuracy=0.991523809523812
      
      print(proc.time() - tic)
      
      ##    user  system elapsed
      ##   9.288   1.680   6.889

      在GPU上訓(xùn)練5輪迭代只花了不到7秒,快了數(shù)十倍!可以看出,對(duì)于這樣的網(wǎng)絡(luò)結(jié)構(gòu),GPU的加速效果是非常顯著的。有了快速訓(xùn)練的辦法,我們便可以很快的做預(yù)測(cè),并且提交到Kaggle上了:

      preds <- predict(model, test.array)
      pred.label <- max.col(t(preds)) - 1
      submission <- data.frame(ImageId=1:ncol(test), Label=pred.label)
      write.csv(submission, file='submission.csv', row.names=FALSE, quote=FALSE)

      三、圖像識(shí)別應(yīng)用

      其實(shí)對(duì)于神經(jīng)網(wǎng)絡(luò)當(dāng)前的應(yīng)用場(chǎng)景而言,識(shí)別手寫數(shù)字已經(jīng)不夠看了。早些時(shí)候,Google公開(kāi)了一個(gè)云API,讓用戶能夠檢測(cè)一幅圖像里面的內(nèi)容。現(xiàn)在我們提供一個(gè)教程,讓大家能夠自制一個(gè)圖像識(shí)別的在線應(yīng)用。

      DMLC用在ImageNet數(shù)據(jù)集上訓(xùn)練了一個(gè)模型,能夠直接拿來(lái)對(duì)真實(shí)圖片進(jìn)行分類。同時(shí),我們搭建了一個(gè)Shiny應(yīng)用,只需要不超過(guò)150行R代碼就能夠自己在瀏覽器中進(jìn)行圖像中的物體識(shí)別。

      為了搭建這個(gè)應(yīng)用,我們要安裝shiny和imager兩個(gè)R包:

      install.packages("shiny", repos="https://cran.")
      install.packages("imager", repos="https://cran.")

      現(xiàn)在你已經(jīng)配置好了mxnet, shiny和imager三個(gè)R包,最困難的部分已經(jīng)完成了!下一步則是讓shiny直接下載并運(yùn)行我們準(zhǔn)備好的代碼:

      shiny::runGitHub("thirdwing/mxnet_shiny")

      第一次運(yùn)行這個(gè)命令會(huì)花上幾分鐘時(shí)間下載預(yù)先訓(xùn)練好的模型。訓(xùn)練的模型是Inception-BatchNorm Network,如果讀者對(duì)它感興趣,可以閱讀這篇文章。準(zhǔn)備就緒之后,你的瀏覽器中會(huì)出現(xiàn)一個(gè)網(wǎng)頁(yè)應(yīng)用,就用本地或在線圖片來(lái)挑戰(zhàn)它吧!

      如果你只需要一個(gè)圖像識(shí)別的模塊,那么我們下面給出最簡(jiǎn)單的一段R代碼讓你能進(jìn)行圖像識(shí)別。首先,我們要導(dǎo)入預(yù)訓(xùn)練過(guò)的模型文件:

      model <<- mx.model.load("Inception/Inception_BN", iteration = 39)
      synsets <<- readLines("Inception/synset.txt")
      mean.img <<- as.array(mx.nd.load("Inception/mean_224.nd")[["mean_img"]])

      接下來(lái)我們使用一個(gè)函數(shù)對(duì)圖像進(jìn)行預(yù)處理,這個(gè)步驟對(duì)于神經(jīng)網(wǎng)絡(luò)模型而言至關(guān)重要。

      preproc.image <- function(im, mean.image) {
        # crop the image
        shape <- dim(im)
        short.edge <- min(shape[1:2])
        yy <- floor((shape[1] - short.edge) / 2) + 1
        yend <- yy + short.edge - 1
        xx <- floor((shape[2] - short.edge) / 2) + 1
        xend <- xx + short.edge - 1
        croped <- im[yy:yend, xx:xend,,]
        # resize to 224 x 224, needed by input of the model.
        resized <- resize(croped, 224, 224)
        # convert to array (x, y, channel)
        arr <- as.array(resized)
        dim(arr) = c(224, 224, 3)
        # substract the mean
        normed <- arr - mean.img
        # Reshape to format needed by mxnet (width, height, channel, num)
        dim(normed) <- c(224, 224, 3, 1)
        return(normed)
      }

      最后我們讀入圖像,預(yù)處理與預(yù)測(cè)就可以了。

      im <- load.image(src)
      normed <- preproc.image(im, mean.img)
      prob <- predict(model, X = normed)
      max.idx <- order(prob[,1], decreasing = TRUE)[1:5]
      result <- synsets[max.idx]

      四、參考資料

      MXNet是一個(gè)在底層與接口都有著豐富功能的軟件,如果讀者對(duì)它感興趣,可以參考一些額外的材料來(lái)進(jìn)一步了解MXNet,或者是深度學(xué)習(xí)這個(gè)領(lǐng)域。

       



        本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評(píng)論

        發(fā)表

        請(qǐng)遵守用戶 評(píng)論公約

        類似文章 更多