Этот пример показывает, как улучшить эффективность развернутой нейронной сети для глубокого обучения путем идентификации слоев горлышка бутылки из результатов профилировщика.
Xilinx™ ZCU102 комплект для разработки на SoC.
Пакет поддержки Deep Learning HDL Toolbox™ для Xilinx™ FPGA и SoC
Deep Learning Toolbox™
Deep Learning HDL Toolbox™
Для загрузки предварительно обученной цифровой сети введите:
snet = getDigitsNetwork();
% To view the layers of the pretrained series network, enter:
snet.Layers
ans = 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