DL4J實戰之四:經典卷積例項(GPU版本)

程式設計師欣宸 發表於 2021-10-15
GPU

歡迎訪問我的GitHub

https://github.com/zq2599/blog_demos

內容:所有原創文章分類彙總及配套原始碼,涉及Java、Docker、Kubernetes、DevOPS等;

本篇概覽

  • 作為《DL4J實戰》的第四篇,今天我們們不寫程式碼,而是為今後的實戰做些準備:在DL4J框架下用GPU加速深度學習的訓練過程;
  • 如果您電腦上有NVIDIA顯示卡,並且成功的安裝了CUDA,那麼就隨本文一起實際操作吧,全文由以下內容構成:
  1. 軟硬體環境參考資訊
  2. DL4J的依賴庫和版本
  3. 使用GPU的具體操作步驟
  4. GPU訓練和CPU訓練對比

軟硬體環境參考資訊

  • 眾所周知,欣宸是個窮人,因此帶NVIDIA顯示卡的電腦就是一臺破舊的聯想筆記本,相關資訊如下:
  1. 作業系統:Ubuntu16桌面版
  2. 顯示卡型號:GTX950M
  3. CUDA:9.2
  4. CPU:i5-6300HQ
  5. 記憶體:32G DDR4
  6. 硬碟:NvMe 1T

DL4J的依賴庫和版本

  • 首先要強調的是:不要使用CUDA 11.2版本(這是執行nvidia-smi時輸出的版本),截止寫本文時,使用CUDA 11.2及其依賴庫,在啟動時會有ClassNotFound異常
  • CUDA 10.X版本我這裡也沒有試過,因此不做評論
  • CUDA 9.1和9.2版本都嘗試過,可以正常使用
  • 為什麼不用9.1呢?我們們先去中央倉庫看看DL4J核心庫的版本情況,如下圖,最新的版本已經到了1.0.0-M1

在這裡插入圖片描述

  • 再看看CUDA 9.1對應的nd4j庫的版本情況,如下圖紅框,最新的是2018年的1.0.0-beta,與核心庫差距太大了:

在這裡插入圖片描述

  • 好了,再來看看CUDA 9.2對應的nd4j庫的版本情況,如下圖紅框,最新的是1.0.0-beta6,與核心庫差兩個版本,因此,建議使用CUDA 9.2:

在這裡插入圖片描述

使用GPU的具體操作步驟

  • 使用CPU還是GPU,具體操作步驟非常簡單:切換不同的依賴庫即可,下面分別介紹
  • 如果您用CPU做訓練,則依賴庫和版本如下:
<!--核心庫,不論是CPU還是GPU都要用到-->
<dependency>
	<groupId>org.deeplearning4j</groupId>
    <artifactId>deeplearning4j-core</artifactId>
    <version>1.0.0-beta6</version>
</dependency>
<!--CPU要用到-->
<dependency>
	<groupId>org.nd4j</groupId>
	<artifactId>nd4j-native</artifactId>
	<version>1.0.0-beta6</version>
</dependency>

如果您用GPU做訓練,且CUDA版本是9.2,則依賴庫和版本如下:

<!--核心庫,不論是CPU還是GPU都要用到-->
<dependency>
	<groupId>org.deeplearning4j</groupId>
    <artifactId>deeplearning4j-core</artifactId>
    <version>1.0.0-beta6</version>
</dependency>
<!--GPU要用到-->
<dependency>
	<groupId>org.deeplearning4j</groupId>
	<artifactId>deeplearning4j-cuda-9.2</artifactId>
	<version>1.0.0-beta6</version>
</dependency>
<!--GPU要用到-->
<dependency>
	<groupId>org.nd4j</groupId>
	<artifactId>nd4j-cuda-9.2-platform</artifactId>
	<version>1.0.0-beta6</version>
</dependency>

記憶體設定

  • 使用IDEA執行程式碼的時候,可以按照當前硬體情況將記憶體適當調大,步驟如下圖:

在這裡插入圖片描述

  • 請酌情調整,我這裡設定為8G

在這裡插入圖片描述

  • 設定完畢,接下來在同一電腦上分別用CPU和GPU執行訓練和測試,通過對比檢查GPU加速效果

CPU版本

  • 在這臺破舊的膝上型電腦上,用CPU做訓練是非常吃力的,如下圖,幾乎被榨乾:

在這裡插入圖片描述

  • 控制檯輸出如下,耗時158秒,真是個漫長的過程:
=========================Confusion Matrix=========================
    0    1    2    3    4    5    6    7    8    9
---------------------------------------------------
  973    1    0    0    0    0    2    2    1    1 | 0 = 0
    0 1132    0    2    0    0    1    0    0    0 | 1 = 1
    1    5 1018    1    1    0    0    4    2    0 | 2 = 2
    0    0    2 1003    0    3    0    1    1    0 | 3 = 3
    0    0    1    0  975    0    2    0    0    4 | 4 = 4
    2    0    0    6    0  880    2    1    1    0 | 5 = 5
    6    1    0    0    3    4  944    0    0    0 | 6 = 6
    0    3    6    1    0    0    0 1012    2    4 | 7 = 7
    3    0    1    1    0    1    1    2  964    1 | 8 = 8
    0    0    0    2    6    2    0    2    0  997 | 9 = 9

Confusion matrix format: Actual (rowClass) predicted as (columnClass) N times
==================================================================
13:24:31.616 [main] INFO com.bolingcavalry.convolution.LeNetMNISTReLu - 完成訓練和測試,耗時[158739]毫秒
13:24:32.116 [main] INFO com.bolingcavalry.convolution.LeNetMNISTReLu - 最新的MINIST模型儲存在[/home/will/temp/202106/26/minist-model.zip]

GPU版本

  • 接下來按照前面給出的依賴關係修改pom.xml檔案,即可啟用GPU,執行過程中,控制檯輸出以下內容表示已啟用GPU:
13:27:08.277 [main] INFO org.nd4j.linalg.api.ops.executioner.DefaultOpExecutioner - Backend used: [CUDA]; OS: [Linux]
13:27:08.277 [main] INFO org.nd4j.linalg.api.ops.executioner.DefaultOpExecutioner - Cores: [4]; Memory: [7.7GB];
13:27:08.277 [main] INFO org.nd4j.linalg.api.ops.executioner.DefaultOpExecutioner - Blas vendor: [CUBLAS]
13:27:08.300 [main] INFO org.nd4j.linalg.jcublas.JCublasBackend - ND4J CUDA build version: 9.2.148
13:27:08.301 [main] INFO org.nd4j.linalg.jcublas.JCublasBackend - CUDA device 0: [GeForce GTX 950M]; cc: [5.0]; Total memory: [4242604032]
  • 這次的執行過程明顯流暢了許多,CPU使用率下降了不少:

在這裡插入圖片描述

  • 控制檯輸出如下,耗時21秒,可見GPU加速效果還是很明顯的:
=========================Confusion Matrix=========================
    0    1    2    3    4    5    6    7    8    9
---------------------------------------------------
  973    1    0    0    0    0    2    2    1    1 | 0 = 0
    0 1129    0    2    0    0    2    2    0    0 | 1 = 1
    1    3 1021    0    1    0    0    4    2    0 | 2 = 2
    0    0    1 1003    0    3    0    1    2    0 | 3 = 3
    0    0    1    0  973    0    3    0    0    5 | 4 = 4
    1    0    0    6    0  882    2    1    0    0 | 5 = 5
    6    1    0    0    2    5  944    0    0    0 | 6 = 6
    0    2    4    1    0    0    0 1016    2    3 | 7 = 7
    1    0    2    1    0    1    0    2  964    3 | 8 = 8
    0    0    0    2    6    3    0    2    1  995 | 9 = 9

Confusion matrix format: Actual (rowClass) predicted as (columnClass) N times
==================================================================
13:27:30.722 [main] INFO com.bolingcavalry.convolution.LeNetMNISTReLu - 完成訓練和測試,耗時[21441]毫秒
13:27:31.323 [main] INFO com.bolingcavalry.convolution.LeNetMNISTReLu - 最新的MINIST模型儲存在[/home/will/temp/202106/26/minist-model.zip]

Process finished with exit code 0
  • 至此,DL4J框架下的GPU加速實戰就完成了,如果您手裡有NVIDIA顯示卡,可以嘗試一下,希望本文能給您一些參考

你不孤單,欣宸原創一路相伴

  1. Java系列
  2. Spring系列
  3. Docker系列
  4. kubernetes系列
  5. 資料庫+中介軟體系列
  6. DevOps系列

歡迎關注公眾號:程式設計師欣宸

微信搜尋「程式設計師欣宸」,我是欣宸,期待與您一同暢遊Java世界...
https://github.com/zq2599/blog_demos