Глубокое обучение является мощным методом машинного обучения, который можно использовать, чтобы обучить устойчивые детекторы объектов. Несколько методов для обнаружения объектов существуют, включая Faster R-CNN и вы только смотрите однажды (YOLO) v2.
Обучайтесь и развернитесь, вы смотрят только однажды (YOLO) v2 детектор объектов при помощи dlhdl.Workflow
объект.
Этот пример использует набор данных небольшого транспортного средства, который содержит 295 изображений. Многие из этих изображений прибывают из Автомобилей Калифорнийского технологического института 1 999 и 2 001 набор данных, используемый с разрешением и доступный в Калифорнийском технологическом институте Вычислительный веб-сайт Видения, созданный Пьетро Пероной. Каждое изображение содержит один или два помеченных экземпляра транспортного средства. Маленький набор данных полезен для исследования метода обучения YOLO v2, но на практике, более помеченные изображения необходимы, чтобы обучить устойчивый детектор. Извлеките изображения транспортного средства и загрузите достоверные данные транспортного средства.
unzip vehicleDatasetImages.zip data = load('vehicleDatasetGroundTruth.mat'); vehicleDataset = data.vehicleDataset;
Данные о транспортном средстве хранятся в двухколоночной таблице, где в первом столбце содержатся пути к файлам изображений, а во втором-ограничительные рамки транспортного средства.
% Add the fullpath to the local vehicle data folder.
vehicleDataset.imageFilename = fullfile(pwd,vehicleDataset.imageFilename);
Разделите набор данных в наборы обучающих данных и наборы тестов. Выберите 60% данных для обучения и используйте остальных для тестирования обученного детектора.
rng(0); shuffledIndices = randperm(height(vehicleDataset)); idx = floor(0.6 * length(shuffledIndices) ); trainingDataTbl = vehicleDataset(shuffledIndices(1:idx),:); testDataTbl = vehicleDataset(shuffledIndices(idx+1:end),:);
Используйте imageDatastore
и boxLabelDatastore
создать хранилища данных для загрузки изображения и данных о метке во время обучения и оценки.
imdsTrain = imageDatastore(trainingDataTbl{:,'imageFilename'}); bldsTrain = boxLabelDatastore(trainingDataTbl(:,'vehicle')); imdsTest = imageDatastore(testDataTbl{:,'imageFilename'}); bldsTest = boxLabelDatastore(testDataTbl(:,'vehicle'));
Объедините изображение и хранилища данных метки поля.
trainingData = combine(imdsTrain,bldsTrain); testData = combine(imdsTest,bldsTest);
Сеть обнаружения объектов YOLO v2 состоит из двух подсетей: сеть извлечения признаков сопровождается сетью обнаружения. Сеть извлечения признаков обычно является предварительно обученным CNN (для получения дополнительной информации смотрите Предварительно обученные Глубокие нейронные сети). Этот пример использует AlexNet для извлечения признаков. Можно также использовать другие предварительно обученные сети, такие как MobileNet v2, или ResNet-18 может также использоваться в зависимости от требований к приложению. Подсеть обнаружения является маленьким CNN по сравнению с сетью извлечения признаков и состоит из нескольких сверточных слоев и слоев, специфичных для YOLO v2.
Используйте yolov2Layers
функция, чтобы создать сеть обнаружения объектов YOLO v2. yolov2Layers
funcvtion требует, чтобы вы задали несколько входных параметров, которые параметрируют сеть YOLO v2:
Сетевой входной размер
Поля привязки
Сеть извлечения признаков
Во-первых, укажите размер входного сигнала сети и количество классов. При выборе размера входного сигнала сети учитывайте минимальный размер, требуемый самой сетью, размер обучающих изображений и вычислительные затраты, связанные с обработкой данных при выбранном размере. Когда это возможно, выберите размер входного сигнала сети, который близок к размеру обучающего изображения и больше, чем размер входного сигнала, необходимый для сети. Чтобы уменьшать вычислительную стоимость выполнения примера, задайте сетевой входной размер 224 224 3, который является минимальным размером, требуемым запускать сеть.
inputSize = [224 224 3];
Задайте количество классов объектов, чтобы обнаружить.
numClasses = width(vehicleDataset)-1;
Учебные изображения, используемые в этом примере, больше, чем 224 224 и отличаются по размеру, таким образом, необходимо изменить размер изображений на шаге предварительной обработки до обучения.
Затем используйте estimateAnchorBoxes
функционируйте, чтобы оценить поля привязки на основе размера объектов в обучающих данных. С учетом изменения размеров изображений до обучения измените размер обучающих данных для оценки полей привязки. Используйте transform
функция, чтобы предварительно обработать обучающие данные и затем задать количество полей привязки и оценить поля привязки. Измените размер обучающих данных к входному размеру изображения сети при помощи функции поддержки yolo_preprocessData
, присоединенный к этому примеру.
Для получения дополнительной информации о выборе полей привязки смотрите Оценочные Поля Привязки От Обучающих данных (Computer Vision Toolbox) (Computer Vision Toolbox™) и Поля Привязки для Обнаружения объектов (Computer Vision Toolbox).
trainingDataForEstimation = transform(trainingData,@(data)yolo_preprocessData(data,inputSize)); numAnchors = 7; [anchorBoxes, meanIoU] = estimateAnchorBoxes(trainingDataForEstimation, numAnchors)
anchorBoxes = 7×2
145 126
91 86
161 132
41 34
67 64
136 111
33 23
meanIoU = 0.8651
Используйте alexnet
функционируйте, чтобы загрузить предварительно обученную модель.
featureExtractionNetwork = alexnet
featureExtractionNetwork = SeriesNetwork with properties: Layers: [25×1 nnet.cnn.layer.Layer] InputNames: {'data'} OutputNames: {'output'}
Выберите 'relu5'
как слой извлечения признаков, чтобы заменить слои после 'relu5'
с подсетью обнаружения. Этот слой извлечения объектов выводит карты объектов, которые уменьшены в 16 раз. Этот объем субдискретизации является хорошим компромиссом между пространственным разрешением и силой извлеченных функций, когда функции, извлеченные дальше вниз сеть, кодируют более сильные функции изображений за счет пространственного разрешения.
featureLayer = 'relu5';
Создайте сеть обнаружения объектов YOLO v2.
lgraph = yolov2Layers(inputSize,numClasses,anchorBoxes,featureExtractionNetwork,featureLayer);
Можно визуализировать сеть при помощи analyzeNetwork
функционируйте или Deep Network Designer от Deep Learning Toolbox™.
Если вы требуете большего количества управления архитектурой сети YOLO v2, используйте Deep Network Designer, чтобы спроектировать сеть обнаружения YOLO v2 вручную. Для получения дополнительной информации см. Проект Сеть обнаружения YOLO v2 (Computer Vision Toolbox).
Увеличение данных используется, чтобы улучшить сетевую точность путем случайного преобразования исходных данных во время обучения. При помощи увеличения данных можно добавить больше разнообразия в обучающие данные, на самом деле не имея необходимость увеличить число помеченных обучающих выборок.
Используйте transform
функционируйте, чтобы увеличить обучающие данные путем случайного зеркального отражения изображения и сопоставленных меток поля горизонтально. Обратите внимание на то, что увеличение данных не применяется к данным о валидации и тесту. Идеально, данные о тесте и валидации являются представительными для исходных данных и оставлены немодифицированными для несмещенной оценки.
augmentedTrainingData = transform(trainingData,@yolo_augmentData);
Предварительно обработайте увеличенные обучающие данные и данные о валидации, чтобы подготовиться к обучению.
preprocessedTrainingData = transform(augmentedTrainingData,@(data)yolo_preprocessData(data,inputSize));
Используйте trainingOptions
функция, чтобы задать сетевые опции обучения. Установите 'ValidationData'
к предварительно обработанным данным о валидации. Установите 'CheckpointPath'
к временному местоположению. Настройки Thse включают сохранение частично обученных детекторов во время учебного процесса. Если обучение прервано, такой как отключением электроэнергии или системным отказом, можно возобновить обучение с сохраненной контрольной точки.
options = trainingOptions('sgdm', ... 'MiniBatchSize', 16, .... 'InitialLearnRate',1e-3, ... 'MaxEpochs',20,... 'CheckpointPath', tempdir, ... 'Shuffle','never');
Используйте trainYOLOv2ObjectDetector
функция, чтобы обучить детектор объектов YOLO v2.
[detector,info] = trainYOLOv2ObjectDetector(preprocessedTrainingData,lgraph,options);
************************************************************************* Training a YOLO v2 Object Detector for the following object classes: * vehicle Training on single CPU. Initializing input data normalization. |========================================================================================| | Epoch | Iteration | Time Elapsed | Mini-batch | Mini-batch | Base Learning | | | | (hh:mm:ss) | RMSE | Loss | Rate | |========================================================================================| | 1 | 1 | 00:00:02 | 7.23 | 52.3 | 0.0010 | | 5 | 50 | 00:00:43 | 0.99 | 1.0 | 0.0010 | | 10 | 100 | 00:01:24 | 0.77 | 0.6 | 0.0010 | | 14 | 150 | 00:02:03 | 0.64 | 0.4 | 0.0010 | | 19 | 200 | 00:02:41 | 0.57 | 0.3 | 0.0010 | | 20 | 220 | 00:02:55 | 0.58 | 0.3 | 0.0010 | |========================================================================================| Detector training complete. *************************************************************************
Как быстрый тест, запустите детектор на одном тестовом изображении. Убедитесь, что вы изменяете размер изображения к тому же размеру как учебные изображения.
I = imread(testDataTbl.imageFilename{2}); I = imresize(I,inputSize(1:2)); [bboxes,scores] = detect(detector,I);
Отобразите результаты.
I_new = insertObjectAnnotation(I,'rectangle',bboxes,scores);
figure
imshow(I_new)
Загрузите предварительно обученную сеть.
snet=detector.Network; I_pre=yolo_pre_proc(I);
Используйте analyzeNetwork
функция
получить информацию о слоях сети.
analyzeNetwork(snet)
Создайте целевой объект для своего целевого устройства с именем поставщика и интерфейсом, чтобы соединить ваше целевое устройство к хосту - компьютеру. Интерфейсные опции являются JTAG (значение по умолчанию) и Ethernet. Опциями поставщика является Intel или Xilinx. Используйте установленный Набор Проекта Xilinx Vivado по соединению Ethernet, чтобы программировать устройство.
hTarget = dlhdl.Target('Xilinx','Interface','Ethernet');
Создайте объект dlhdl.Workflow
класс. Задайте сеть и имя потока битов. Задайте сохраненную предварительно обученную серийную сеть trainedNetNoCar
как сеть. Убедитесь, что имя потока битов совпадает с типом данных и платой FPGA, для которой вы предназначаетесь. В этом примере целевая плата FPGA является Zynq UltraScale + плата MPSoC ZCU102. Поток битов использует один тип данных.
hW=dlhdl.Workflow('Network', snet, 'Bitstream', 'zcu102_single','Target',hTarget)
hW = Workflow with properties: Network: [1×1 DAGNetwork] Bitstream: 'zcu102_single' ProcessorConfig: [] Target: [1×1 dlhdl.Target]
Скомпилировать snet
серийная сеть, запуск функция компиляции dlhdl.Workflo
w объект.
dn = hW.compile
### Compiling network for Deep Learning FPGA prototyping ... ### Targeting FPGA bitstream zcu102_single ... ### The network includes the following layers: 1 'data' Image Input 224×224×3 images with 'zerocenter' normalization (SW Layer) 2 'conv1' Convolution 96 11×11×3 convolutions with stride [4 4] and padding [0 0 0 0] (HW Layer) 3 'relu1' ReLU ReLU (HW Layer) 4 'norm1' Cross Channel Normalization cross channel normalization with 5 channels per element (HW Layer) 5 'pool1' Max Pooling 3×3 max pooling with stride [2 2] and padding [0 0 0 0] (HW Layer) 6 'conv2' Grouped Convolution 2 groups of 128 5×5×48 convolutions with stride [1 1] and padding [2 2 2 2] (HW Layer) 7 'relu2' ReLU ReLU (HW Layer) 8 'norm2' Cross Channel Normalization cross channel normalization with 5 channels per element (HW Layer) 9 'pool2' Max Pooling 3×3 max pooling with stride [2 2] and padding [0 0 0 0] (HW Layer) 10 'conv3' Convolution 384 3×3×256 convolutions with stride [1 1] and padding [1 1 1 1] (HW Layer) 11 'relu3' ReLU ReLU (HW Layer) 12 'conv4' Grouped Convolution 2 groups of 192 3×3×192 convolutions with stride [1 1] and padding [1 1 1 1] (HW Layer) 13 'relu4' ReLU ReLU (HW Layer) 14 'conv5' Grouped Convolution 2 groups of 128 3×3×192 convolutions with stride [1 1] and padding [1 1 1 1] (HW Layer) 15 'relu5' ReLU ReLU (HW Layer) 16 'yolov2Conv1' Convolution 256 3×3×256 convolutions with stride [1 1] and padding 'same' (HW Layer) 17 'yolov2Batch1' Batch Normalization Batch normalization with 256 channels (HW Layer) 18 'yolov2Relu1' ReLU ReLU (HW Layer) 19 'yolov2Conv2' Convolution 256 3×3×256 convolutions with stride [1 1] and padding 'same' (HW Layer) 20 'yolov2Batch2' Batch Normalization Batch normalization with 256 channels (HW Layer) 21 'yolov2Relu2' ReLU ReLU (HW Layer) 22 'yolov2ClassConv' Convolution 42 1×1×256 convolutions with stride [1 1] and padding [0 0 0 0] (HW Layer) 23 'yolov2Transform' YOLO v2 Transform Layer. YOLO v2 Transform Layer with 7 anchors. (SW Layer) 24 'yolov2OutputLayer' YOLO v2 Output YOLO v2 Output with 7 anchors. (SW Layer) ### Optimizing series network: Fused 'nnet.cnn.layer.BatchNormalizationLayer' into 'nnet.cnn.layer.Convolution2DLayer' 2 Memory Regions created. Skipping: data Compiling leg: conv1>>yolov2ClassConv ... Compiling leg: conv1>>yolov2ClassConv ... complete. Skipping: yolov2Transform Skipping: yolov2OutputLayer 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" "0.0 MB" "SystemBufferOffset" "0x01c00000" "28.0 MB" "InstructionDataOffset" "0x03800000" "4.0 MB" "ConvWeightDataOffset" "0x03c00000" "16.0 MB" "EndOffset" "0x04c00000" "Total: 76.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]
Чтобы развернуть сеть на Zynq® UltraScale +™ оборудование MPSoC ZCU102, запустите развернуть функцию dlhdl.Workflow
объект. Эта функция использует выход функции компиляции, чтобы программировать плату FPGA при помощи файла программирования. Функция также загружает сетевые веса и смещения. Развернуть функция проверяет на инструмент Xilinx Vivado и поддерживаемую версию инструмента. Это затем начинает программировать устройство FPGA при помощи потока битов и отображает сообщения о ходе выполнения и время, которое требуется, чтобы развернуть сеть.
hW.deploy
### FPGA bitstream programming has been skipped as the same bitstream is already loaded on the target FPGA. ### Loading weights to Conv Processor. ### Conv Weights loaded. Current time is 20-Dec-2020 15:26:28
Выполните предсказать функцию на dlhdl.Workflow
возразите и отобразите результат.
[prediction, speed] = hW.predict(I_pre,'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 8615567 0.03916 1 8615567 25.5 conv1 1357049 0.00617 norm1 569406 0.00259 pool1 205869 0.00094 conv2 2207222 0.01003 norm2 360973 0.00164 pool2 197444 0.00090 conv3 976419 0.00444 conv4 761188 0.00346 conv5 521782 0.00237 yolov2Conv1 660213 0.00300 yolov2Conv2 661162 0.00301 yolov2ClassConv 136816 0.00062 * The clock frequency of the DL processor is: 220MHz
Отобразите результаты предсказания.
[bboxesn, scoresn, labelsn] = yolo_post_proc(prediction,I_pre,anchorBoxes,{'Vehicle'}); I_new3 = insertObjectAnnotation(I,'rectangle',bboxesn,scoresn); figure imshow(I_new3)