Main Content

Deep Learning Prediction with ARM Compute Using codegen

This example shows how to use codegen to generate code for a Logo classification application that uses deep learning on ARM® processors. The logo classification application uses the LogoNet series network to perform logo recognition from images. The generated code takes advantage of the ARM Compute library for computer vision and machine learning.

Prerequisites

  • ARM processor that supports the NEON extension

  • Open Source Computer Vision Library (OpenCV) v3.1

  • Environment variables for ARM Compute and OpenCV libraries

  • MATLAB® Coder™ for C++ code generation

  • The support package MATLAB Coder Interface for Deep Learning

  • Deep Learning Toolbox™ for using the SeriesNetwork object

For more information, see Prerequisites for Deep Learning with MATLAB Coder (MATLAB Coder).

This example is supported on Linux® and Windows® platforms and not supported for MATLAB Online.

Get the Pretrained SeriesNetwork

Download the pretrained LogoNet network and save it as logonet.mat, if it does not exist. The network was developed in MATLAB® and its architecture is similar to that of AlexNet. This network can recognize 32 logos under various lighting conditions and camera angles.

net = getLogonet();

The network contains 22 layers including convolution, fully connected, and the classification output layers.

net.Layers
ans = 

  22×1 Layer array with layers:

     1   'imageinput'    Image Input             227×227×3 images with 'zerocenter' normalization and 'randfliplr' augmentations
     2   'conv_1'        Convolution             96 5×5×3 convolutions with stride [1  1] and padding [0  0  0  0]
     3   'relu_1'        ReLU                    ReLU
     4   'maxpool_1'     Max Pooling             3×3 max pooling with stride [2  2] and padding [0  0  0  0]
     5   'conv_2'        Convolution             128 3×3×96 convolutions with stride [1  1] and padding [0  0  0  0]
     6   'relu_2'        ReLU                    ReLU
     7   'maxpool_2'     Max Pooling             3×3 max pooling with stride [2  2] and padding [0  0  0  0]
     8   'conv_3'        Convolution             384 3×3×128 convolutions with stride [1  1] and padding [0  0  0  0]
     9   'relu_3'        ReLU                    ReLU
    10   'maxpool_3'     Max Pooling             3×3 max pooling with stride [2  2] and padding [0  0  0  0]
    11   'conv_4'        Convolution             128 3×3×384 convolutions with stride [2  2] and padding [0  0  0  0]
    12   'relu_4'        ReLU                    ReLU
    13   'maxpool_4'     Max Pooling             3×3 max pooling with stride [2  2] and padding [0  0  0  0]
    14   'fc_1'          Fully Connected         2048 fully connected layer
    15   'relu_5'        ReLU                    ReLU
    16   'dropout_1'     Dropout                 50% dropout
    17   'fc_2'          Fully Connected         2048 fully connected layer
    18   'relu_6'        ReLU                    ReLU
    19   'dropout_2'     Dropout                 50% dropout
    20   'fc_3'          Fully Connected         32 fully connected layer
    21   'softmax'       Softmax                 softmax
    22   'classoutput'   Classification Output   crossentropyex with 'adidas' and 31 other classes

Set Environment Variables

On the ARM target hardware, make sure that ARM_COMPUTELIB is set and that LD_LIBRARY_PATH contains the path to the ARM Compute Library folder.

See Prerequisites for Deep Learning with MATLAB Coder (MATLAB Coder).

logonet_predict Function

The logonet_predict.m entry-point function takes an image input and performs prediction on the image using the deep learning network saved in the LogoNet MAT-file. The function loads the network object from LogoNet.mat into a persistent network vairable logonet. On subsequent calls to the function, the persistent object is reused.

type logonet_predict
function out = logonet_predict(in)
%#codegen

% Copyright 2017-2020 The MathWorks, Inc.

persistent logonet;

if isempty(logonet)
    
    logonet = coder.loadDeepLearningNetwork('LogoNet.mat','logonet');
end

out = logonet.predict(in);

end

Set Up a Code Generation Configuration Object for a Static Library

When you generate code targeting an ARM-based device and do not use a hardware support package, create a configuration object for a library. Do not create a configuration object for an executable program.

Set up the configuration object for generation of C++ code and generation of code only.

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

Set Up a Configuration Object for Deep Learning Code Generation

Create a coder.ARMNEONConfig object. Specify the library version and the architecture of the target ARM processor. For example, suppose that the target board is a HiKey/Rock960 board with ARMv8 architecture and ARM Compute Library version 19.05.

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

Attach the Deep Learning Configuration Object to the Code Generation Configuration Object

Set the DeepLearningConfig property of the code generation configuration object to the deep learning configuration object.

cfg.DeepLearningConfig = dlcfg;

Generate Source C++ Code by Using codegen

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

The code is generated in the arm_compute folder in the current working folder on the host computer.

Generate the Zip File Using the packNGo function

The packNGo function packages all relevant files in a compressed zip file.

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

Copy the Generated Zip File to the Target Hardware

Copy the Zip file and extract into a folder. Remove the Zip file from the targer hardware.

In the following commands, replace:

  • password with your password

  • username with your user name

  • targetname with the name of your device

  • targetloc with the destination folder for the files

Run these commands to copy and extract zip file from Linux.

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

Run these commands to copy and extract zip file from Windows.

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

Copy Example Files to the Target Hardware

Copy these supporting files from the host computer to the target hardware:

  • Input image, coderdemo_google.png

  • Makefile for generating the library, logonet_predict_rtw.mk

  • Makefile for building the executable program, makefile_arm_logo.mk

  • Synset dictionary, synsetWordsLogoDet.txt

In the following commands, replace:

  • password with your password

  • username with your user name

  • targetname with the name of your device

  • targetloc with the destination folder for the files

Perform the steps below to copy all the required files when running from 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

Perform the steps below to copy all the required files when running from 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

Build the Library on the Target Hardware

To build the library on the target hardware, execute the generated makefile on the ARM hardware.

Make sure that you set the environment variables ARM_COMPUTELIB and LD_LIBRARY_PATH on the target hardware. See Prerequisites for Deep Learning with MATLAB Coder (MATLAB Coder). The ARM_ARCH variable is used in the Makefile to pass compiler flags based on Arm Architecture. ARM_VER variable is used in the Makefile to compile the code based on Arm Compute Version. Replace the hardware credentials and paths in these commands similar to previous section.

Perform the below steps to build the library from 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

Perform the below steps to build the library from 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

Create Executable from the Library on the Target Hardware

Build the library with the source main wrapper file to create the executable. main_arm_logo.cpp is the C++ main wrapper file which invokes the logonet_predict function.

Run the below command to create the executable from 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

Run the below command to create the executable from 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

Run the Executable on the Target Hardware

Run the executable from Linux using below command.
if isunix, system('sshpass -p password ssh username@targetname "cd targetloc/arm_compute/; ./logonet coderdemo_google.png"'), end
Run the executable from Windows using below command.
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