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

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

Необходимые условия

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

  • Пакет поддержки Deep Learning HDL Toolbox™ для Xilinx™ FPGA и SoC

  • Deep Learning Toolbox™

  • Deep Learning HDL Toolbox™

Загрузка предварительно обученной сети SeriesNetwork

Для загрузки предварительно обученной цифровой сети введите:

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

Чтобы скомпилировать сеть серии 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"

Программа Bitstream на 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