В этом примере показано, как изменить предварительно обученную сеть MobileNet v2 для создания сети обнаружения объектов YOLO v2.
Процедура преобразования предварительно обученной сети в сеть YOLO v2 аналогична процедуре передачи обучения для классификации изображений:
Загрузите предварительно обученную сеть.
Выберите слой из предварительно обученной сети для редукции данных.
Удалите все слои после слоя редукции данных.
Добавьте новые слои для поддержки задачи обнаружения объектов.
Загрузка предварительно обученной сети MobileNet v2 с помощью mobilenetv2
. Для этого требуется модель поддержки Deep Learning Toolbox Model для Network™ MobileNet v2. Если этот пакет поддержки не установлен, то функция предоставляет ссылку на загрузку. После загрузки сети преобразуйте сеть в layerGraph
объект, чтобы можно было управлять слоями.
net = mobilenetv2(); lgraph = layerGraph(net);
Обновите размер входа сети, чтобы соответствовать требованиям к обучающим данным. Для примера предположим, что обучающие данные являются изображениями 300 на 300 RGB. Установите размер входа.
imageInputSize = [300 300 3];
Затем создайте новый входной слой для изображений с таким же именем, как и исходный слой.
imgLayer = imageInputLayer(imageInputSize,"Name","input_1")
imgLayer = ImageInputLayer with properties: Name: 'input_1' InputSize: [300 300 3] Hyperparameters DataAugmentation: 'none' Normalization: 'zerocenter' NormalizationDimension: 'auto' Mean: []
Замените старый входной слой изображения новым входным слоем изображения.
lgraph = replaceLayer(lgraph,"input_1",imgLayer);
Слой редукции данных YOLO v2 наиболее эффективен, когда ширина и высота выхода функции в 8-16 раз меньше, чем вход изображение. Такое количество понижающей дискретизации является компромиссом между пространственным разрешением и качеством выходных признаков. Можно использовать analyzeNetwork
функцию или приложение Deep Network Designer, чтобы определить выходные размеры слоев в сети. Обратите внимание, что выбор оптимального слоя редукции данных требует эмпирической оценки.
Установите слой редукции данных равным "block_12_add".
Размер выхода этого слоя примерно в 16 раза меньше, чем размер входа изображения 300 на 300.
featureExtractionLayer = "block_12_add";
Затем удалите слои после редукции данных. Это можно сделать, импортировав сеть в приложение Deep Network Designer, вручную удалив слои и экспортировав измененную сеть в рабочую область.
В данном примере загружает измененную сеть, которая была добавлена в этот пример как вспомогательный файл.
modified = load("mobilenetv2Block12Add.mat");
lgraph = modified.mobilenetv2Block12Add;
Подсеть обнаружения состоит из групп последовательно связанных слоев свертки, ReLU и нормализации партии .. Эти слои следуют за yolov2TransformLayer
и a yolov2OutputLayer
.
Сначала создайте две группы последовательно связанных слоев свертки, ReLU и нормализации партии .. Установите размер фильтра слоя свертки 3 на 3 и количество фильтров, чтобы соответствовать количеству каналов в выходном слое редукции данных. Задайте "same"
заполнение в слое свертки для сохранения входа.
filterSize = [3 3]; numFilters = 96; detectionLayers = [ convolution2dLayer(filterSize,numFilters,"Name","yolov2Conv1","Padding", "same", "WeightsInitializer",@(sz)randn(sz)*0.01) batchNormalizationLayer("Name","yolov2Batch1") reluLayer("Name","yolov2Relu1") convolution2dLayer(filterSize,numFilters,"Name","yolov2Conv2","Padding", "same", "WeightsInitializer",@(sz)randn(sz)*0.01) batchNormalizationLayer("Name","yolov2Batch2") reluLayer("Name","yolov2Relu2") ]
detectionLayers = 6x1 Layer array with layers: 1 'yolov2Conv1' Convolution 96 3x3 convolutions with stride [1 1] and padding 'same' 2 'yolov2Batch1' Batch Normalization Batch normalization 3 'yolov2Relu1' ReLU ReLU 4 'yolov2Conv2' Convolution 96 3x3 convolutions with stride [1 1] and padding 'same' 5 'yolov2Batch2' Batch Normalization Batch normalization 6 'yolov2Relu2' ReLU ReLU
Затем создайте конечный фрагмент подсети обнаружения, которая имеет слой свертки, за которым следует yolov2TransformLayer
и a yolov2OutputLayer
. Выходные выходы слоя свертки предсказывают следующее для каждого якорного ящика:
Вероятности класса объекта.
Смещение местоположения X и Y.
Смещение ширины и высоты.
Укажите якорные рамки и количество классов и вычислите количество фильтров для слоя свертки.
numClasses = 5; anchorBoxes = [ 16 16 32 16 ]; numAnchors = size(anchorBoxes,1); numPredictionsPerAnchor = 5; numFiltersInLastConvLayer = numAnchors*(numClasses+numPredictionsPerAnchor);
Добавьте convolution2dLayer
, yolov2TransformLayer
, и yolov2OutputLayer
в подсеть обнаружения.
detectionLayers = [ detectionLayers convolution2dLayer(1,numFiltersInLastConvLayer,"Name","yolov2ClassConv",... "WeightsInitializer", @(sz)randn(sz)*0.01) yolov2TransformLayer(numAnchors,"Name","yolov2Transform") yolov2OutputLayer(anchorBoxes,"Name","yolov2OutputLayer") ]
detectionLayers = 9x1 Layer array with layers: 1 'yolov2Conv1' Convolution 96 3x3 convolutions with stride [1 1] and padding 'same' 2 'yolov2Batch1' Batch Normalization Batch normalization 3 'yolov2Relu1' ReLU ReLU 4 'yolov2Conv2' Convolution 96 3x3 convolutions with stride [1 1] and padding 'same' 5 'yolov2Batch2' Batch Normalization Batch normalization 6 'yolov2Relu2' ReLU ReLU 7 'yolov2ClassConv' Convolution 20 1x1 convolutions with stride [1 1] and padding [0 0 0 0] 8 'yolov2Transform' YOLO v2 Transform Layer. YOLO v2 Transform Layer with 2 anchors. 9 'yolov2OutputLayer' YOLO v2 Output YOLO v2 Output with 2 anchors.
Присоедините подсеть обнаружения к сети редукции данных.
lgraph = addLayers(lgraph,detectionLayers);
lgraph = connectLayers(lgraph,featureExtractionLayer,"yolov2Conv1");
Использование analyzeNetwork(lgraph)
чтобы проверить сеть, а затем обучить детектор объектов YOLO v2 с помощью trainYOLOv2ObjectDetector
функция.