Main Content

本页翻译不是最新的。点击此处可查看最新英文版本。

ARM 目标上的深度学习代码生成

此示例说明如何在不使用硬件支持包的情况下,在基于 ARM® 的设备上为预测生成和部署代码。

当您使用 ARM Compute Library 和硬件支持包为预测生成代码时,codegen 会在主机上生成代码,将生成的文件复制到目标硬件,并在目标硬件上编译可执行文件。在没有硬件支持包的情况下,codegen 会在主机上生成代码。您必须运行命令来复制文件并在目标硬件上编译可执行程序。

此示例使用 packNGo 函数将所有相关文件打包到一个压缩的 zip 文件中。使用此示例了解如何使用 packNGo 在没有硬件支持包的 ARM Neon 目标上部署生成的代码。

前提条件

  • 支持 NEON 扩展的 ARM 处理器

  • ARM Compute Library(在目标 ARM 硬件上)

  • 开源计算机视觉库 (Open CV)

  • 编译器和库的环境变量。

  • MATLAB® Coder™

  • MATLAB Coder Interface for Deep Learning 支持包

  • Deep Learning Toolbox™

此示例使用的 ARM Compute Library 版本可能不是代码生成支持的最新版本。有关受支持的库版本和有关设置环境变量的信息,请参阅 使用 MATLAB Coder 进行深度学习的前提条件 (MATLAB Coder)

MATLAB Online 不支持此示例。

squeezenet_predict 函数

此示例通过 ARM Compute Library 使用 DAG 网络 SqueezeNet 显示图像分类。Deep Learning Toolbox 中提供了针对 MATLAB 的预训练 SqueezeNet。squeezenet_predict 函数将 SqueezeNet 网络加载到一个持久性网络对象中。在对该函数的后续调用中,将重复使用该持久性对象。

type squeezenet_predict
% Copyright 2018 The MathWorks, Inc.

function out = squeezenet_predict(in) 
%#codegen

% A persistent object mynet is used to load the DAG network object.
% At the first call to this function, the persistent object is constructed and
% set up. When the function is called subsequent times, the same object is reused 
% to call predict on inputs, avoiding reconstructing and reloading the
% network object.

persistent mynet;
if isempty(mynet)
       mynet = coder.loadDeepLearningNetwork('squeezenet','squeezenet');
end

out = mynet.predict(in);

为静态库设置代码生成配置对象

当您针对基于 ARM 的设备生成代码并且不使用硬件支持包时,请为库创建一个配置对象。不要为可执行程序创建配置对象。

为生成 C++ 代码和仅生成代码设置配置对象。

cfg = coder.config('lib');
cfg.TargetLang = 'C++';
cfg.GenCodeOnly = true;

为深度学习代码生成设置配置对象

创建一个 coder.ARMNEONConfig 对象。指定目标 ARM 处理器的库版本和架构。例如,假设目标板是具有 ARMv8 架构和 ARM Compute Library 20.02.1 版本的 HiKey/Rock960 板。

dlcfg = coder.DeepLearningConfig('arm-compute');
dlcfg.ArmComputeVersion = '20.02.1';
dlcfg.ArmArchitecture = 'armv8';

将深度学习配置对象连接到代码生成配置对象

将代码生成配置对象的 DeepLearningConfig 属性设置为深度学习配置对象。

cfg.DeepLearningConfig = dlcfg;

使用 codegen 生成 C++ 源代码

codegen -config cfg squeezenet_predict -args {ones(227, 227, 3, 'single')} -d arm_compute

代码在主机上当前工作文件夹的 arm_compute 文件夹中生成。

使用 packNGo 函数生成 Zip 文件

packNGo 函数将所有相关文件打包到一个压缩的 zip 文件中。

zipFileName = 'arm_compute.zip';
bInfo = load(fullfile('arm_compute','buildInfo.mat'));
packNGo(bInfo.buildInfo, {'fileName', zipFileName,'minimalHeaders', false, 'ignoreFileMissing',true});

代码生成为 zip 文件。

将生成的 Zip 文件复制到目标硬件

复制该 Zip 文件并提取到文件夹中,然后在硬件中删除 Zip 文件

在以下命令中,进行以下替换:

  • password 替换为您的密码

  • username 替换为您的用户名

  • targetname 替换为您设备的名称

  • targetloc 替换为文件的目标文件夹

执行以下步骤以从 Linux 复制和提取 zip 文件。

if isunix, system(['sshpass -p password scp -r '  fullfile(pwd,zipFileName) ' username@targetname:targetloc/']), end
if isunix, system('sshpass -p password ssh username@targetname "if [ -d targetloc/arm_compute ]; then rm -rf targetloc/arm_compute; fi"'), end
if isunix, system(['sshpass -p password ssh username@targetname "unzip targetloc/' zipFileName ' -d targetloc/arm_compute"']), end
if isunix, system(['sshpass -p password ssh username@targetname "rm -rf  targetloc' zipFileName '"']), end

执行以下步骤以从 Windows 复制和提取 zip 文件。

if ispc, system(['pscp.exe -pw password -r '  fullfile(pwd,zipFileName) ' username@targetname:targetloc/']), end
if ispc, system('plink.exe -l username -pw password targetname "if [ -d targetloc/arm_compute ]; then rm -rf targetloc/arm_compute; fi"'), end
if ispc, system(['plink.exe -l username -pw password targetname "unzip targetloc/' zipFileName ' -d targetloc/arm_compute"']), end
if ispc, system(['plink.exe -l username -pw password targetname "rm -rf  targetloc' zipFileName '"']), end

将示例文件复制到目标硬件

将下列支持文件从主机复制到目标硬件:

  • 输入图像,coffeemug.png

  • 用于生成库的联编文件,squeezenet_predict_rtw.mk

  • 用于编译可执行程序的联编文件,makefile_squeezenet_arm_generic.mk

  • Synset 字典,synsetWords.txt

在以下命令中,进行以下替换:

  • password 替换为您的密码

  • username 替换为您的用户名

  • targetname 替换为您设备的名称

  • targetloc 替换为文件的目标文件夹

从 Linux 运行时,执行以下步骤以复制所有必需的文件

if isunix, system('sshpass -p password scp squeezenet_predict_rtw.mk username@targetname:targetloc/arm_compute/'), end
if isunix, system('sshpass -p password scp coffeemug.png username@targetname:targetloc/arm_compute/'), end
if isunix, system('sshpass -p password scp makefile_squeezenet_arm_generic.mk username@targetname:targetloc/arm_compute/'), end
if isunix, system('sshpass -p password scp synsetWords.txt username@targetname:targetloc/arm_compute/'), end

从 Windows 运行时,执行以下步骤以复制所有必需的文件

if ispc, system('pscp.exe -pw password squeezenet_predict_rtw.mk username@targetname:targetloc/arm_compute/'), end
if ispc, system('pscp.exe -pw password coffeemug.png username@targetname:targetloc/arm_compute/'), end
if ispc, system('pscp.exe -pw password makefile_squeezenet_arm_generic.mk username@targetname:targetloc/arm_compute/'), end
if ispc, system('pscp.exe -pw password synsetWords.txt username@targetname:targetloc/arm_compute/'), end

在目标硬件上编译库

要在目标硬件上编译库,请在 ARM 硬件上执行生成的联编文件。

确保您在目标硬件上设置环境变量 ARM_COMPUTELIB 和 LD_LIBRARY_PATH。请参阅使用 MATLAB Coder 进行深度学习的前提条件 (MATLAB Coder)。在联编文件中使用 ARM_ARCH 变量来基于 Arm 架构传递编译器标志。在联编文件中使用 ARM_VER 变量来基于 Arm Compute 版本编译代码。按照与上述步骤类似的方式更换硬件凭据和路径。

执行以下步骤从 Linux 编译库。

if isunix, system('sshpass -p password scp main_squeezenet_arm_generic.cpp username@targetname:targetloc/arm_compute/'), end
if isunix, system(['sshpass -p password ssh username@targetname "make -C targetloc/arm_compute/ -f squeezenet_predict_rtw.mk ARM_ARCH=' dlcfg.ArmArchitecture ' ARM_VER=' dlcfg.ArmComputeVersion ' "']), end

执行以下步骤从 Windows 编译库。

if ispc, system('pscp.exe -pw password main_squeezenet_arm_generic.cpp username@targetname:targetloc/arm_compute/'), end
if ispc, system(['plink.exe -l username -pw password targetname "make -C targetloc/arm_compute/ -f squeezenet_predict_rtw.mk ARM_ARCH=' dlcfg.ArmArchitecture ' ARM_VER=' dlcfg.ArmComputeVersion ' "']), end

从目标硬件上的库中创建可执行文件

用源主包装文件编译库来创建可执行文件。main_squeezenet_arm_generic.cpp 是 C++ 主包装文件,它调用 squeezenet_predict 函数来创建可执行文件。

运行以下命令以从 Linux 创建可执行文件。

if isunix, system('sshpass -p password ssh username@targetname "make -C targetloc/arm_compute/ -f makefile_squeezenet_arm_generic.mk targetDirName=targetloc/arm_compute"'), end

运行以下命令以从 Windows 创建可执行文件。

if ispc, system('plink.exe -l username -pw password targetname "make -C targetloc/arm_compute/ -f makefile_squeezenet_arm_generic.mk targetDirName=targetloc/arm_compute"'), end

在目标硬件上运行可执行文件

Run the executable from Linux using below command.
if isunix, system('sshpass -p password ssh username@targetname "cd targetloc/arm_compute/; ./squeezenet coffeemug.png"'), end
Run the executable from Windows using below command.
if ispc, system('plink.exe -l username -pw password targetname "cd targetloc/arm_compute/; ./squeezenet coffeemug.png"'), end
Top 5 Predictions:
-----------------------------
88.299% coffee mug
7.309% cup
1.098% candle
0.634% paper towel
0.591% water jug