介绍
基于视觉的机器学习推理是一个热门话题,现在边缘计算普遍用于从车辆检测到运动跟踪以及物体识别的一系列应用。

 

由于卷积神经网络的复杂性,实现机器学习推理可能是计算密集型的。这使得使用传统计算架构实现高帧速率具有挑战性。像 Zynq 和 Zynq MPSoC 这样的芯片上的异构系统将高性能 ARM 处理器与可编程逻辑相结合,提供可显着提高性能的解决方案。

 

以前的挑战是创建可编程逻辑实现,该实现易于使用并且可以使用常见的机器学习流程,例如 Caffe 和 TensorFlow。

 

深度神经网络开发套件
为了解决使用通用行业框架并在可编程逻辑中实现加速的需求。Deephi(由 Xilinx 拥有)开发了深度神经网络开发套件(DNNDK)。

 

DNNDK 基于 C / C ++ API,允许我们使用通用的行业标准框架,以及流行的网络,包括 VGG,ResNet,GoogLeNet,YOLO,SSD 和 MobileNet。

 

深度学习处理器单元(DPU)是 DNNDK 的核心,它可以加速深度学习算法。在我们的 Zynq 或 Zynq MPSoC 系统上,DPU 位于可编程逻辑中。为了支持不同的深度学习加速,可以实现几种不同的 DPU 变体。

 

DPU 的结构

 

使用 DNNDK 在 Zynq / Zynq MPSoC 中部署 AI / ML 应用程序的基本阶段是:

压缩神经网络模型  - 采用网络模型(prototext),训练权重(Caffe)并生成使用 INT8 表示的量化模型。为此,通常还需要一个小型输入训练集 - 这包含 100 到 1000 个图像。
编译神经网络模型 - 这将生成 DPU 实例化所需的 ELF 文件。它还将识别 DPU 不支持的网络元素,以便在 CPU 上实现。


使用 DNNDK API 创建程序  - 创建 DPU 内核后,我们现在可以构建管理输入和输出的应用程序,执行 DPU 内核生命周期管理和 DPU 任务管理。在此阶段,我们还需要在 CPU 上实现 DPU 不支持的网络元素。


编译混合 DPU 应用程序 - 一旦应用程序准备就绪,我们就可以运行混合编译器,它将生成 CPU 代码并将其链接到可编程逻辑中的 DPU 的 ELF。


在我们的目标上运行混合 DPU 可执行文件。

 

混合编译


为了执行这五个步骤,DNNDK 提供了几种不同的工具,这些工具在主机和目标之间分开。

 

在主机方面,我们提供以下工具:

 

DECENT  - 深度压缩工具,预先压缩网络模型。
DNNC  - 深度神经网络编译器,执行网络编译。DNNC 有一个子组件 DNNAS - 深度神经网络汇编器,它为 DPU 生成 ELF 文件。


在目标方面:

 

N2Cube  - 这是 DPU 运行时引擎,提供 DNNDK 应用程序的加载,调度和资源分配。N2Cube 的核心组件包括 DPU 驱动程序,DPU 加载程序和 DPU 跟踪程序。
DExplorer  - 在运行时提供 DPU 信息。
DSight  - 分析工具,提供基于 Dtracer 信息的可视化数据。

 

部署


在这个项目中,我们将看看如何在 Ultra96 和 ZCU104 板上启动和运行示例。

 

一旦我们启动并运行,我们将对其中一个示例进行一些简单的修改,以便我们可以看到它从实时视频源运行。

 

配置
在我们看到第一个示例启动并运行之前,我们需要从 Xilinx 网站下载 DNNDK。一旦我们下载 DNNDK,下一步就是提取压缩文件。

 

 

在解压缩的目录中,您将注意到以下目录

  • Common - 包含许多用于分类的图像
  • Host_x86 - 主机开发工具,例如 DECENT 和 DNNC
  • DP-8020 / DP-N1 / ZCU102 / ZCU104 / Ultra96 - 这些是参考命名板的工具链和示例应用程序。


要安装工具链和电路板,我们需要首先从 Xilinx Deephi 网站下载感兴趣的电路板的 linux 映像。

 

下载完这些后,我们可以解压缩图像并将图像写入 SD 卡,用于 Ultra96 或 ZCU104(确保使用正确的图像)。

 

为此,我使用了 Disk Imager 或 Etcher 等程序。

 

 

一旦电路板启动了映像,我们还需要能够在运行时将下载的 DNNDK 示例和工具传输到电路板。

 

为此,我们将使用 MObaXTerm,它允许我们在连接到网络时将信息传输到目标板。

 

MObaXTerm

 

接下来要做的就是设置电路板,这两个过程非常相似,只需稍微改编一下 Ultra96 及其 WIFI 连接即可。

 

设置 ZCU104
我们要检查的第一块板是 ZCU104,一张 SD 卡,图像准备就绪。仔细检查 ZCU104 上的启动模式开关并打开电路板。

 

确保 ZCU104 连接到以太网连接,几秒钟后您将看到启动过程完成。

 

如果在任何时候您被要求输入用户名和密码,则它们都是 root 用户。

 

在 ZCU104/ultra96 上启动的 Linux

 

一旦 Linux 映像启动并运行,首先要确定分配的 IP 地址。我们可以通过输入命令来完成此操作:

ifconfig

 

分配 IP 地址


现在电路板已启动并运行并连接到网络,我们可以使用 mobaXterm 来传输 ZCU 104 的工具和示例。

 

在 mobaXterm 中输入命令:

scp -r /ZCU104 root@<ZCU104 IP address>:~/


这会将文件从开发机器传输到 ZCU104。

传输文件

 

然后,我们可以使用 SSH 或串行终端安装 DNNDK 及其示例。

 

使用终端,您会注意到安装了一个名为 ZCU104 的新目录。在这里,您将看到安装脚本使用该命令安装脚本:

./install.sh

 

安装 DNNDK


这将开始安装过程,如下所示

 

开始安装

 

作为安装过程的一部分,您将看到 Linux 映像重新启动

在 DNNDK 安装期间重新启动 ZCU04 Linux 映像

 

我们现在可以使用为特定板提供的示例应用程序。

 

但是,对于每个示例,我们首先需要编译它,这是通过调用您希望看到的示例中的 make 函数来实现的。

 

 

设置 Ultra96
我们以与 ZCU104 类似的方式设置 Ultra96 但是,我们需要对 WIFI 进行一些调整。

 

一旦初始 Ultra96 映像启动就能安装 DNNDK 工具和应用程序,我们需要先连接到 WIFI。

 

为此,我们需要使用 USB 集线器,它允许我们连接到鼠标和键盘,并将 Mini DisplayPort 输出连接到合适的监视器。

 

打开 Ultra96 电源,您将看到它启动到桌面环境

DNNDK 桌面

 

要连接到 WIFI,请单击菜单,然后选择 Internet-> Wicd Network Manager。这将打开列出所有可用网络的网络管理。

 

可用网络

 

选择所需的一个,然后单击“连接”,如果有加密,则会发出警告并要求输入密码。

 

安全配置

 

输入密码后,单击“确定”,然后单击“连接”。连接到网络可能需要几秒钟。

 

我们可以再次使用 mobaXterm 上传 Ultra96 目录,然后像我们为 ZCU104 那样在板上安装工具和应用程序:

scp -r /Ultra96 root@<Ultra6 IP address>:~/

 

上传 Ultra96 文件


我们再次通过运行命令安装 Ultra96 工具和应用程序:

./install.sh

 

我们现在准备开始与我们的董事会合作。对于本项目的其余部分,我们将重点关注 Ultra96,但使用 ZCU104 是完全相同的。

 

构建和运行示例
我们可以使用 Ultra96 上的鼠标,键盘和终端窗口在 Ultra96 上运行 DNNDK 示例。

 

如上所述,为了运行每个示例,我们首先需要通过在应用程序目录中运行 Make 来实现它。

 

但是,我们可能还想使用其他工具,这些工具随 DNNDK 一起提供。

 

我们可以使用 dexploerer 来获取有关 PL 中包含的核心的信息。输入以下命令将列出:

dexplorer -w.


此命令将显示 PL 中实现的 DPU 的类型类型,我们可以在下面的 ZCU104 和 Ultra96 实现中看到

 

ZCU 104 中的 B4096F DPU

Ultra96 中的 B1152F DPU

 

我们还可以使用 status 命令,它将列出 DPU 的状态:

dexplorer-s

DPU 状态


另一个有趣的命令是 profiling 命令,这将创建分析信息。

 

要开始分析,我们运行命令:

dexplorer -m profile


应用程序完成后,我们可以使用以下命令将配置文件信息转换为 HTML。每个跟踪将具有不同的 PID,具体取决于进程 ID。

dsight -p dpu_trace_[PID].prof


重新运行应用程序示例时,我们还将捕获配置文件信息。

 

运行 ADAS 示例
让我们举个例子来运行 Ultra96 ADAS 示例。要运行它,我们需要使用以下命令:

cd Ultra96/samples/adas_detection
make
dexplorer -m profile
./adas_detection video/adas.avi


这将运行应用程序,卸载元件到可编程逻辑中的 DPU。

 

当我们运行此应用程序时,桌面上会出现一个视频,您将看到在检测到并识别和跟踪汽车的情况下运行的视频


应用程序完成后,我们可以通过使用该命令将其转换为 HTML 来查看配置文件应用程序:

dsight -p dpu_trace_[PID].prof


在运行 ADAS 实现时捕获的配置文件信息上运行此结果将生成下图。

ADAS 检测配置文件信息

 

修改姿势示例以使用实时源
随着应用程序和工具全部在我们的主板上运行,我们可以开始开发自己的应用程序。为此我们有两个选择,一个使用 TensorFlow / Caffe,DECENT 和 DNNC 训练新的网络权重,或者我们可以调整其中一个示例。

 

我们将调整 pose_detection 算法以使用直播流而不是视频。这是一个非常简单的修改,我们可以通过以下更改来实现。

 

更新视频捕获的声明,如下所示:

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 目录中再次编译应用程序:

make
dexplorer -m profile
./pose_detection


在 Ultra96 上运行它并让我的妻子为测试做了一些建模。

 

 


最后要做的是观察个人资料信息

实时馈送姿势检测的配置文件信息

 

结论
该项目有望为 DNNDK 提供一个很好的介绍,以及我们如何轻松地启动和运行它。如果我们愿意,我们可以调整现有的应用程序。

 

如果我们想要训练一个新的网络进行部署,我们将很快在另一个项目中进行检查。

 

如果你对这个项目感兴趣,想获取完整信息请访问:

https://www.hackster.io/adam-taylor/machine-learning-at-the-edge-with-xilinx-dnn-developer-kit-68c672