Generate Code and Deploy SqueezeNet Network to Raspberry Pi
This example shows how to generate C code that does not depend on any third-party deep learning libraries for pretrained SqueezeNet network. This example uses the processor-in-the-loop (PIL) workflow to generate a MEX function, which in turn calls the executable generated in the Raspberry Pi™ hardware from MATLAB®.
Third-Party Prerequisites
Raspberry Pi hardware
This example is not supported for MATLAB Online.
The squeezenet_predict
Entry-point Function
This example uses a dlnetwork
network object to show image classification. The squeezenet_predict
function uses the imagePretrainedNetwork
to load the pretrained SqueezeNet network into a persistent dlnetwork
object. On subsequent calls, the function reuses the object. A dlarray object is created within the entry-point function, input and output to the function are of single datatype. For more information, see Code Generation for dlarray (MATLAB Coder).
type squeezenet_predict
function out = squeezenet_predict(in) %#codegen % Copyright 2018-2024 The MathWorks, Inc. dlIn = dlarray(in,'SSC'); persistent dlnet; if isempty(dlnet) dlnet = imagePretrainedNetwork('squeezenet'); end dlOut = predict(dlnet, dlIn); out = extractdata(dlOut); end
Create Connection to Raspberry Pi
Use the MATLAB Support Package for Raspberry Pi Hardware function raspi
to create a connection to the Raspberry Pi.
r = raspi;
If this is your first time connecting to a Raspberry Pi board or you want to connect to a different board, use this line of code and replace:
raspiname
with the host name of your Raspberry Piusername
with your usernamepassword
with your password
r = raspi('raspiname','username','password');
Configure Code Generation Hardware Parameters for Raspberry Pi
Create a coder.EmbeddedCodeConfig
object to generate a static library. Set the VerificationMode
property to 'PIL'
to enable PIL-based execution. By default, the DeepLearningConfig
property is a coder.DeepLearningCodeConfig
(MATLAB Coder) object and target library is set to 'none'.
cfg = coder.config('lib','ecoder',true); cfg.VerificationMode = 'PIL';
Create a coder.Hardware
object and specify the target hardware as Raspberry Pi. Assign hardware object to the Hardware
property of cfg
.
hw = coder.hardware('Raspberry Pi');
cfg.Hardware = hw;
Specify a build folder on the Raspberry Pi.
buildDir = '/home/pi/squeezenet_predict';
cfg.Hardware.BuildDir = buildDir;
Generate PIL MEX Function
Run the codegen
command by specifying an input size of 227-by-227-by-3. This value corresponds to the input layer size of the SqueezeNet network.
codegen -config cfg squeezenet_predict -args {ones(227, 227, 3, 'single')}
### Connectivity configuration for function 'squeezenet_predict': 'Raspberry Pi' Location of the generated elf : /home/pi/squeezenet_predict/MATLAB_ws/R2024a/C/EM_Path/ExampleManager/yangzhu.Bdoc.24b/deeplearning_shared-ex98393496/codegen/lib/squeezenet_predict/pil Code generation successful.
Perform Prediction on Test Image
Load an input image. Call squeezenet_predict_pil
on the input image.
I = imread('coffeemug.png');
I = imresize(I,[227,227]);
output = squeezenet_predict_pil(single(I));
### Starting application: 'codegen\lib\squeezenet_predict\pil\squeezenet_predict.elf' To terminate execution: clear squeezenet_predict_pil ### Launching application squeezenet_predict.elf...
Multiply the output value by 100 to convert scores into percentage. Display the top five classification labels on the image.
[val,indx] = sort(output, 'descend'); scores = val(1:5)*100; [~,classNames] = imagePretrainedNetwork('squeezenet'); top5labels = classNames(indx(1:5)); outputImage = zeros(227,400,3, 'uint8'); for k = 1:3 outputImage(:,174:end,k) = I(:,:,k); end scol = 1; srow = 20; for k = 1:5 outputImage = insertText(outputImage, [scol, srow], ... [top5labels{k},' ',num2str(scores(k), '%2.2f'),'%'], ... 'TextColor', 'w','FontSize',15, 'BoxColor', 'black'); srow = srow + 20; end imshow(imresize(outputImage,[448,800]));
Clear Generated PIL Executable
clear squeezenet_predict_pil
### Host application produced the following standard output (stdout) and standard error (stderr) messages: