丁香五月天婷婷久久婷婷色综合91|国产传媒自偷自拍|久久影院亚洲精品|国产欧美VA天堂国产美女自慰视屏|免费黄色av网站|婷婷丁香五月激情四射|日韩AV一区二区中文字幕在线观看|亚洲欧美日本性爱|日日噜噜噜夜夜噜噜噜|中文Av日韩一区二区

您正在使用IE低版瀏覽器,為了您的雷峰網(wǎng)賬號安全和更好的產(chǎn)品體驗,強(qiáng)烈建議使用更快更安全的瀏覽器
此為臨時鏈接,僅用于文章預(yù)覽,將在時失效
人工智能開發(fā)者 正文
發(fā)私信給AI研習(xí)社
發(fā)送

0

DeepLearning4j 實戰(zhàn):手寫體數(shù)字識別的 GPU 實現(xiàn)與性能對比

本文作者: AI研習(xí)社 2017-05-19 16:58
導(dǎo)語:GPU 到底有多快?

DeepLearning4j 實戰(zhàn):手寫體數(shù)字識別的 GPU 實現(xiàn)與性能對比

雷鋒網(wǎng)按:本文作者 wangongxi,原文載于作者個人博客,雷鋒網(wǎng)已獲授權(quán)。

在之前的博客中已經(jīng)用單機(jī)、Spark分布式兩種訓(xùn)練的方式對深度神經(jīng)網(wǎng)絡(luò)進(jìn)行訓(xùn)練,但其實DeepLearning4j也是支持多GPU訓(xùn)練的。

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

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

環(huán)境部署完后,分別用java -version和nvidia-smi來確認(rèn)環(huán)境是否部署正確,如果出現(xiàn)類似以下的信息,則說明環(huán)境部署正確,否則需要重新安裝。

  GPU配置:

DeepLearning4j 實戰(zhàn):手寫體數(shù)字識別的 GPU 實現(xiàn)與性能對比

  Java環(huán)境截圖:

DeepLearning4j 實戰(zhàn):手寫體數(shù)字識別的 GPU 實現(xiàn)與性能對比

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

  下面說明下代碼的構(gòu)成:

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

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">  

  <modelVersion>4.0.0</modelVersion>  

  <groupId>DeepLearning</groupId>  

  <artifactId>DeepLearning</artifactId>  

  <version>2.0</version>  

    

  <properties>  

    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>  

    <nd4j.version>0.8.0</nd4j.version>  

    <dl4j.version>0.8.0</dl4j.version>  

    <datavec.version>0.8.0</datavec.version>  

    <scala.binary.version>2.11</scala.binary.version>  

  </properties>  

    

 <dependencies>  

       <dependency>  

         <groupId>org.nd4j</groupId>  

         <artifactId>nd4j-native</artifactId>   

         <version>${nd4j.version}</version>  

       </dependency>  

       <dependency>  

            <groupId>org.deeplearning4j</groupId>  

            <artifactId>deeplearning4j-core</artifactId>  

            <version>${dl4j.version}</version>  

        </dependency>  

        <dependency>  

         <groupId>org.nd4j</groupId>  

         <artifactId>nd4j-cuda-8.0</artifactId>  

         <version>${nd4j.version}</version>  

        </dependency>  

        <dependency>  

            <groupId>org.deeplearning4j</groupId>  

            <artifactId>deeplearning4j-parallel-wrapper_${scala.binary.version}</artifactId>  

            <version>${dl4j.version}</version>  

        </dependency>  

    </dependencies>  

  <build>  

    <plugins>  

        <plugin>  

            <groupId>org.apache.maven.plugins</groupId>  

            <artifactId>maven-jar-plugin</artifactId>  

            <version>2.4</version>  

            <configuration>  

                <source>1.7</source>   

                <target>1.7</target>   

                <archive>  

                    <manifest>  

                        <mainClass>cn.live.wangongxi.cv.CNNMnist</mainClass>  

                    </manifest>  

                </archive>  

            </configuration>  

        </plugin>  

    </plugins>  

</build>  

</project>  

創(chuàng)建完Maven工程以及添加了上面POM文件的內(nèi)容之后,就可以開始著手上層應(yīng)用邏輯的構(gòu)建。這里我參考了官網(wǎng)的例子,具體由以下幾個部分構(gòu)成:

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

● 讀取Mnist二進(jìn)制文件(和之前的博客內(nèi)容一致)

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

● 訓(xùn)練以及評估模型的指標(biāo)

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

//精度設(shè)置,常用精度有單、雙、半精度  

//HALF : 半精度  

DataTypeUtil.setDTypeForContext(DataBuffer.Type.HALF);  

//FLOAT : 單精度  

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

//DOUBLE : 雙精度  

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

  

//創(chuàng)建CUDA上下文實例并設(shè)置參數(shù)  

   CudaEnvironment.getInstance().getConfiguration()  

    //是否允許多GPU  

       .allowMultiGPU(false)  

       //設(shè)置顯存中緩存數(shù)據(jù)的容量,單位:字節(jié)  

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

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

       .allowCrossDeviceAccess(false);  

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

再下面就是設(shè)置CUDA的一些上下文參數(shù),比如代碼中羅列的cache數(shù)據(jù)的顯存大小,P2P訪問內(nèi)存和多GPU運(yùn)行的標(biāo)志位等等。對于網(wǎng)絡(luò)結(jié)構(gòu)相對簡單,數(shù)據(jù)量不大的情況下,默認(rèn)的參數(shù)就夠用了。這里我們也只是簡單設(shè)置了幾個參數(shù),這對于用LeNet來訓(xùn)練Mnist數(shù)據(jù)集來說已經(jīng)足夠了。

從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<nEpochs; 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卡進(jìn)行Mnist數(shù)據(jù)集進(jìn)行訓(xùn)練和評估的邏輯。如果想在多GPU下進(jìn)行并行訓(xùn)練的話,需要修改一些設(shè)置,例如在之前第一步的創(chuàng)建CUDA環(huán)境上下文的時候,需要允許多GPU和P2P內(nèi)存訪問,即設(shè)置為true。然后在邏輯里添加并行訓(xùn)練的邏輯:

ParallelWrapper wrapper = new ParallelWrapper.Builder(model)  

    .prefetchBuffer(24)  

    .workers(4)  

    .averagingFrequency(3)  

    .reportScoreAfterAveraging(true)  

    .useLegacyAveraging(true)  

    .build();  

這樣如果有多張GPU卡就可以進(jìn)行單機(jī)多卡的并行訓(xùn)練。

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

  單卡訓(xùn)練截圖:

DeepLearning4j 實戰(zhàn):手寫體數(shù)字識別的 GPU 實現(xiàn)與性能對比

  雙卡并行訓(xùn)練截圖:

DeepLearning4j 實戰(zhàn):手寫體數(shù)字識別的 GPU 實現(xiàn)與性能對比

  訓(xùn)練時間評估:

DeepLearning4j 實戰(zhàn):手寫體數(shù)字識別的 GPU 實現(xiàn)與性能對比DeepLearning4j 實戰(zhàn):手寫體數(shù)字識別的 GPU 實現(xiàn)與性能對比

最后做下簡單的總結(jié)。由于Deeplearning4j本身支持GPU單卡,多卡以及集群的訓(xùn)練方式,而且對于底層的接口都已經(jīng)進(jìn)行了很多的封裝,暴露的接口都是比較hig-level的接口,一般設(shè)置一些屬性就可以了。當(dāng)然前提是硬件包括CUDA都要正確安裝。

雷鋒網(wǎng)相關(guān)閱讀:

玩深度學(xué)習(xí)選哪塊英偉達(dá) GPU?有性價比排名還不夠!

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


NLP實戰(zhàn)特訓(xùn)班:阿里IDST9大專家?guī)闳腴T

iDST 九大工程師首次在線授課,帶你快速入門NLP技術(shù)

課程鏈接:http://www.mooc.ai/course/83

加入AI慕課學(xué)院人工智能學(xué)習(xí)交流QQ群:624413030,與AI同行一起交流成長


雷峰網(wǎng)版權(quán)文章,未經(jīng)授權(quán)禁止轉(zhuǎn)載。詳情見轉(zhuǎn)載須知

DeepLearning4j 實戰(zhàn):手寫體數(shù)字識別的 GPU 實現(xiàn)與性能對比

分享:
相關(guān)文章

編輯

聚焦數(shù)據(jù)科學(xué),連接 AI 開發(fā)者。更多精彩內(nèi)容,請訪問:yanxishe.com
當(dāng)月熱門文章
最新文章
請?zhí)顚懮暾埲速Y料
姓名
電話
郵箱
微信號
作品鏈接
個人簡介
為了您的賬戶安全,請驗證郵箱
您的郵箱還未驗證,完成可獲20積分喲!
請驗證您的郵箱
立即驗證
完善賬號信息
您的賬號已經(jīng)綁定,現(xiàn)在您可以設(shè)置密碼以方便用郵箱登錄
立即設(shè)置 以后再說