В этом примере вы используете Deep Learning HDL Toolbox™, чтобы развернуть квантованную глубокую сверточную нейронную сеть и классифицировать изображение. Пример использует предварительно обученную сверточную нейронную сеть ResNet-18, чтобы продемонстрировать передачу обучения, квантование и развертывание для квантованной сети. Используйте MATLAB ®, чтобы получить результаты предсказания.
ResNet-18 был обучен на более чем миллионе изображений и может классифицировать изображения в 1 000 категорий объектов (таких как клавиатура, кофейная кружка, карандаш и многие животные). Сеть изучила богатые представления функции для широкого спектра изображений. Сеть берет изображение в качестве входа и выводит метку для объекта в изображении вместе с вероятностями для каждой из категорий объектов.
В данном примере вам нужно:
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™ Interface для библиотек глубокого обучения
Чтобы выполнить классификацию на новом наборе изображений, вы подстраиваете предварительно обученную сверточную нейронную сеть ResNet-18, переводом учась. В передаче обучения можно взять предварительно обученную сеть и использовать ее в качестве начальной точки, чтобы изучить новую задачу. Подстройка сети с передачей обучения обычно намного быстрее и легче, чем обучение сети со случайным образом инициализированными весами с нуля. Можно быстро передать изученные функции новой задаче с помощью меньшего числа учебных изображений.
Загружать предварительно обученную сеть ResNet-18, введите:
snet = resnet18;
Просмотреть слои предварительно обученной сети, введите:
analyzeNetwork(snet);
Первый слой, входной слой для изображений, требует входных изображений размера 227 227 3, где 3 количество цветовых каналов.
inputSize = snet.Layers(1).InputSize;
Этот пример использует MathWorks
Набор данных MerchData. Это - небольшой набор данных, содержащий 75 изображений товаров MathWorks, принадлежа пяти различным классам (дно, куб, игра в карты, отвертка и факел).
curDir = pwd; unzip('MerchData.zip'); imds = imageDatastore('MerchData', ... 'IncludeSubfolders',true, ... 'LabelSource','foldernames'); [imdsTrain,imdsValidation] = splitEachLabel(imds,0.7,'randomized');
Полносвязный слой и слой классификации предварительно обученной сети net
сконфигурированы для 1 000 классов. Эти два слоя 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, но изображения в хранилищах данных изображений имеют различные размеры. Используйте увеличенный datastore изображений, чтобы автоматически изменить размер учебных изображений. Задайте дополнительные операции увеличения, чтобы выполнить на учебных изображениях, таких как случайное зеркальное отражение учебных изображений вдоль вертикальной оси и случайным образом перевода их до 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™ и поддерживаемого устройства графического процессора. Для получения дополнительной информации смотрите Поддержку графического процессора Релизом (Parallel Computing Toolbox)). В противном случае сеть использует центральный процессор (требует Интерфейса MATLAB Coder для Глубокого обучения Libraries™). Можно также задать среду выполнения при помощи 'ExecutionEnvironment'
аргумент значения имени trainingOptions
.
netTransfer = trainNetwork(augimdsTrain,lgraph,options);
Создайте dlquantizer
возразите и задайте сеть, чтобы квантовать.
dlquantObj = dlquantizer(netTransfer,'ExecutionEnvironment','FPGA');
Используйте calibrate
функционируйте, чтобы осуществить сеть с демонстрационными входными параметрами и собрать информацию области значений. calibrate
функционируйте осуществляет сеть и собирает динамические диапазоны весов и смещений в свертке и полносвязных слоях сети и динамические диапазоны активаций во всех слоях сети. 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™ Установки 2019.2. Установить Xilinx Vivado toolpath, введите:
% 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'