dusty-nv/jetson-inference 譯
前言
此篇文章僅為在學習過程中順手翻譯,由於本人英文能力甚差,故翻譯可能會較多錯誤或不通順之處,若有還煩請來信告知,感謝!
另外,由於原專案 README.md 中有部分可能因 JetPack 更新或其他因素導致有其他作法或修正,故本人會以 Holey:
來表示當前狀況或額外註解,使翻譯內容盡量與原內容相符。
在本篇之前開始,建議先閱讀 NVIDIA Jetson TX2 環境部署 以進行組件與系統安裝的動作。
安裝 NVIDIA 驅動於本機
在這一節上,JetPack 將會刷新 Jetson 的 L4T BSP,並在 Jetson 與本機上安裝 CUDA 工具包。然而, NVIDIA PCIe 驅動仍需要安裝在主機上才能啟動 GPU 加速訓練。從主機執行以下命令以從 Ubuntu repo 安裝 NIVDIA 驅動程式:
1 | sudo apt-get install nvidia-375 |
重新開機之後,NVIDIA 驅動程式應該將會列表在 lsmod
下:
1 | lsmod | grep nvidia |
若要驗證 CUDA 工具包以及 NVIDIA 驅動程式是否能運作,可以執行 CUDA 所提供的一些測試樣本:
1 | cd /usr/local/cuda/samples |
安裝 cuDNN 於本機
下一個步驟是安裝 NVIDIA cuDNN 函式庫於本機上。從 NVIDIA 網站下載 libcudnn 與 libcudnn 組件:
1 | https://developer.nvidia.com/compute/machine-learning/cudnn/secure/v6/prod/8.0_20170307/Ubuntu16_04_x64/libcudnn6_6.0.20-1+cuda8.0_amd64-deb |
接著執行以下命令以安裝這些組件:
1 | sudo dpkg -i libcudnn6_6.0.20-1+cuda8.0_amd64.deb |
安裝 NVcaffe 於本機
NVcaffe 是 Caffe 的 NVIDIA 分支,且針對 GPU 進行了優化。NVcaffe 使用 cuDNN 並用於訓練 DNNs。為了安裝它,需要先從 Github 上 Clone NVcaffe repo 並編譯來源,以下使用 NVcaffe-0.15。
note: 對於本節,NVcaffe 只需要在主機上(用於訓練),在推理(inferencing)階段,Jetson 使用 TensorRT 而不需要 caffe。
在安裝 Caffe 之前需要先安裝一些必要組件,包括 DIGITS 所需要的 Python 連結(Python bindings):
1 | sudo apt-get install --no-install-recommends build-essential cmake git gfortran libatlas-base-dev libboost-filesystem-dev libboost-python-dev libboost-system-dev libboost-thread-dev libgflags-dev libgoogle-glog-dev libhdf5-serial-dev libleveldb-dev liblmdb-dev libprotobuf-dev libsnappy-dev protobuf-compiler python-all-dev python-dev python-h5py python-matplotlib python-numpy python-opencv python-pil python-pip python-protobuf python-scipy python-skimage python-sklearn python-setuptools |
至此,Caffe 應可被配置與建構。現在編輯用戶下的 ~/.bashrc
來引入 Caffe tree 的路徑(記得替換路徑為自己的):
1 | export CAFFE_ROOT=/home/dusty/workspace/caffe |
接著關閉並重新開啟終端機(Terminal)來讓變更生效。
安裝 DIGITS 於本機
NVIDIA DIGITS 是基於 Python 的 Web 服務,可以交互式訓練 DNNs 並管理資料檔案。在 DIGITS 的工作流程中,它在主機上執行並在訓練階段時建立網路模型,接著將受過訓練的模型從主機複製到 Jetson,以用於運行 TensorRT 的推理階段。
在安裝 DIGITS 之前先安裝需要的組件,接著再從 Github Clone DIGITS repo:
1 | sudo apt-get install --no-install-recommends graphviz python-dev python-flask python-flaskext.wtf python-gevent python-h5py python-numpy python-pil python-pip python-protobuf python-scipy python-tk |
啟動 DIGITS 伺服器
假設你的終端機仍然在 DIGITS 目錄中,則可以通過執行 digits-devserver 的 Python 腳本來啟動 Web 伺服器:
1 | ./digits-devserver |
DIGITS 將會儲存使用者的工作(訓練資料檔案和模型快照)在 digits\jobs
資料夾下。
開啟瀏覽器並進入 0.0.0.0:5000
可以訪問交互式 DIGITS 對話。
note: DIGITS 伺服器預設為使用 port 5000,若要修改可在使用
digits-devserver
腳本時加入--port
參數來自定義。
Building from Source on Jetson
Provided along with this repo are TensorRT-enabled deep learning primitives for running Googlenet/Alexnet on live camera feed for image recognition, pedestrian detection networks with localization capabilities (i.e. that provide bounding boxes), and segmentation. This repo is intended to be built & run on the Jetson and to accept the network models from the host PC trained on the DIGITS server.
最新的版本可以在 Github 上取得並在 Jetson TX1/TX2 上編譯。
note: 這個分支是針對以下 BSP 版本進行驗證:
- Jetson TX2 - JetPack 3.0 / L4T R27.1 aarch64 (Ubuntu 16.04 LTS)
- Jetson TX1 - JetPack 2.3 / L4T R24.2 aarch64 (Ubuntu 16.04 LTS)
- Jetson TX1 - JetPack 2.3.1 / L4T R24.2.1 aarch64 (Ubuntu 16.04 LTS)
Clone the Repo
在取得這個 repository 之前,先確定選擇的資料夾是 Jetson。首先,確認 git 和 cmake 在本機是已經安裝的:
1 | sudo apt-get install git cmake |
Holey: 若出現問題建議可先
sudo apt-get update
再次嘗試安裝
接著 Clone jetson-inference 的 repo:
1 | git clone http://github.com/dusty-nv/jetson-inference |
配置 CMake
當 cmake 已在運作,可以運行一個特別的安裝腳本(CMakePreBuild.sh)來自動安裝任何相依項(dependencies)。
1 | cd jetson-inference |
note: cmake 命令在啟動 CMakePrebuild.sh 腳本時將會要求 sudo 以確保先決條件組件已安裝在 Jetson 上。該腳本也會從 Web 服務下載網路模型快照。
編譯專案
請先確認資料夾仍然在 jetson-inference/build
,若是則直接執行第二項命令:
1 | cd jetson-inference/build # omit if pwd is already /build from above |
根據不同的架構,組件將會被構建為 armhf
或 aarch64
,並具有以下目錄結構:
1 | |-build |
位於 aarch64/bin
的二進制文件,其標頭在 aarch64/include
,函式庫則在aarch64/lib
。
Digging Into the Code (這段不翻)
For reference, see the available vision primitives, including imageNet for image recognition and detectNet for object localization.
1 | /* |
Both inherit from the shared tensorNet
object which contains common TensorRT code.
以 ImageNet 進行圖片分類
有多種類型的深度學習網路可使用,包括識別、擷取/局部和立即分割。在本節中強調的第一個深度學習能力是使用已被訓練用來識別類似對象的 imageNet
的圖片識別。
imageNet
接受輸入圖片並輸出每個類別的相似度,目前已經有 1000 個對象在 ImageNet 數據庫上進行過訓練。而標準的 AlexNet 和 GoogleNet 網路已經在上面的步驟 2 中下載。而我們提供一個名為 imagenet-console
的命令列介面和一個名為 imagenet-camera
的即時相機程式作為使用 imageNet
的示例。
使用 Console Program 於 Jetson 上
首先,試著使用 imagenet-console
程式在一些測試圖片上測試 imageNet
識別。它會讀取圖片,使用 TensorRT 和 imageNet
類來執行推理,接著在圖片上印上分類並儲存輸出的圖片。
在 building 之後,先確認你的終端機在 aarch64/bin
資料夾下:
1 | cd jetson-inference/build/aarch64/bin |
接著就可以利用 imagenet-console
來分類測試圖片。imagenet-console
接收兩個命令列參數:輸入圖片的路徑和輸出圖片(印上分類)的路徑。
1 | ./imagenet-console orange_0.jpg output_0.jpg |
1 | ./imagenet-console granny_smith_1.jpg output_1.jpg |
接著,我們將使用 imageNet
來分類來自 Jetson 上的相機所得到的即時影像。
進行即時相機識別演示
與上一個例子類似,即時圖片識別演示(realtime image recognition demo)位於 arrch64/bin
中,稱為 imagenet-camera
。它在即時相機串流(live camera stream)上執行且根據使用者給予的參數,以 TensorRT 加載 googlenet
或 alexnet
。
1 | ./imagenet-camera googlenet # to run using googlenet |
幀率(Frame per Second,FPS)、物件類別名稱和相似度將會印於 openGL 視窗的標題列。在預設情況下,程式可以識別多達 1000 種不同類型的物件,這是因為 Googlenet 和 Alexnet 在 ILSVRXC12 ImageNet 資料庫上進行了訓練,而該資料庫包含 1000 種物件。這 1000 種物件類型的名稱可以在 repo 中的 data/networks/ilsvrc12_synset_words.txt
找到。
note: 預設情況下,Jetson 開發版所搭載的 CSI 視訊鏡頭將會被用做視訊源,如果你希望使用 USB 攝影機,請更改
imagenet-camera.cpp
頂部的DEFAULT_CAMERA
定義,以對應在/dev/video
V4L2 裝置中你的 USB 攝影機。在下方測試中使用的設備型號是 Logitech C920。
Holey: 目前在 openGL 視窗上,標題列僅會顯示 FPS,而物件類別名稱和相似度將會直接印於視窗上。
利用 DIGITS 重新訓練網路
從 repo 所下載的現有 GoogleNet 與 AlexNet 模型是由 ImageNet ILSVRC23 基準測試所預先訓練的 1000 種物件類別。
若要識別一個新的物件類別,可以使用 DIGITS 來重新對網路進行新的數據訓練。你還可以將現有的物件類別以不同的方式組織,包括將多個子類別組合成一個子類別。例如,在本教學中,我們將使用 1000 個類別中的 230 個,將它們分組到 12 個類別中並重新訓練網路。
讓我們先從下載 ILSVRC12 圖片開始,或者將自己的數據集替換進圖片資料夾。
下載圖片識別數據集
圖像識別數據集是由大量按其分類類型(通常按目錄)排序的圖片所組成。ILSVRC12 數據集是用於訓練預設的 GoogleNet 和 AlexNet 模型,它的大小約為 100GB,包括 1000 多種不同的類別的 100 萬張圖片。數據集將會使用 imagenet-download.py
圖片爬蟲來下載到 DIGITS 伺服器。
為了下載數據集,首先必須確定你的 DIGITS 伺服器有足夠的硬碟空間(建議為 120GB),接著在你希望儲存數據集的伺服器資料夾上執行以下命令:
1 | wget --no-check-certificate https://nvidia.box.com/shared/static/gzr5iewf5aouhc5exhp3higw6lzhcysj.gz -O ilsvrc12_urls.tar.gz |
在上面的命令中,在啟動爬蟲程序之前會先下載圖片 URL 清單以及腳本。
note: 由公司網路執行圖片爬蟲時需要注意 IT 可能會標記這項動作。It will probably take overnight on a decent connection to download the 1000 ILSVRC12 classes (100GB).
爬蟲將會下載圖片至其對應的分類子目錄中。每個圖片類別都儲存在自己的目錄中,共有 1000 個目錄(ILSVRC12 中的每個類別各一個)。資料夾的命名方式類似於:
1 | n01440764/ |
這些資料夾的 8 位數字 ID 被稱為類別的 synset ID,該類別的名稱字串可以在 ilsvrc12_synset_words.txt
查詢。例如:synset n01484850 great white shark
。
自訂物件類別
我們在上一步中下載的數據集,用來自不同核心類群的 1000 個物件類別來訓練預設的 AlexNet 與 GoogleNet 模型,包括不同種類的鳥、植物、水果、魚、狗、貓、車輛類型等。為了實現目的,我們可以考慮 GoogleNet 的伴隨模型,該模型識別了由原始的 1000 個類別所組成的十幾個核心類群(例如將 122 種不同品種的狗全部組合為一個普通的狗類型)。這 12 個核心類群可能比 1000 個單獨的 synsets 更加實用,且跨類別的組合可以獲得更多的訓練數據和更強的群體分類。
DIGITS 會從資料夾結構來取得數據,因此我們可以建立群組目錄,然後象徵性地連接到上面所下載的 ILSVRC12 的 synsets。DIGITS 將自動組合根目錄下所有資料夾中的圖片。目錄結構類似於下面的內容,括號中的值表示用於組成群組的類型數量,箭頭旁邊的值為指示連結到的 synset ID。
1 | ‣ ball/ (7) |
既然實際上有很多從 ILSVRC12 連結到的 synsets,我們提供了 imagenet-subset.sh
腳本,以生成目錄結構和指定給數據集的路徑連結,從 DIGITS 伺服器執行以下命令:
1 | wget https://rawgit.com/dusty-nv/jetson-inference/master/tools/imagenet-subset.sh |
在這個範例中,連結將會建立在 12_classed 資料夾中,而腳本的第一個參數則是上一步下載的 ILSVRC12 路徑。