當前位置:
首頁 > 新聞 > DeepLearning4j 實戰:手寫體數字識別的 GPU 實現與性能對比

DeepLearning4j 實戰:手寫體數字識別的 GPU 實現與性能對比

DeepLearning4j 實戰:手寫體數字識別的 GPU 實現與性能對比

雷鋒網按:本文作者 wangongxi,原文載於作者個人博客,雷鋒網已獲授權。

在之前的博客中已經用單機、Spark分布式兩種訓練的方式對深度神經網路進行訓練,但其實DeepLearning4j也是支持多GPU訓練的。

這篇文章我就總結下用GPU來對DNN/CNN進行訓練和評估過程。並且我會給出CPU、GPU和多卡GPU之前的性能比較圖表。不過,由於重點在於說明Mnist數據集在GPU上訓練的過程,所以對於一些環境的部署,比如Java環境和CUDA的安裝就不再詳細說明了。

軟體環境的部署主要在於兩個方面,一個是JDK的安裝,另外一個是CUDA。目前最新版本的DeepLearning4j以及Nd4j支持CUDA-8.0,JDK的話1.7以上。

環境部署完後,分別用java -version和nvidia-smi來確認環境是否部署正確,如果出現類似以下的信息,則說明環境部署正確,否則需要重新安裝。

GPU配置:

DeepLearning4j 實戰:手寫體數字識別的 GPU 實現與性能對比

Java環境截圖:

從系統返回的信息可以看到,jdk是openJDK1.7,GPU是2張P40的卡。

下面說明下代碼的構成:

由於我這裡用了DeepLearning4j最新的版本--v0.8,所以和之前博客的pom文件有些修改,具體如下:


創建完Maven工程以及添加了上面POM文件的內容之後,就可以開始著手上層應用邏輯的構建。這裡我參考了官網的例子,具體由以下幾個部分構成:


● 初始化CUDA的環境(底層邏輯包括硬體檢測、CUDA版本校驗和一些GPU參數)

● 讀取Mnist二進位文件(和之前的博客內容一致)

● CNN的定義,這裡我還是用的LeNet

● 訓練以及評估模型的指標

首先貼一下第一部分的代碼:

//精度設置,常用精度有單、雙、半精度

//HALF : 半精度

DataTypeUtil.setDTypeForContext(DataBuffer.Type.HALF);

//FLOAT : 單精度

//DataTypeUtil.setDTypeForContext(DataBuffer.Type.FLOAT);

//DOUBLE : 雙精度

//DataTypeUtil.setDTypeForContext(DataBuffer.Type.DOUBLE);

//創建CUDA上下文實例並設置參數

CudaEnvironment.getInstance.getConfiguration

//是否允許多GPU

.allowMultiGPU(false)

//設置顯存中緩存數據的容量,單位:位元組

.setMaximumDeviceCache(2L * 1024L * 1024L * 1024L)

//是否允許多GPU間點對點(P2P)的內存訪問

.allowCrossDeviceAccess(false);

通常我們需要根據需要來設置GPU計算的精度,常用的就像代碼中寫的那樣有單、雙、半精度三種。通過選擇DataBuffer中定義的enum類型Type中的值來達到設置精度的目的。如果不設置,默認的是單精度。

再下面就是設置CUDA的一些上下文參數,比如代碼中羅列的cache數據的顯存大小,P2P訪問內存和多GPU運行的標誌位等等。對於網路結構相對簡單,數據量不大的情況下,默認的參數就夠用了。這裡我們也只是簡單設置了幾個參數,這對於用LeNet來訓練Mnist數據集來說已經足夠了。

從2~4部分的邏輯和之前的博客里幾乎是一樣的,就直接上代碼了:


int nChannels = 1;

int outputNum = 10;

int batchSize = 128;

int nEpochs = 10;

int iterations = 1;

int seed = 123;

log.info("Load data....");

DataSetIterator mnistTrain = new MnistDataSetIterator(batchSize,true,12345);

DataSetIterator mnistTest = new MnistDataSetIterator(batchSize,false,12345);

log.info("Build model....");

MultiLayerConfiguration conf = new NeuralNetConfiguration.Builder

.seed(seed)

.iterations(iterations)

.regularization(true).l2(0.0005)

.learningRate(.01)

.weightInit(WeightInit.XAVIER)

.optimizationAlgo(OptimizationAlgorithm.STOCHASTIC_GRADIENT_DESCENT)

.updater(Updater.NESTEROVS).momentum(0.9)

.list

.layer(0, new ConvolutionLayer.Builder(5, 5)

.nIn(nChannels)

.stride(1, 1)

.nOut(20)

.activation(Activation.IDENTITY)

.build)

.layer(1, new SubsamplingLayer.Builder(SubsamplingLayer.PoolingType.MAX)

.kernelSize(2,2)

.stride(2,2)

.build)

.layer(2, new ConvolutionLayer.Builder(5, 5)

.stride(1, 1)

.nOut(50)

.activation(Activation.IDENTITY)

.build)

.layer(3, new SubsamplingLayer.Builder(SubsamplingLayer.PoolingType.MAX)

.kernelSize(2,2)

.stride(2,2)

.build)

.layer(4, new DenseLayer.Builder.activation(Activation.RELU)

.nOut(500).build)

.layer(5, new OutputLayer.Builder(LossFunctions.LossFunction.NEGATIVELOGLIKELIHOOD)

.nOut(outputNum)

.activation(Activation.SOFTMAX)

.build)

.setInputType(InputType.convolutionalFlat(28,28,1))

.backprop(true).pretrain(false).build;

MultiLayerNetwork model = new MultiLayerNetwork(conf);

model.init;

log.info("Train model....");

model.setListeners(new ScoreIterationListener(100));

long timeX = System.currentTimeMillis;

for( int i=0; i

long time1 = System.currentTimeMillis;

model.fit(mnistTrain);

long time2 = System.currentTimeMillis;

log.info("*** Completed epoch {}, time: {} ***", i, (time2 - time1));

}

long timeY = System.currentTimeMillis;

log.info("*** Training complete, time: {} ***", (timeY - timeX));

log.info("Evaluate model....");

Evaluation eval = new Evaluation(outputNum);

while(mnistTest.hasNext){

DataSet ds = mnistTest.next;

INDArray output = model.output(ds.getFeatureMatrix, false);

eval.eval(ds.getLabels, output);

}

log.info(eval.stats);

log.info("****************Example finished********************");

以上邏輯就是利用一塊GPU卡進行Mnist數據集進行訓練和評估的邏輯。如果想在多GPU下進行並行訓練的話,需要修改一些設置,例如在之前第一步的創建CUDA環境上下文的時候,需要允許多GPU和P2P內存訪問,即設置為true。然後在邏輯里添加並行訓練的邏輯:


ParallelWrapper wrapper = new ParallelWrapper.Builder(model)

.prefetchBuffer(24)

.workers(4)

.averagingFrequency(3)

.reportScoreAfterAveraging(true)

.useLegacyAveraging(true)

.build;

這樣如果有多張GPU卡就可以進行單機多卡的並行訓練。

下面貼一下訓練Mnist數據集在CPU/GPU/多GPU下的性能比較還有訓練時候的GPU使用情況:

單卡訓練截圖:

DeepLearning4j 實戰:手寫體數字識別的 GPU 實現與性能對比

雙卡並行訓練截圖:

DeepLearning4j 實戰:手寫體數字識別的 GPU 實現與性能對比

訓練時間評估:

DeepLearning4j 實戰:手寫體數字識別的 GPU 實現與性能對比

DeepLearning4j 實戰:手寫體數字識別的 GPU 實現與性能對比

最後做下簡單的總結。由於Deeplearning4j本身支持GPU單卡,多卡以及集群的訓練方式,而且對於底層的介面都已經進行了很多的封裝,暴露的介面都是比較hig-level的介面,一般設置一些屬性就可以了。當然前提是硬體包括CUDA都要正確安裝。

雷鋒網相關閱讀:

玩深度學習選哪塊英偉達 GPU?有性價比排名還不夠!

谷歌說TPU比GPU更牛,Nvidia表示不服,並朝谷歌扔了一塊Tesla V100

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 雷鋒網 的精彩文章:

勒索病毒阻擊戰取得新突破,騰訊反病毒實驗室成功解密被鎖XP系統
「人工智慧產業技術創新戰略聯盟」著手籌建,攜手邁進「AI 2.0」
從這開始了解深度學習——視覺的深度學習與網路
湘雅二醫院、丁香園、大拿科技三方聯手,推出中國首個皮膚病人工智慧輔助診斷系統
瑞星發布預防勒索病毒工具「瑞星之劍」,現場演示抵禦 WannaCry

TAG:雷鋒網 |

您可能感興趣

TensorFlow 實踐之手寫體數字識別!
DC宣布全新流媒體數字平台名稱DC Universe
Windows窗體數據抓取詳解
億級學術圖譜 Open Academic Graph 更新至 2.0 版本:包含約 7 億實體數據、20 億關係
蘋果說 iPhone XR 是公司最暢銷的手機,但沒有給出具體數字
DC宣布全新流媒體數字平台名稱DC Universe 將首播真人版《沼澤怪物》
突飛猛進,AURALiC VEGA G2解碼器/ARIES G2無線流媒體數字轉盤
解密美圖大規模多媒體數據檢索技術 DeepHash
蘋果iPhone手機上線股票軟體數字貨幣行情 Mac受惡意挖礦軟體攻擊
119元 好輕Color2智能體脂秤發布:3秒測出17項身體數據
數碼寶貝:六大究極體數碼獸Boss,哪個在你心中是最強的?
高通CEO談與蘋果和解:不會公布具體數字
baby現場稱體重,李晨念出具體數字後,網友都不相信!
殺毒軟體公司McAfee:2018年加密貨幣惡意軟體數量增加4000%
對標小米9的iQOO有多能打?著名媒體數字尾巴是這樣測試的!
拍照不會擺pose?「人體數字照」拯救你,分分鐘湊齊九宮格!
張向寧:對比特幣、全體數字加密貨幣、ICO和對區塊鏈,有四個態度
PS教程/立體數字特效
好體知智能體脂秤N1:人體數據高精度,還帶肝臟脂肪指數檢測功能
亞馬遜獲得了流媒體數據市場授予的BTC用例專利