exponenta event banner

Профильная сеть для повышения производительности

В этом примере показано, как улучшить производительность развернутой сети глубокого обучения путем идентификации слоев горлышка бутылки по результатам профилировщика.

Предпосылки

  • Xilinx™ ZCU102 комплект для разработки SoC.

  • Пакет поддержки глубокого обучения HDL Toolbox™ для Xilinx™ FPGA и SoC

  • Глубокое обучение Toolbox™

  • Глубокое обучение 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');

Создание объекта WorkFlow

Создание объекта 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

Для компиляции сети серии 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"

Передача битового потока в FPGA и загрузка веса сети

Для развертывания сети на оборудовании 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