В этом примере показано, как импортировать предварительно обученную ONNX™ (Open Neural Network Exchange), которую вы смотрите только один раз (YOLO) v2 [1] сети обнаружения объектов и используете ее для обнаружения объектов. После импорта сети ее можно развернуть на встраиваемых платформах с помощью GPU Coder™ или переобучить на пользовательских данных с помощью передачи обучения с trainYOLOv2ObjectDetector
.
Загрузите файлы, относящиеся к предварительно обученной сети Tiny YOLO v2.
pretrainedURL = 'https://ssd.mathworks.com/supportfiles/vision/deeplearning/models/yolov2/tiny_yolov2.tar'; pretrainedNetTar = 'yolov2Tiny.tar'; if ~exist(pretrainedNetTar,'file') disp('Downloading pretrained network (58 MB)...'); websave(pretrainedNetTar,pretrainedURL); end
Downloading pretrained network (58 MB)...
Чтобы извлечь сеть Tiny YOLO v2, распакуйте загруженный файл. Загрузите 'Model.onnx'
модель из tiny_yolov2
папка, которая является сетью ONNX YOLO v2, предварительно обученной на наборе данных PASCAL VOC. Сеть может обнаруживать объекты из 20 различных классов [4].
onnxfiles = untar(pretrainedNetTar);
pretrainedNet = 'tiny_yolov2/Model.onnx';
Используйте importONNXLayers
функция для импорта загруженной сети.
lgraph = importONNXLayers(pretrainedNet,'ImportWeights',true);
Warning: Imported layers have no output layer because ONNX files do not specify the network's output layer type. The layers will not be trainable until an output layer is added. Either add an output layer to the imported layers, or specify the output layer type using 'OutputLayerType' in the call to importONNXLayers.
В этом примере вы добавляете слой выхода к импортированным слоям, поэтому можно игнорировать это предупреждение. В разделе Add YOLO v2 Transform and Output Layers показано, как добавить выходной слой YOLO v2 вместе со слоем YOLO v2 Transform к импортированным слоям.
Сеть в этом примере не содержит неподдерживаемых слоев. Обратите внимание, что если импортируемая сеть имеет неподдерживаемые слои, функция импортирует их как слои-заполнители. Перед использованием импортированной сети необходимо заменить эти слои. Дополнительные сведения о замене слоев-заполнителей см. в разделе findPlaceholderLayers
(Deep Learning Toolbox).
YOLO v2 использует предопределенные якорные рамки для предсказания местоположения объекта. Анкерные ящики, используемые в импортированной сети, определены в файле строения сети Tiny YOLO v2 [5]. Якоря ONNX заданы относительно выхода размера конечного слоя свертки, который составляет 13 на 13. Как использовать якоря с yolov2ObjectDetector
измените размер анкерных блоков на размер входного сигнала сети, который составляет 416 416. Якорные коробки для yolov2ObjectDetector
необходимо указать в форме [высота, ширина].
onnxAnchors = [1.08,1.19; 3.42,4.41; 6.63,11.38; 9.42,5.11; 16.62,10.52]; inputSize = lgraph.Layers(1,1).InputSize(1:2); lastActivationSize = [13,13]; upScaleFactor = inputSize./lastActivationSize; anchorBoxesTmp = upScaleFactor.* onnxAnchors; anchorBoxes = [anchorBoxesTmp(:,2),anchorBoxesTmp(:,1)];
Для эффективной обработки необходимо переупорядочить веса и смещения последнего слоя свертки в импортированной сети, чтобы получить активации в расположении, которое yolov2ObjectDetector
требует. yolov2ObjectDetector
ожидает 125 каналов карты функций последнего слоя свертки в следующем расположении:
Каналы с 1 по 5 - значения IoU для пяти якорей
Каналы с 6 по 10 - значения X для пяти якорей
Каналы с 11 по 15 - значения Y для пяти якорей
Каналы с 16 по 20 - Значения ширины для пяти якорей
Каналы с 21 по 25 - Значения высоты для пяти якорей
Каналы с 26 по 30 - значения вероятностей класса 1 для пяти якорей
Каналы с 31 по 35 - значения вероятностей класса 2 для пяти якорей
Каналы с 121 по 125 - значения вероятностей класса 20 для пяти якорей
Однако в последнем слое свертки, который имеет размер 13 на 13, активации расположены по-другому. Каждый из 25 каналов в карте функций соответствует:
Канал 1 - значения X
Канал 2 - значения Y
Канал 3 - Значения ширины
Канал 4 - Значения высоты
Канал 5 - значения IoU
Канал 6 - значения вероятностей класса 1
Канал 7 - значения вероятностей класса 2
Канал 25 - значения вероятностей класса 20
Используйте вспомогательную функцию rearrangeONNXWeights
, перечисленный в конце этого примера, чтобы переупорядочить веса и смещения последнего слоя свертки в импортированной сети и получить активации в формате, требуемом yolov2ObjectDetector
.
weights = lgraph.Layers(end,1).Weights; bias = lgraph.Layers(end,1).Bias; layerName = lgraph.Layers(end,1).Name; numAnchorBoxes = size(onnxAnchors,1); [modWeights,modBias] = rearrangeONNXWeights(weights,bias,numAnchorBoxes);
Замените веса и смещения последнего слоя свертки в импортированной сети новым слоем свертки с помощью переупорядоченных весов и смещений.
filterSize = size(modWeights,[1 2]); numFilters = size(modWeights,4); modConvolution8 = convolution2dLayer(filterSize,numFilters,... 'Name',layerName,'Bias',modBias,'Weights',modWeights); lgraph = replaceLayer(lgraph,'convolution8',modConvolution8);
Сеть обнаружения YOLO v2 требует слоев преобразования YOLO v2 и выхода YOLO v2. Создайте оба этих слоев, сложите их последовательно и присоедините слой преобразования YOLO v2 к последнему слою свертки.
classNames = tinyYOLOv2Classes; layersToAdd = [ yolov2TransformLayer(numAnchorBoxes,'Name','yolov2Transform'); yolov2OutputLayer(anchorBoxes,'Classes',classNames,'Name','yolov2Output'); ]; lgraph = addLayers(lgraph, layersToAdd); lgraph = connectLayers(lgraph,layerName,'yolov2Transform');
The ElementwiseAffineLayer
в импортированной сети дублирует шаг предварительной обработки, выполненный yolov2ObjectDetector
. Следовательно, удалите ElementwiseAffineLayer
из импортированной сети.
yoloScaleLayerIdx = find(... arrayfun( @(x)isa(x,'nnet.onnx.layer.ElementwiseAffineLayer'), ... lgraph.Layers)); if ~isempty(yoloScaleLayerIdx) for i = 1:size(yoloScaleLayerIdx,1) layerNames {i} = lgraph.Layers(yoloScaleLayerIdx(i,1),1).Name; end lgraph = removeLayers(lgraph,layerNames); lgraph = connectLayers(lgraph,'Input_image','convolution'); end
Соберите график слоев с помощью assembleNetwork
и создайте детектор объектов YOLO v2 с помощью yolov2ObjectDetector
функция.
net = assembleNetwork(lgraph)
net = DAGNetwork with properties: Layers: [34×1 nnet.cnn.layer.Layer] Connections: [33×2 table] InputNames: {'Input_image'} OutputNames: {'yolov2Output'}
yolov2Detector = yolov2ObjectDetector(net)
yolov2Detector = yolov2ObjectDetector with properties: ModelName: 'importedNetwork' Network: [1×1 DAGNetwork] TrainingImageSize: [416 416] AnchorBoxes: [5×2 double] ClassNames: [aeroplane bicycle bird boat bottle bus car cat chair cow diningtable dog horse motorbike person pottedplant sheep sofa train tvmonitor]
Используйте импортированный детектор для обнаружения объектов в тестовом изображении. Отображение результатов.
I = imread('highway.png'); % Convert image to BGR format. Ibgr = cat(3,I(:,:,3),I(:,:,2),I(:,:,1)); [bboxes, scores, labels] = detect(yolov2Detector, Ibgr); detectedImg = insertObjectAnnotation(I, 'rectangle', bboxes, scores); figure imshow(detectedImg);
function [modWeights,modBias] = rearrangeONNXWeights(weights,bias,numAnchorBoxes) %rearrangeONNXWeights rearranges the weights and biases of an imported YOLO %v2 network as required by yolov2ObjectDetector. numAnchorBoxes is a scalar %value containing the number of anchors that are used to reorder the weights and %biases. This function performs the following operations: % * Extract the weights and biases related to IoU, boxes, and classes. % * Reorder the extracted weights and biases as expected by yolov2ObjectDetector. % * Combine and reshape them back to the original dimensions. weightsSize = size(weights); biasSize = size(bias); sizeOfPredictions = biasSize(3)/numAnchorBoxes; % Reshape the weights with regard to the size of the predictions and anchors. reshapedWeights = reshape(weights,prod(weightsSize(1:3)),sizeOfPredictions,numAnchorBoxes); % Extract the weights related to IoU, boxes, and classes. weightsIou = reshapedWeights(:,5,:); weightsBoxes = reshapedWeights(:,1:4,:); weightsClasses = reshapedWeights(:,6:end,:); % Combine the weights of the extracted parameters as required by % yolov2ObjectDetector. reorderedWeights = cat(2,weightsIou,weightsBoxes,weightsClasses); permutedWeights = permute(reorderedWeights,[1 3 2]); % Reshape the new weights to the original size. modWeights = reshape(permutedWeights,weightsSize); % Reshape the biases with regared to the size of the predictions and anchors. reshapedBias = reshape(bias,sizeOfPredictions,numAnchorBoxes); % Extract the biases related to IoU, boxes, and classes. biasIou = reshapedBias(5,:); biasBoxes = reshapedBias(1:4,:); biasClasses = reshapedBias(6:end,:); % Combine the biases of the extracted parameters as required by yolov2ObjectDetector. reorderedBias = cat(1,biasIou,biasBoxes,biasClasses); permutedBias = permute(reorderedBias,[2 1]); % Reshape the new biases to the original size. modBias = reshape(permutedBias,biasSize); end function classes = tinyYOLOv2Classes() % Return the class names corresponding to the pretrained ONNX tiny YOLO v2 % network. % % The tiny YOLO v2 network is pretrained on the Pascal VOC data set, % which contains images from 20 different classes [4]. classes = [ ... " aeroplane", "bicycle", "bird", "boat", "bottle", "bus", "car",... "cat", "chair", "cow", "diningtable", "dog", "horse", "motorbike",... "person", "pottedplant", "sheep", "sofa", "train", "tvmonitor"]; end
[1] Редмон, Джозеф и Али Фархади. «YOLO9000: Лучше, Быстрее, Сильнее». В 2017 году IEEE Conference on Компьютерное Зрение and Pattern Recognition (CVPR), 6517-25. Гонолулу, HI: IEEE, 2017. https://doi.org/10.1109/CVPR.2017.690.
[2] «Tiny YOLO v2 Model». https://github.com/onnx/models/tree/master/vision/object_detection_segmentation/tiny-yolov2
[3] «Tiny YOLO v2 Model License».
https://github.com/onnx/onnx/blob/master/LICENSE.
[4] Эверингем, Марк, Люк Ван Голь, Кристофер К. И. Уильямс, Джон Уинн и Эндрю Зиссерман. «Вызов Pascal Visual Классы (LOS)». Международный журнал компьютерного зрения 88, № 2 (июнь 2010): 303-38. https://doi.org/10.1007/s11263-009-0275-4.
[5] «yolov2-tiny-voc.cfg» https://github.com/pjreddie/darknet/blob/master/cfg/yolov2-tiny-voc.cfg.