В этом примере показано, как улучшить производительность развернутой сети глубокого обучения путем идентификации слоев горлышка бутылки по результатам профилировщика.
Xilinx™ ZCU102 комплект для разработки SoC.
Пакет поддержки глубокого обучения HDL Toolbox™ для Xilinx™ FPGA и SoC
Глубокое обучение Toolbox™
Глубокое обучение HDL Toolbox™
Для загрузки сети серии предварительно обученных цифр введите:
snet = getDigitsNetwork();
% To view the layers of the pretrained series network, enter:
snet.Layersans =
15×1 Layer array with layers:
1 'imageinput' Image Input 28×28×1 images with 'zerocenter' normalization
2 'conv_1' Convolution 8 3×3×1 convolutions with stride [1 1] and padding 'same'
3 'batchnorm_1' Batch Normalization Batch normalization with 8 channels
4 'relu_1' ReLU ReLU
5 'maxpool_1' Max Pooling 2×2 max pooling with stride [2 2] and padding [0 0 0 0]
6 'conv_2' Convolution 16 3×3×8 convolutions with stride [1 1] and padding 'same'
7 'batchnorm_2' Batch Normalization Batch normalization with 16 channels
8 'relu_2' ReLU ReLU
9 'maxpool_2' Max Pooling 2×2 max pooling with stride [2 2] and padding [0 0 0 0]
10 'conv_3' Convolution 32 3×3×16 convolutions with stride [1 1] and padding 'same'
11 'batchnorm_3' Batch Normalization Batch normalization with 32 channels
12 'relu_3' ReLU ReLU
13 'fc' Fully Connected 10 fully connected layer
14 'softmax' Softmax softmax
15 'classoutput' Classification Output crossentropyex with '0' and 9 other classes
Создайте целевой объект с пользовательским именем для целевого устройства и интерфейсом для подключения целевого устройства к хост-компьютеру. Опции интерфейса - JTAG и Ethernet. Для интерфейса Ethernet введите:
hTarget = dlhdl.Target('Xilinx','Interface','Ethernet');
Чтобы использовать интерфейс JTAG, установите Xilinx™ Vivado™ Design Suite 2019.2. Настройте путь к установленному исполняемому файлу Xilinx Vivado, если он еще не настроен. Например, чтобы задать траекторию движения инструмента, введите:
% hdlsetuptoolpath('ToolName', 'Xilinx Vivado', 'ToolPath', 'C:\Xilinx\Vivado\2019.2\bin\vivado.bat');Для интерфейса JTAG введите:
% hTarget = dlhdl.Target('Xilinx','Interface','JTAG');Создание объекта dlhdl.Workflow класс. При создании объекта укажите сеть и имя битового потока. Определите спасенную предварительно обученную нейронную сеть цифр, snet, как сеть. Убедитесь, что имя битового потока соответствует типу данных и целевой плате FPGA. В этом примере целевой платой FPGA является плата Xilinx ZCU102 SOC. Битовый поток использует один тип данных.
hW = dlhdl.Workflow('Network', snet, 'Bitstream', 'zcu102_single', 'Target', hTarget); % % If running on Xilinx ZC706 board, instead of the above command, % uncomment the command below. % % hW = dlhdl.Workflow('Network', snet, 'Bitstream', 'zc706_single','Target',hTarget);
Для компиляции сети серии MNIST выполните функцию компиляции dlhdl.Workflow объект.
dn = hW.compile;
### Optimizing series network: Fused 'nnet.cnn.layer.BatchNormalizationLayer' into 'nnet.cnn.layer.Convolution2DLayer'
offset_name offset_address allocated_space
_______________________ ______________ ________________
"InputDataOffset" "0x00000000" "4.0 MB"
"OutputResultOffset" "0x00400000" "4.0 MB"
"SystemBufferOffset" "0x00800000" "28.0 MB"
"InstructionDataOffset" "0x02400000" "4.0 MB"
"ConvWeightDataOffset" "0x02800000" "4.0 MB"
"FCWeightDataOffset" "0x02c00000" "4.0 MB"
"EndOffset" "0x03000000" "Total: 48.0 MB"
Для развертывания сети на оборудовании Xilinx ZCU102 SoC выполните функцию развертывания dlhdl.Workflow объект. Эта функция использует выходные данные функции компиляции для программирования платы FPGA с помощью файла программирования. Он также загружает веса сети и отклонения.
hW.deploy;
### Programming FPGA Bitstream using Ethernet... Downloading target FPGA device configuration over Ethernet to SD card ... # Copied /tmp/hdlcoder_rd to /mnt/hdlcoder_rd # Copying Bitstream hdlcoder_system.bit to /mnt/hdlcoder_rd # Set Bitstream to hdlcoder_rd/hdlcoder_system.bit # Copying Devicetree devicetree_dlhdl.dtb to /mnt/hdlcoder_rd # Set Devicetree to hdlcoder_rd/devicetree_dlhdl.dtb # Set up boot for Reference Design: 'AXI-Stream DDR Memory Access : 3-AXIM' Downloading target FPGA device configuration over Ethernet to SD card done. The system will now reboot for persistent changes to take effect. System is rebooting . . . . . . ### Programming the FPGA bitstream has been completed successfully. ### Loading weights to FC Processor. ### FC Weights loaded. Current time is 28-Jun-2020 12:24:21
Загрузите пример изображения.
inputImg = imread('five_28x28.pgm');Выполнение функции прогнозирования dlhdl.Workflow объект, для которого для параметра профиля установлено значение «on» для отображения результатов задержки и пропускной способности.
[~, speed] = hW.predict(single(inputImg),'Profile','on');
### Finished writing input activations.
### Running single input activations.
Deep Learning Processor Profiler Performance Results
LastLayerLatency(cycles) LastLayerLatency(seconds) FramesNum Total Latency Frames/s
------------- ------------- --------- --------- ---------
Network 73231 0.00033 1 73273 3002.5
conv_module 26847 0.00012
conv_1 6618 0.00003
maxpool_1 4823 0.00002
conv_2 4876 0.00002
maxpool_2 3551 0.00002
conv_3 7039 0.00003
fc_module 46384 0.00021
fc 46384 0.00021
* The clock frequency of the DL processor is: 220MHz
Удалить NumFrames, Total latency, и Frames/s из таблицы результатов профилировщика. Это включает удаление результатов профилировщика уровня модуля и сетевого уровня. Сохраните только результаты профилировщика сетевого уровня. Как только слой горлышка бутылки идентифицирован, отображается индекс слоя горлышка бутылки, время работы и информация.
speed('Network',:) = []; speed('____conv_module',:) = []; speed('____fc_module',:) = []; speed = removevars(speed, {'NumFrames','Total Latency(cycles)','Frame/s'}); % then sort the profiler's results in descending ordering speed = sortrows(speed,'Latency(cycles)','descend'); % the first row in the profile table is the bottleneck layer. Thus the % following layerSpeed = speed(1,:); layerName = strip(layerSpeed.Properties.RowNames{1},'_'); for idx = 1:length(snet.Layers) currLayer = snet.Layers(idx); if strcmp(currLayer.Name, layerName) bottleNeckLayer = currLayer; break; end end % disply the bottle neck layer index dnnfpga.disp(['Bottleneck layer index is ', num2str(idx), '.']);
### Bottleneck layer index is 13.
% disply the bottle neck layer running time percentage percent = layerSpeed.("Latency(cycles)")/sum(speed.("Latency(cycles)")) * 100; dispStr = sprintf('It accounts for about %0.2f percent of the total running time.', percent); dnnfpga.disp(dispStr);
### It accounts for about 63.29 percent of the total running time.
% disply the bottle neck layer information dnnfpga.disp('Bottleneck layer information: ');
### Bottleneck layer information:
disp(currLayer);
FullyConnectedLayer with properties:
Name: 'fc'
Hyperparameters
InputSize: 1568
OutputSize: 10
Learnable Parameters
Weights: [10×1568 single]
Bias: [10×1 single]
Show all properties