介紹
基于視覺(jué)的機(jī)器學(xué)習(xí)推理是一個(gè)熱門(mén)話題,現(xiàn)在邊緣計(jì)算普遍用于從車輛檢測(cè)到運(yùn)動(dòng)跟蹤以及物體識(shí)別的一系列應(yīng)用。
由于卷積神經(jīng)網(wǎng)絡(luò)的復(fù)雜性,實(shí)現(xiàn)機(jī)器學(xué)習(xí)推理可能是計(jì)算密集型的。這使得使用傳統(tǒng)計(jì)算架構(gòu)實(shí)現(xiàn)高幀速率具有挑戰(zhàn)性。像 Zynq 和 Zynq MPSoC 這樣的芯片上的異構(gòu)系統(tǒng)將高性能 ARM 處理器與可編程邏輯相結(jié)合,提供可顯著提高性能的解決方案。
以前的挑戰(zhàn)是創(chuàng)建可編程邏輯實(shí)現(xiàn),該實(shí)現(xiàn)易于使用并且可以使用常見(jiàn)的機(jī)器學(xué)習(xí)流程,例如 Caffe 和 TensorFlow。
深度神經(jīng)網(wǎng)絡(luò)開(kāi)發(fā)套件
為了解決使用通用行業(yè)框架并在可編程邏輯中實(shí)現(xiàn)加速的需求。Deephi(由 Xilinx 擁有)開(kāi)發(fā)了深度神經(jīng)網(wǎng)絡(luò)開(kāi)發(fā)套件(DNNDK)。
DNNDK 基于 C / C ++ API,允許我們使用通用的行業(yè)標(biāo)準(zhǔn)框架,以及流行的網(wǎng)絡(luò),包括 VGG,ResNet,GoogLeNet,YOLO,SSD 和 MobileNet。
深度學(xué)習(xí)處理器單元(DPU)是 DNNDK 的核心,它可以加速深度學(xué)習(xí)算法。在我們的 Zynq 或 Zynq MPSoC 系統(tǒng)上,DPU 位于可編程邏輯中。為了支持不同的深度學(xué)習(xí)加速,可以實(shí)現(xiàn)幾種不同的 DPU 變體。
DPU 的結(jié)構(gòu)
使用 DNNDK 在 Zynq / Zynq MPSoC 中部署 AI / ML 應(yīng)用程序的基本階段是:
壓縮神經(jīng)網(wǎng)絡(luò)模型? - 采用網(wǎng)絡(luò)模型(prototext),訓(xùn)練權(quán)重(Caffe)并生成使用 INT8 表示的量化模型。為此,通常還需要一個(gè)小型輸入訓(xùn)練集 - 這包含 100 到 1000 個(gè)圖像。
編譯神經(jīng)網(wǎng)絡(luò)模型?- 這將生成 DPU 實(shí)例化所需的 ELF 文件。它還將識(shí)別 DPU 不支持的網(wǎng)絡(luò)元素,以便在 CPU 上實(shí)現(xiàn)。
使用 DNNDK API 創(chuàng)建程序? - 創(chuàng)建 DPU 內(nèi)核后,我們現(xiàn)在可以構(gòu)建管理輸入和輸出的應(yīng)用程序,執(zhí)行 DPU 內(nèi)核生命周期管理和 DPU 任務(wù)管理。在此階段,我們還需要在 CPU 上實(shí)現(xiàn) DPU 不支持的網(wǎng)絡(luò)元素。
編譯混合 DPU 應(yīng)用程序?- 一旦應(yīng)用程序準(zhǔn)備就緒,我們就可以運(yùn)行混合編譯器,它將生成 CPU 代碼并將其鏈接到可編程邏輯中的 DPU 的 ELF。
在我們的目標(biāo)上運(yùn)行混合 DPU 可執(zhí)行文件。
混合編譯
為了執(zhí)行這五個(gè)步驟,DNNDK 提供了幾種不同的工具,這些工具在主機(jī)和目標(biāo)之間分開(kāi)。
在主機(jī)方面,我們提供以下工具:
DECENT? - 深度壓縮工具,預(yù)先壓縮網(wǎng)絡(luò)模型。
DNNC ?- 深度神經(jīng)網(wǎng)絡(luò)編譯器,執(zhí)行網(wǎng)絡(luò)編譯。DNNC 有一個(gè)子組件 DNNAS - 深度神經(jīng)網(wǎng)絡(luò)匯編器,它為 DPU 生成 ELF 文件。
在目標(biāo)方面:
N2Cube ?- 這是 DPU 運(yùn)行時(shí)引擎,提供 DNNDK 應(yīng)用程序的加載,調(diào)度和資源分配。N2Cube 的核心組件包括 DPU 驅(qū)動(dòng)程序,DPU 加載程序和 DPU 跟蹤程序。
DExplorer ?- 在運(yùn)行時(shí)提供 DPU 信息。
DSight ?- 分析工具,提供基于 Dtracer 信息的可視化數(shù)據(jù)。
部署
在這個(gè)項(xiàng)目中,我們將看看如何在 Ultra96 和 ZCU104 板上啟動(dòng)和運(yùn)行示例。
一旦我們啟動(dòng)并運(yùn)行,我們將對(duì)其中一個(gè)示例進(jìn)行一些簡(jiǎn)單的修改,以便我們可以看到它從實(shí)時(shí)視頻源運(yùn)行。
配置
在我們看到第一個(gè)示例啟動(dòng)并運(yùn)行之前,我們需要從 Xilinx 網(wǎng)站下載 DNNDK。一旦我們下載 DNNDK,下一步就是提取壓縮文件。
在解壓縮的目錄中,您將注意到以下目錄
- Common - 包含許多用于分類的圖像
- Host_x86 - 主機(jī)開(kāi)發(fā)工具,例如 DECENT 和 DNNC
- DP-8020 / DP-N1 / ZCU102 / ZCU104 / Ultra96 - 這些是參考命名板的工具鏈和示例應(yīng)用程序。
要安裝工具鏈和電路板,我們需要首先從 Xilinx Deephi 網(wǎng)站下載感興趣的電路板的 linux 映像。
下載完這些后,我們可以解壓縮圖像并將圖像寫(xiě)入 SD 卡,用于 Ultra96 或 ZCU104(確保使用正確的圖像)。
為此,我使用了 Disk Imager 或 Etcher 等程序。
一旦電路板啟動(dòng)了映像,我們還需要能夠在運(yùn)行時(shí)將下載的 DNNDK 示例和工具傳輸?shù)诫娐钒濉?/p>
為此,我們將使用 MObaXTerm,它允許我們?cè)谶B接到網(wǎng)絡(luò)時(shí)將信息傳輸?shù)侥繕?biāo)板。
MObaXTerm
?
接下來(lái)要做的就是設(shè)置電路板,這兩個(gè)過(guò)程非常相似,只需稍微改編一下 Ultra96 及其 WIFI 連接即可。
設(shè)置 ZCU104
我們要檢查的第一塊板是 ZCU104,一張 SD 卡,圖像準(zhǔn)備就緒。仔細(xì)檢查 ZCU104 上的啟動(dòng)模式開(kāi)關(guān)并打開(kāi)電路板。
確保 ZCU104 連接到以太網(wǎng)連接,幾秒鐘后您將看到啟動(dòng)過(guò)程完成。
如果在任何時(shí)候您被要求輸入用戶名和密碼,則它們都是 root 用戶。
在 ZCU104/ultra96 上啟動(dòng)的 Linux
一旦 Linux 映像啟動(dòng)并運(yùn)行,首先要確定分配的 IP 地址。我們可以通過(guò)輸入命令來(lái)完成此操作:
ifconfig
分配 IP 地址
現(xiàn)在電路板已啟動(dòng)并運(yùn)行并連接到網(wǎng)絡(luò),我們可以使用 mobaXterm 來(lái)傳輸 ZCU 104 的工具和示例。
在 mobaXterm 中輸入命令:
scp -r /ZCU104 root@<ZCU104 IP address>:~/
這會(huì)將文件從開(kāi)發(fā)機(jī)器傳輸?shù)?ZCU104。
傳輸文件
然后,我們可以使用 SSH 或串行終端安裝 DNNDK 及其示例。
使用終端,您會(huì)注意到安裝了一個(gè)名為 ZCU104 的新目錄。在這里,您將看到安裝腳本使用該命令安裝腳本:
./install.sh
安裝 DNNDK
這將開(kāi)始安裝過(guò)程,如下所示
開(kāi)始安裝
作為安裝過(guò)程的一部分,您將看到 Linux 映像重新啟動(dòng)
在 DNNDK 安裝期間重新啟動(dòng) ZCU04 Linux 映像
我們現(xiàn)在可以使用為特定板提供的示例應(yīng)用程序。
但是,對(duì)于每個(gè)示例,我們首先需要編譯它,這是通過(guò)調(diào)用您希望看到的示例中的 make 函數(shù)來(lái)實(shí)現(xiàn)的。
設(shè)置 Ultra96
我們以與 ZCU104 類似的方式設(shè)置 Ultra96 但是,我們需要對(duì) WIFI 進(jìn)行一些調(diào)整。
一旦初始 Ultra96 映像啟動(dòng)就能安裝 DNNDK 工具和應(yīng)用程序,我們需要先連接到 WIFI。
為此,我們需要使用 USB 集線器,它允許我們連接到鼠標(biāo)和鍵盤(pán),并將 Mini DisplayPort 輸出連接到合適的監(jiān)視器。
打開(kāi) Ultra96 電源,您將看到它啟動(dòng)到桌面環(huán)境
DNNDK 桌面
要連接到 WIFI,請(qǐng)單擊菜單,然后選擇 Internet-> Wicd Network Manager。這將打開(kāi)列出所有可用網(wǎng)絡(luò)的網(wǎng)絡(luò)管理。
可用網(wǎng)絡(luò)
選擇所需的一個(gè),然后單擊“連接”,如果有加密,則會(huì)發(fā)出警告并要求輸入密碼。
安全配置
輸入密碼后,單擊“確定”,然后單擊“連接”。連接到網(wǎng)絡(luò)可能需要幾秒鐘。
我們可以再次使用 mobaXterm 上傳 Ultra96 目錄,然后像我們?yōu)?ZCU104 那樣在板上安裝工具和應(yīng)用程序:
scp -r /Ultra96 root@<Ultra6 IP address>:~/
上傳 Ultra96 文件
我們?cè)俅瓮ㄟ^(guò)運(yùn)行命令安裝 Ultra96 工具和應(yīng)用程序:
./install.sh
我們現(xiàn)在準(zhǔn)備開(kāi)始與我們的董事會(huì)合作。對(duì)于本項(xiàng)目的其余部分,我們將重點(diǎn)關(guān)注 Ultra96,但使用 ZCU104 是完全相同的。
構(gòu)建和運(yùn)行示例
我們可以使用 Ultra96 上的鼠標(biāo),鍵盤(pán)和終端窗口在 Ultra96 上運(yùn)行 DNNDK 示例。
如上所述,為了運(yùn)行每個(gè)示例,我們首先需要通過(guò)在應(yīng)用程序目錄中運(yùn)行 Make 來(lái)實(shí)現(xiàn)它。
但是,我們可能還想使用其他工具,這些工具隨 DNNDK 一起提供。
我們可以使用 dexploerer 來(lái)獲取有關(guān) PL 中包含的核心的信息。輸入以下命令將列出:
dexplorer -w.
此命令將顯示 PL 中實(shí)現(xiàn)的 DPU 的類型類型,我們可以在下面的 ZCU104 和 Ultra96 實(shí)現(xiàn)中看到
ZCU 104 中的 B4096F DPU
Ultra96 中的 B1152F DPU
?
我們還可以使用 status 命令,它將列出 DPU 的狀態(tài):
dexplorer-s
DPU 狀態(tài)
另一個(gè)有趣的命令是 profiling 命令,這將創(chuàng)建分析信息。
要開(kāi)始分析,我們運(yùn)行命令:
dexplorer -m profile
應(yīng)用程序完成后,我們可以使用以下命令將配置文件信息轉(zhuǎn)換為 HTML。每個(gè)跟蹤將具有不同的 PID,具體取決于進(jìn)程 ID。
dsight -p dpu_trace_[PID].prof
重新運(yùn)行應(yīng)用程序示例時(shí),我們還將捕獲配置文件信息。
運(yùn)行 ADAS 示例
讓我們舉個(gè)例子來(lái)運(yùn)行 Ultra96 ADAS 示例。要運(yùn)行它,我們需要使用以下命令:
cd Ultra96/samples/adas_detection
make
dexplorer -m profile
./adas_detection video/adas.avi
這將運(yùn)行應(yīng)用程序,卸載元件到可編程邏輯中的 DPU。
當(dāng)我們運(yùn)行此應(yīng)用程序時(shí),桌面上會(huì)出現(xiàn)一個(gè)視頻,您將看到在檢測(cè)到并識(shí)別和跟蹤汽車的情況下運(yùn)行的視頻
應(yīng)用程序完成后,我們可以通過(guò)使用該命令將其轉(zhuǎn)換為 HTML 來(lái)查看配置文件應(yīng)用程序:
dsight -p dpu_trace_[PID].prof
在運(yùn)行 ADAS 實(shí)現(xiàn)時(shí)捕獲的配置文件信息上運(yùn)行此結(jié)果將生成下圖。
ADAS 檢測(cè)配置文件信息
修改姿勢(shì)示例以使用實(shí)時(shí)源
隨著應(yīng)用程序和工具全部在我們的主板上運(yùn)行,我們可以開(kāi)始開(kāi)發(fā)自己的應(yīng)用程序。為此我們有兩個(gè)選擇,一個(gè)使用 TensorFlow / Caffe,DECENT 和 DNNC 訓(xùn)練新的網(wǎng)絡(luò)權(quán)重,或者我們可以調(diào)整其中一個(gè)示例。
我們將調(diào)整 pose_detection 算法以使用直播流而不是視頻。這是一個(gè)非常簡(jiǎn)單的修改,我們可以通過(guò)以下更改來(lái)實(shí)現(xiàn)。
更新視頻捕獲的聲明,如下所示:
VideoCapture cap(0);
修改主要功能如下:
int main(int argc, char **argv) {
?? // Attach to DPU driver and prepare for running
?? dpuOpen();
?? if (!cap.isOpened()) {
????? return -1;
?? }
cap.set(CV_CAP_PROP_FRAME_WIDTH,640);
cap.set(CV_CAP_PROP_FRAME_HEIGHT,320);
?? // Run tasks for SSD
?? array<thread, 4> threads = {thread(Read, ref(is_reading)),
?????????????????????????????? thread(runGestureDetect, ref(is_running_1)),
?????????????????????????????? thread(runGestureDetect, ref(is_running_1)),
?????????????????????????????? thread(Display, ref(is_displaying))};
?? for (int i = 0; i < 4; ++i) {
?????? threads[i].join();
?? }
?? // Detach from DPU driver and release resources
?? dpuClose();
?? cap.release();
?? return 0;
}
?
修改 Read 功能,如下所示:
void Read(bool &is_reading) {
?? while (is_reading) {
?????? Mat img;
?????? if (read_queue.size() < 30) {
?????????? if (!cap.read(img)) {
?????????????? cout << "Finish reading the video." << endl;
?????????????? is_reading = false;
?????????????? break;
?????????? }
?????????? mtx_read_queue.lock();
?????????? read_queue.push(make_pair(read_index++, img));
?????????? mtx_read_queue.unlock();
?????? } else {
?????????? usleep(20);
?????? }
?? }
}
然后我們可以使用 pose 命令在 pose_detection 目錄中再次編譯應(yīng)用程序:
make
dexplorer -m profile
./pose_detection
在 Ultra96 上運(yùn)行它并讓我的妻子為測(cè)試做了一些建模。
最后要做的是觀察個(gè)人資料信息
實(shí)時(shí)饋送姿勢(shì)檢測(cè)的配置文件信息
結(jié)論
該項(xiàng)目有望為 DNNDK 提供一個(gè)很好的介紹,以及我們?nèi)绾屋p松地啟動(dòng)和運(yùn)行它。如果我們?cè)敢猓覀兛梢哉{(diào)整現(xiàn)有的應(yīng)用程序。
如果我們想要訓(xùn)練一個(gè)新的網(wǎng)絡(luò)進(jìn)行部署,我們將很快在另一個(gè)項(xiàng)目中進(jìn)行檢查。
如果你對(duì)這個(gè)項(xiàng)目感興趣,想獲取完整信息請(qǐng)?jiān)L問(wèn):