通过 ARM 计算使用 codegen
进行深度学习预测
此示例说明如何使用 codegen
为在 ARM® 处理器上使用深度学习的徽标分类应用程序生成代码。徽标分类应用程序使用 dlnetwork
对象从图像中执行徽标识别。生成的代码利用 ARM Compute Library 进行计算机视觉和机器学习。
第三方前提条件
支持 NEON 扩展的 ARM 处理器
开源计算机视觉库 (OpenCV) v3.1
ARM Compute 和 OpenCV 库的环境变量
此示例使用的 ARM Compute Library 版本可能不是代码生成支持的最新版本。有关受支持的库版本和有关设置环境变量的信息,请参阅使用 MATLAB Coder 进行深度学习的前提条件 (MATLAB Coder)。
此示例在 Linux® 和 Windows® 平台上受支持,不受 MATLAB Online 支持。
获得预训练的 SeriesNetwork
下载经过预训练的 LogoNet
网络,并将其另存为 logonet.mat
(如果它不存在的话)。该网络是在 MATLAB® 中开发的,其架构类似于 AlexNet 架构。该网络可以在各种光照条件和相机角度下识别 32 个徽标。
net = getLogonet();
将 SeriesNetwork
网络对象转换为 dlnetwork
对象,并将网络保存到 MAT 文件中。
dlconvnet = dag2dlnetwork(net); save dlLogoNet.mat dlconvnet
该网络包含 22 个层,包括卷积层、全连接层和分类输出层。要查看网络架构,请使用 analyzeNetwork
函数。
analyzeNetwork(dlconvnet)
设置环境变量
在 ARM 目标硬件上,确保设置了 ARM_COMPUTELIB,并且 LD_LIBRARY_PATH 包含指向 ARM Compute Library 文件夹的路径。
logonet_predict 入口函数
logonet_predict.m
入口函数以图像作为输入,并使用保存在 dlLogoNet.mat
文件中的深度学习网络对图像执行预测。该函数将 dlLogoNet.mat
中的网络对象加载到持久变量 dlLogonet
中,并在后续的预测调用中重用该持久变量。dlarray 对象是在函数中创建的,函数的输入和输出属于原始数据类型。
type logonet_predict
function out = logonet_predict(in) %#codegen % Copyright 2017-2023 The MathWorks, Inc. % A persistent object dlLogonet is used to load the network object. At the % first call to this function, the persistent object is constructed and % setup. When the function is called subsequent times, the same object is % reused to call predict on inputs, thus avoiding reconstructing and % reloading the network object. dlIn = dlarray(in, 'SSC'); persistent dlLogonet; if isempty(dlLogonet) dlLogonet = coder.loadDeepLearningNetwork('dlLogoNet.mat','dlLogonet'); end dlOut = predict(dlLogonet, dlIn); out = extractdata(dlOut); end
生成 C++ 源代码
当您针对基于 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';
将深度学习配置对象连接到代码生成配置对象。使用 codegen 命令生成源代码。
cfg.DeepLearningConfig = dlcfg; codegen -config cfg logonet_predict -args {ones(227, 227, 3, 'single')} -d arm_compute
Code generation successful.
代码在主机上当前工作文件夹的 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 文件。
在以下命令中,进行以下替换:
将
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
将示例文件复制到目标硬件
将下列支持文件从主机复制到目标硬件:
输入图像,
coderdemo_google.png
用于生成库的联编文件,
logonet_predict_rtw.mk
用于编译可执行程序的联编文件,
makefile_arm_logo.mk
Synset 字典,
synsetWordsLogoDet.txt
在以下命令中,进行以下替换:
将
password
替换为您的密码将
username
替换为您的用户名将
targetname
替换为您设备的名称将
targetloc
替换为文件的目标文件夹
从 Linux 运行时,执行以下步骤以复制所有必需的文件
if isunix, system('sshpass -p password scp logonet_predict_rtw.mk username@targetname:targetloc/arm_compute/'), end if isunix, system('sshpass -p password scp coderdemo_google.png username@targetname:targetloc/arm_compute/'), end if isunix, system('sshpass -p password scp makefile_arm_logo.mk username@targetname:targetloc/arm_compute/'), end if isunix, system('sshpass -p password scp synsetWordsLogoDet.txt username@targetname:targetloc/arm_compute/'), end
从 Windows 运行时,执行以下步骤以复制所有必需的文件
if ispc, system('pscp.exe -pw password logonet_predict_rtw.mk username@targetname:targetloc/arm_compute/'), end if ispc, system('pscp.exe -pw password coderdemo_google.png username@targetname:targetloc/arm_compute/'), end if ispc, system('pscp.exe -pw password makefile_arm_logo.mk username@targetname:targetloc/arm_compute/'), end if ispc, system('pscp.exe -pw password synsetWordsLogoDet.txt username@targetname:targetloc/arm_compute/'), end
在目标硬件上编译库
要在目标硬件上编译库,请在 ARM 硬件上执行生成的联编文件。
确保您在目标硬件上设置环境变量 ARM_COMPUTELIB 和 LD_LIBRARY_PATH。在联编文件中使用 ARM_ARCH 变量来基于 Arm 架构传递编译器标志。在联编文件中使用 ARM_VER 变量来基于 Arm Compute 版本编译代码。按照与上一节中类似的步骤替换下列命令中的硬件凭据和路径。
执行以下步骤从 Linux 编译库。
if isunix, system('sshpass -p password scp main_arm_logo.cpp username@targetname:targetloc/arm_compute/'), end if isunix, system(['sshpass -p password ssh username@targetname "make -C targetloc/arm_compute/ -f logonet_predict_rtw.mk ARM_ARCH=' dlcfg.ArmArchitecture ' ARM_VER=' dlcfg.ArmComputeVersion ' "']), end
执行以下步骤从 Windows 编译库。
if ispc, system('pscp.exe -pw password main_arm_logo.cpp username@targetname:targetloc/arm_compute/'), end if ispc, system(['plink.exe -l username -pw password targetname "make -C targetloc/arm_compute/ -f logonet_predict_rtw.mk ARM_ARCH=' dlcfg.ArmArchitecture ' ARM_VER=' dlcfg.ArmComputeVersion ' "']), end
从目标硬件上的库中创建可执行文件
用源主包装文件编译库来创建可执行文件。main_arm_logo.cpp
是调用 logonet_predict
函数的 C++ 主包装文件。
运行以下命令以从 Linux 创建可执行文件。
if isunix, system('sshpass -p password ssh username@targetname "make -C targetloc/arm_compute/ -f makefile_arm_logo.mk targetDirName=targetloc/arm_compute"'), end
运行以下命令以从 Windows 创建可执行文件。
if ispc, system('plink.exe -l username -pw password targetname "make -C targetloc/arm_compute/ -f makefile_arm_logo.mk targetDirName=targetloc/arm_compute"'), end
在目标硬件上运行可执行文件
使用以下命令从 Linux 运行可执行文件。
if isunix, system('sshpass -p password ssh username@targetname "cd targetloc/arm_compute/; ./logonet coderdemo_google.png"'), end
使用以下命令从 Windows 运行可执行文件。
if ispc, system('plink.exe -l username -pw password targetname "cd targetloc/arm_compute/; ./logonet coderdemo_google.png"'), end
Top 5 Predictions: ----------------------------- 99.992% google 0.003% corona 0.003% singha 0.001% esso 0.000% fedex