В этом примере вы используете Глубокое Обучение HDL Toolbox, чтобы развернуть квантованную глубокую сверточную нейронную сеть и классифицировать изображение. Пример использует предварительно обученную ResNet-18 сверточную нейронную сеть, чтобы продемонстрировать передачу обучения, квантование и развертывание для квантованной сети. Используйте MATLAB ®, чтобы получить результаты предсказания.
ResNet-18 обучена на более чем миллионе изображений и может классифицировать изображения в 1000 категорий объектов (таких как клавиатура, кофейная кружка, карандаш и многие животные). Сеть изучила представления богатых функций для широкой области значений изображений. Сеть принимает изображение как вход и выводит метку для объекта в изображении вместе с вероятностями для каждой из категорий объектов.
В данном примере вам нужно:
Набор инструментов Deep Learning Toolbox ™
Deep Learning HDL Toolbox ™
Deep Learning Toolbox модель для ResNet-18 сети
Пакет поддержки пакета Deep Learning HDL Toolbox для устройств Xilinx FPGA и SoC
Image Processing Toolbox ™
Библиотека квантования модели Deep Learning Toolbox
MATLAB CODER для библиотек глубокого обучения
Чтобы выполнить классификацию на новом наборе изображений, вы тонко настраиваете предварительно обученную ResNet-18 сверточную нейронную сеть путем передачи обучения. В передачу обучения можно взять предварительно обученную сеть и использовать ее как начальная точка, чтобы узнать новую задачу. Подстройка сети с передачей обучения обычно намного быстрее и проще, чем обучение сети со случайным образом инициализированными весами с нуля. Можно быстро перенести выученные функции в новую задачу с помощью меньшего количества обучающих изображений.
Чтобы загрузить предварительно обученные сетевые ResNet-18, введите:
snet = resnet18;
Чтобы просмотреть слои предварительно обученной последовательной сети, введите:
analyzeNetwork(snet);
Первый слой, входной слой для изображений, требует входа изображений размера 227 227 3, где 3 количество цветовых каналов.
inputSize = snet.Layers(1).InputSize;
Этот пример использует MathWorks
Набор данных MerchData. Это небольшой набор данных, содержащий 75 изображений товаров MathWorks, принадлежащих пяти различным классам (прописная буква, cube, игральные карты, отвертка и факел).
curDir = pwd; unzip('MerchData.zip'); imds = imageDatastore('MerchData', ... 'IncludeSubfolders',true, ... 'LabelSource','foldernames'); [imdsTrain,imdsValidation] = splitEachLabel(imds,0.7,'randomized');
Слой полносвязного слоя и классификации предварительно обученной сети net
настроены для 1000 классов. Эти два слоя fc1000
и ClassificationLayer_predictions
в ResNet-18 содержат информацию о том, как объединить функции, которые сеть извлекает в вероятности классов и предсказанные метки. Эти два слоя должны быть уточнены для новой задачи классификации. Извлеките все слои, кроме последних двух слоев, из предварительно обученной сети.
lgraph = layerGraph(snet)
lgraph = LayerGraph with properties: Layers: [71×1 nnet.cnn.layer.Layer] Connections: [78×2 table] InputNames: {'data'} OutputNames: {'ClassificationLayer_predictions'}
numClasses = numel(categories(imdsTrain.Labels))
numClasses = 5
newLearnableLayer = fullyConnectedLayer(numClasses, ... 'Name','new_fc', ... 'WeightLearnRateFactor',10, ... 'BiasLearnRateFactor',10); lgraph = replaceLayer(lgraph,'fc1000',newLearnableLayer); newClassLayer = classificationLayer('Name','new_classoutput'); lgraph = replaceLayer(lgraph,'ClassificationLayer_predictions',newClassLayer);
Сеть требует изображений входа размера 224 на 224 на 3, но у изображений в хранилищах данных изображения есть различные размеры. Используйте хранилище данных дополненных изображений, чтобы автоматически изменить размер обучающих изображений. Задайте дополнительные операции увеличения для выполнения обучающих изображений, такие как случайное листание обучающих изображений вдоль вертикальной оси и случайное перемещение их до 30 пикселей горизонтально и вертикально. Увеличение количества данных помогает предотвратить сверхподбор кривой сети и запоминание точных деталей обучающих изображений.
pixelRange = [-30 30]; imageAugmenter = imageDataAugmenter( ... 'RandXReflection',true, ... 'RandXTranslation',pixelRange, ... 'RandYTranslation',pixelRange);
Чтобы автоматически изменить размер изображений валидации, не выполняя дальнейшего увеличения данных, используйте хранилище datastore с дополненными изображениями, не задавая никаких дополнительных операций предварительной обработки.
augimdsTrain = augmentedImageDatastore(inputSize(1:2),imdsTrain, ... 'DataAugmentation',imageAugmenter); augimdsValidation = augmentedImageDatastore(inputSize(1:2),imdsValidation);
Задайте опции обучения. Для передачи обучения сохраните функции из ранних слоев предварительно обученной сети (веса переданных слоев). Чтобы замедлить обучение в перенесенных слоях, установите начальную скорость обучения на небольшое значение. Укажите размер мини-пакета и данные валидации. Программное обеспечение проверяет сеть каждый ValidationFrequency
итерации во время обучения.
options = trainingOptions('sgdm', ... 'MiniBatchSize',10, ... 'MaxEpochs',6, ... 'InitialLearnRate',1e-4, ... 'Shuffle','every-epoch', ... 'ValidationData',augimdsValidation, ... 'ValidationFrequency',3, ... 'Verbose',false, ... 'Plots','training-progress');
Обучите сеть, которая состоит из переданного и нового слоев. По умолчанию trainNetwork
использует графический процессор, если он доступен (требует Parallel Computing Toolbox™ и поддерживаемое устройство GPU. Для получения дополнительной информации смотрите Поддержку GPU by Release (Parallel Computing Toolbox)). В противном случае в сети используется центральный процессор (для глубокого обучения требуется MATLAB Coder Interface Libraries™). Можно также задать окружение выполнения с помощью 'ExecutionEnvironment'
аргумент имя-значение trainingOptions
.
netTransfer = trainNetwork(augimdsTrain,lgraph,options);
Создайте dlquantizer
объект и укажите сеть для квантования.
dlquantObj = dlquantizer(netTransfer,'ExecutionEnvironment','FPGA');
Используйте calibrate
функция для упражнения сети с выборочными входами и сбора информации о области значений. The calibrate
функция реализует сеть и собирает динамические области значений весов и смещений в свертках и полносвязных слоях сети и динамические области значений активаций во всех слоях сети. The calibrate
функция возвращает таблицу. Каждая строка таблицы содержит информацию о области значений для настраиваемого параметра квантованной сети.
dlquantObj.calibrate(augimdsTrain)
ans=95×5 table
Optimized Layer Name Network Layer Name Learnables / Activations MinValue MaxValue
__________________________ __________________ ________________________ ________ ________
{'conv1_Weights' } {'bn_conv1' } "Weights" -0.86045 1.3675
{'conv1_Bias' } {'bn_conv1' } "Bias" -0.66706 0.67651
{'res2a_branch2a_Weights'} {'bn2a_branch2a'} "Weights" -0.40354 0.34824
{'res2a_branch2a_Bias' } {'bn2a_branch2a'} "Bias" -0.7954 1.3412
{'res2a_branch2b_Weights'} {'bn2a_branch2b'} "Weights" -0.75855 0.5863
{'res2a_branch2b_Bias' } {'bn2a_branch2b'} "Bias" -1.3406 1.7593
{'res2b_branch2a_Weights'} {'bn2b_branch2a'} "Weights" -0.32464 0.35274
{'res2b_branch2a_Bias' } {'bn2b_branch2a'} "Bias" -1.1606 1.5388
{'res2b_branch2b_Weights'} {'bn2b_branch2b'} "Weights" -1.1713 0.95244
{'res2b_branch2b_Bias' } {'bn2b_branch2b'} "Bias" -0.73906 1.2628
{'res3a_branch2a_Weights'} {'bn3a_branch2a'} "Weights" -0.19423 0.2396
{'res3a_branch2a_Bias' } {'bn3a_branch2a'} "Bias" -0.53868 0.69323
{'res3a_branch2b_Weights'} {'bn3a_branch2b'} "Weights" -0.53801 0.73706
{'res3a_branch2b_Bias' } {'bn3a_branch2b'} "Bias" -0.6457 1.1458
{'res3a_branch1_Weights' } {'bn3a_branch1' } "Weights" -0.64085 0.98864
{'res3a_branch1_Bias' } {'bn3a_branch1' } "Bias" -0.9258 0.76574
⋮
Используйте dlhdl.Target
Класс создать целевой объект с пользовательским именем для целевого устройства и интерфейсом для подключения целевого устройства к хосту-компьютеру. Опции интерфейса JTAG и Ethernet. Чтобы использовать JTAG, Установите Xilinx™ Vivado™ Design Suite 2019.2. Чтобы задать траекторию инструмента Xilinx Vivado, введите:
% hdlsetuptoolpath('ToolName', 'Xilinx Vivado', 'ToolPath', 'C:\Xilinx\Vivado\2019.2\bin\vivado.bat');
hTarget = dlhdl.Target('Xilinx','Interface','Ethernet');
Используйте dlhdl.Workflow
класс, чтобы создать объект. Когда вы создаете объект, задайте сеть и имя битового потока. Укажите сохраненную предварительно обученную нейронную сеть alexnet в качестве сети. Убедитесь, что имя битового потока соответствует типу данных и плате FPGA, на которую вы нацелены. В этом примере целевой платой FPGA является плата Xilinx ZCU102 SoC. Битовый поток использует один тип данных.
hW = dlhdl.Workflow('Network', dlquantObj, 'Bitstream', 'zcu102_int8','Target',hTarget);
Чтобы скомпилировать сеть netTransfer DAG, запустите метод компиляции dlhdl.Workflow
объект. Вы можете опционально задать максимальное количество входных кадров.
dn = hW.compile('InputFrameNumberLimit',15)
### Compiling network for Deep Learning FPGA prototyping ... ### Targeting FPGA bitstream zcu102_int8 ... ### The network includes the following layers: 1 'data' Image Input 224×224×3 images with 'zscore' normalization (SW Layer) 2 'conv1' Convolution 64 7×7×3 convolutions with stride [2 2] and padding [3 3 3 3] (HW Layer) 3 'bn_conv1' Batch Normalization Batch normalization with 64 channels (HW Layer) 4 'conv1_relu' ReLU ReLU (HW Layer) 5 'pool1' Max Pooling 3×3 max pooling with stride [2 2] and padding [1 1 1 1] (HW Layer) 6 'res2a_branch2a' Convolution 64 3×3×64 convolutions with stride [1 1] and padding [1 1 1 1] (HW Layer) 7 'bn2a_branch2a' Batch Normalization Batch normalization with 64 channels (HW Layer) 8 'res2a_branch2a_relu' ReLU ReLU (HW Layer) 9 'res2a_branch2b' Convolution 64 3×3×64 convolutions with stride [1 1] and padding [1 1 1 1] (HW Layer) 10 'bn2a_branch2b' Batch Normalization Batch normalization with 64 channels (HW Layer) 11 'res2a' Addition Element-wise addition of 2 inputs (HW Layer) 12 'res2a_relu' ReLU ReLU (HW Layer) 13 'res2b_branch2a' Convolution 64 3×3×64 convolutions with stride [1 1] and padding [1 1 1 1] (HW Layer) 14 'bn2b_branch2a' Batch Normalization Batch normalization with 64 channels (HW Layer) 15 'res2b_branch2a_relu' ReLU ReLU (HW Layer) 16 'res2b_branch2b' Convolution 64 3×3×64 convolutions with stride [1 1] and padding [1 1 1 1] (HW Layer) 17 'bn2b_branch2b' Batch Normalization Batch normalization with 64 channels (HW Layer) 18 'res2b' Addition Element-wise addition of 2 inputs (HW Layer) 19 'res2b_relu' ReLU ReLU (HW Layer) 20 'res3a_branch2a' Convolution 128 3×3×64 convolutions with stride [2 2] and padding [1 1 1 1] (HW Layer) 21 'bn3a_branch2a' Batch Normalization Batch normalization with 128 channels (HW Layer) 22 'res3a_branch2a_relu' ReLU ReLU (HW Layer) 23 'res3a_branch2b' Convolution 128 3×3×128 convolutions with stride [1 1] and padding [1 1 1 1] (HW Layer) 24 'bn3a_branch2b' Batch Normalization Batch normalization with 128 channels (HW Layer) 25 'res3a' Addition Element-wise addition of 2 inputs (HW Layer) 26 'res3a_relu' ReLU ReLU (HW Layer) 27 'res3a_branch1' Convolution 128 1×1×64 convolutions with stride [2 2] and padding [0 0 0 0] (HW Layer) 28 'bn3a_branch1' Batch Normalization Batch normalization with 128 channels (HW Layer) 29 'res3b_branch2a' Convolution 128 3×3×128 convolutions with stride [1 1] and padding [1 1 1 1] (HW Layer) 30 'bn3b_branch2a' Batch Normalization Batch normalization with 128 channels (HW Layer) 31 'res3b_branch2a_relu' ReLU ReLU (HW Layer) 32 'res3b_branch2b' Convolution 128 3×3×128 convolutions with stride [1 1] and padding [1 1 1 1] (HW Layer) 33 'bn3b_branch2b' Batch Normalization Batch normalization with 128 channels (HW Layer) 34 'res3b' Addition Element-wise addition of 2 inputs (HW Layer) 35 'res3b_relu' ReLU ReLU (HW Layer) 36 'res4a_branch2a' Convolution 256 3×3×128 convolutions with stride [2 2] and padding [1 1 1 1] (HW Layer) 37 'bn4a_branch2a' Batch Normalization Batch normalization with 256 channels (HW Layer) 38 'res4a_branch2a_relu' ReLU ReLU (HW Layer) 39 'res4a_branch2b' Convolution 256 3×3×256 convolutions with stride [1 1] and padding [1 1 1 1] (HW Layer) 40 'bn4a_branch2b' Batch Normalization Batch normalization with 256 channels (HW Layer) 41 'res4a' Addition Element-wise addition of 2 inputs (HW Layer) 42 'res4a_relu' ReLU ReLU (HW Layer) 43 'res4a_branch1' Convolution 256 1×1×128 convolutions with stride [2 2] and padding [0 0 0 0] (HW Layer) 44 'bn4a_branch1' Batch Normalization Batch normalization with 256 channels (HW Layer) 45 'res4b_branch2a' Convolution 256 3×3×256 convolutions with stride [1 1] and padding [1 1 1 1] (HW Layer) 46 'bn4b_branch2a' Batch Normalization Batch normalization with 256 channels (HW Layer) 47 'res4b_branch2a_relu' ReLU ReLU (HW Layer) 48 'res4b_branch2b' Convolution 256 3×3×256 convolutions with stride [1 1] and padding [1 1 1 1] (HW Layer) 49 'bn4b_branch2b' Batch Normalization Batch normalization with 256 channels (HW Layer) 50 'res4b' Addition Element-wise addition of 2 inputs (HW Layer) 51 'res4b_relu' ReLU ReLU (HW Layer) 52 'res5a_branch2a' Convolution 512 3×3×256 convolutions with stride [2 2] and padding [1 1 1 1] (HW Layer) 53 'bn5a_branch2a' Batch Normalization Batch normalization with 512 channels (HW Layer) 54 'res5a_branch2a_relu' ReLU ReLU (HW Layer) 55 'res5a_branch2b' Convolution 512 3×3×512 convolutions with stride [1 1] and padding [1 1 1 1] (HW Layer) 56 'bn5a_branch2b' Batch Normalization Batch normalization with 512 channels (HW Layer) 57 'res5a' Addition Element-wise addition of 2 inputs (HW Layer) 58 'res5a_relu' ReLU ReLU (HW Layer) 59 'res5a_branch1' Convolution 512 1×1×256 convolutions with stride [2 2] and padding [0 0 0 0] (HW Layer) 60 'bn5a_branch1' Batch Normalization Batch normalization with 512 channels (HW Layer) 61 'res5b_branch2a' Convolution 512 3×3×512 convolutions with stride [1 1] and padding [1 1 1 1] (HW Layer) 62 'bn5b_branch2a' Batch Normalization Batch normalization with 512 channels (HW Layer) 63 'res5b_branch2a_relu' ReLU ReLU (HW Layer) 64 'res5b_branch2b' Convolution 512 3×3×512 convolutions with stride [1 1] and padding [1 1 1 1] (HW Layer) 65 'bn5b_branch2b' Batch Normalization Batch normalization with 512 channels (HW Layer) 66 'res5b' Addition Element-wise addition of 2 inputs (HW Layer) 67 'res5b_relu' ReLU ReLU (HW Layer) 68 'pool5' Global Average Pooling Global average pooling (HW Layer) 69 'new_fc' Fully Connected 5 fully connected layer (HW Layer) 70 'prob' Softmax softmax (SW Layer) 71 'new_classoutput' Classification Output crossentropyex with 'MathWorks Cap' and 4 other classes (SW Layer) ### Optimizing series network: Fused 'nnet.cnn.layer.BatchNormalizationLayer' into 'nnet.cnn.layer.Convolution2DLayer' 5 Memory Regions created. Skipping: data Compiling leg: conv1>>pool1 ... Compiling leg: conv1>>pool1 ... complete. Compiling leg: res2a_branch2a>>res2a_branch2b ... Compiling leg: res2a_branch2a>>res2a_branch2b ... complete. Compiling leg: res2b_branch2a>>res2b_branch2b ... Compiling leg: res2b_branch2a>>res2b_branch2b ... complete. Compiling leg: res3a_branch1 ... Compiling leg: res3a_branch1 ... complete. Compiling leg: res3a_branch2a>>res3a_branch2b ... Compiling leg: res3a_branch2a>>res3a_branch2b ... complete. Compiling leg: res3b_branch2a>>res3b_branch2b ... Compiling leg: res3b_branch2a>>res3b_branch2b ... complete. Compiling leg: res4a_branch1 ... Compiling leg: res4a_branch1 ... complete. Compiling leg: res4a_branch2a>>res4a_branch2b ... Compiling leg: res4a_branch2a>>res4a_branch2b ... complete. Compiling leg: res4b_branch2a>>res4b_branch2b ... Compiling leg: res4b_branch2a>>res4b_branch2b ... complete. Compiling leg: res5a_branch1 ... Compiling leg: res5a_branch1 ... complete. Compiling leg: res5a_branch2a>>res5a_branch2b ... Compiling leg: res5a_branch2a>>res5a_branch2b ... complete. Compiling leg: res5b_branch2a>>res5b_branch2b ... Compiling leg: res5b_branch2a>>res5b_branch2b ... complete. Compiling leg: pool5 ... Compiling leg: pool5 ... complete. Compiling leg: new_fc ... Compiling leg: new_fc ... complete. Skipping: prob Skipping: new_classoutput Creating Schedule... ............................. Creating Schedule...complete. Creating Status Table... ............................ Creating Status Table...complete. Emitting Schedule... .......................... Emitting Schedule...complete. Emitting Status Table... .............................. Emitting Status Table...complete. ### Allocating external memory buffers: offset_name offset_address allocated_space _______________________ ______________ ________________ "InputDataOffset" "0x00000000" "24.0 MB" "OutputResultOffset" "0x01800000" "4.0 MB" "SchedulerDataOffset" "0x01c00000" "4.0 MB" "SystemBufferOffset" "0x02000000" "28.0 MB" "InstructionDataOffset" "0x03c00000" "4.0 MB" "ConvWeightDataOffset" "0x04000000" "16.0 MB" "FCWeightDataOffset" "0x05000000" "4.0 MB" "EndOffset" "0x05400000" "Total: 84.0 MB" ### Network compilation complete.
dn = struct with fields:
weights: [1×1 struct]
instructions: [1×1 struct]
registers: [1×1 struct]
syncInstructions: [1×1 struct]
Чтобы развернуть сеть на оборудовании Xilinx ZCU102, запустите функцию развертывания dlhdl.Workflow
объект. Эта функция использует выход функции компиляции, чтобы запрограммировать плату FPGA с помощью файла программирования. Он также загружает веса и смещения сети. Функция развертывания начинает программировать устройство 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 Conv Processor. ### Conv Weights loaded. Current time is 11-Jan-2021 11:26:16 ### Loading weights to FC Processor. ### FC Weights loaded. Current time is 11-Jan-2021 11:26:16
Загрузите пример изображения.
imgFile = fullfile(pwd,'MerchData','MathWorks Cube','Mathworks cube_0.jpg'); inputImg = imresize(imread(imgFile),[224 224]); imshow(inputImg)
Выполните метод предсказания на dlhdl.Workflow
Объект и затем отобразите метку в командном окне MATLAB.
[prediction, speed] = hW.predict(single(inputImg),'Profile','on');
### Finished writing input activations. ### Running single input activations. Deep Learning Processor Profiler Performance Results LastFrameLatency(cycles) LastFrameLatency(seconds) FramesNum Total Latency Frames/s ------------- ------------- --------- --------- --------- Network 7323615 0.02929 1 7323615 34.1 conv1 1111619 0.00445 pool1 235563 0.00094 res2a_branch2a 268736 0.00107 res2a_branch2b 269031 0.00108 res2a 94319 0.00038 res2b_branch2a 268677 0.00107 res2b_branch2b 268863 0.00108 res2b 94255 0.00038 res3a_branch1 155156 0.00062 res3a_branch2a 226445 0.00091 res3a_branch2b 243593 0.00097 res3a 47248 0.00019 res3b_branch2a 243461 0.00097 res3b_branch2b 243581 0.00097 res3b 47232 0.00019 res4a_branch1 133899 0.00054 res4a_branch2a 134402 0.00054 res4a_branch2b 234184 0.00094 res4a 23628 0.00009 res4b_branch2a 234058 0.00094 res4b_branch2b 234648 0.00094 res4b 23756 0.00010 res5a_branch1 310730 0.00124 res5a_branch2a 310810 0.00124 res5a_branch2b 595374 0.00238 res5a 11827 0.00005 res5b_branch2a 595150 0.00238 res5b_branch2b 595904 0.00238 res5b 12012 0.00005 pool5 35870 0.00014 new_fc 17811 0.00007 * The clock frequency of the DL processor is: 250MHz
[val, idx] = max(prediction); dlquantObj.NetworkObject.Layers(end).ClassNames{idx}
ans = 'MathWorks Cube'