Создайте Сеть обнаружения объектов YOLO v2

В этом примере показано, как изменить предварительно обученную сеть MobileNet v2, чтобы создать сеть обнаружения объектов YOLO v2. Этот подход предлагает дополнительную гибкость по сравнению с yolov2Layers функция, которая возвращает канонический детектор объектов YOLO v2.

Процедура, чтобы преобразовать предварительно обученную сеть в сеть YOLO v2 похожа на процедуру изучения передачи для классификации изображений:

  1. Загрузите предварительно обученную сеть.

  2. Выберите слой из предварительно обученной сети, чтобы использовать в извлечении признаков.

  3. Удалите все слои после слоя извлечения признаков.

  4. Добавьте новые слои, чтобы поддержать задачу обнаружения объектов.

Можно также реализовать эту процедуру с помощью deepNetworkDesigner приложение.

Загрузите предварительно обученную сеть

Загрузите предварительно обученную сеть MobileNet v2 использование mobilenetv2. Это требует Модели Deep Learning Toolbox для MobileNet v2 Network™.

% Load a pretrained network.
net = mobilenetv2();

% Convert network into a layer graph object
% in order to manipulate the layers.
lgraph = layerGraph(net);

Обновите сетевой размер изображения

Измените размер изображения сети на основе требований обучающих данных. Чтобы проиллюстрировать этот шаг, примите, что необходимый размер изображения [300 300 3] для изображений RGB.

% Input size for detector.
imageInputSize = [300 300 3];

% Create new image input layer. Set the new layer name
% to the original layer name.
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: []

% Replace old image input layer.
lgraph = replaceLayer(lgraph,"input_1",imgLayer);

Выберите Feature Extraction Layer

Хороший слой извлечения признаков для YOLO v2 является тем, где выходная ширина функции и высота между в 8 и 16 раз меньше, чем входное изображение. Этот объем субдискретизации является компромиссом между пространственным разрешением и качеством выходных функций. analyzeNetwork приложение или deepNetworkDesigner приложение может использоваться, чтобы определить выходные размеры слоев в сети. Обратите внимание на то, что выбор оптимального слоя извлечения признаков требует эмпирической оценки.

Установите слой извлечения признаков на “block_12_add” от MobileNet v2. Поскольку необходимый входной размер был ранее установлен в [300 300], выходной размер элемента [19 19]. Это приводит к фактору субдискретизации приблизительно 16.

featureExtractionLayer = "block_12_add";

Удалите слои после слоя извлечения признаков

Чтобы легко удалить слои из глубокой сети, такие как MobileNet v2, используют deepNetworkDesigner приложение. Импортируйте сеть в приложение, чтобы вручную удалить слои после "block_12_add". Экспортируйте модифицированную сеть в свою рабочую область. Этот пример использует предварительную сохраненную версию MobileNet v2, который экспортировался из приложения.

% Load a network modified using Deep Network Designer.
modified = load("mobilenetv2Block12Add.mat");
lgraph = modified.mobilenetv2Block12Add;

В качестве альтернативы, если у вас есть список слоев, чтобы удалить, можно использовать removeLayers функция, чтобы удалить их вручную.

Создайте Подсеть обнаружения YOLO v2

Подсеть обнаружения состоит из групп последовательно связанной свертки, ReLU и пакетных слоев нормализации. Эти слои сопровождаются yolov2TransformLayer и yolov2OutputLayer.

Создайте свертку, ReLU, и обработайте фрагмент нормализации в пакетном режиме подсети обнаружения.

% Set the convolution layer filter size to [3 3].
% This size is common in CNN architectures. 
filterSize = [3 3];

% Set the number of filters in the convolution layers
% to match the number of channels in the
% feature extraction layer output.
numFilters = 96;

% Create the detection subnetwork.
% * The convolution layer uses "same" padding
%   to preserve the input size.
detectionLayers = [
    % group 1
    convolution2dLayer(filterSize,numFilters,"Name","yolov2Conv1",...
    "Padding", "same", "WeightsInitializer",@(sz)randn(sz)*0.01)
    batchNormalizationLayer("Name","yolov2Batch1");
    reluLayer("Name","yolov2Relu1");
    
    % group 2
    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

Оставшиеся слои сконфигурированы на основе специализированных деталей, таких как количество классов объектов и полей привязки.

% Define the number of classes to detect.
numClasses = 5;

% Define the anchor boxes.
anchorBoxes = [
    16 16
    32 16
    ];

% Number of anchor boxes.
numAnchors = size(anchorBoxes,1);

% There are five predictions per anchor box: 
%  * Predict the x, y, width, and height offset
%    for each anchor.
%  * Predict the intersection-over-union with ground
%    truth boxes.
numPredictionsPerAnchor = 5;

% Number of filters in last convolution layer.
outputSize = numAnchors*(numClasses+numPredictionsPerAnchor);

Создайте convolution2dLayer, yolov2Transform, и yolov2Output слои.

% Final layers in detection sub-network.
finalLayers = [
    convolution2dLayer(1,outputSize,"Name","yolov2ClassConv",...
    "WeightsInitializer", @(sz)randn(sz)*0.01)
    yolov2TransformLayer(numAnchors,"Name","yolov2Transform")
    yolov2OutputLayer(anchorBoxes,"Name","yolov2OutputLayer")
    ];

Добавьте последние слои в сеть.

% Add the last layers to network.
detectionLayers = [
    detectionLayers
    finalLayers
    ]
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

Полная Сеть обнаружения YOLO v2

Присоедините подсеть обнаружения к сети извлечения признаков.

% Add the detection subnetwork to the feature extraction network.
lgraph = addLayers(lgraph,detectionLayers);

% Connect the detection subnetwork to the feature extraction layer.
lgraph = connectLayers(lgraph,featureExtractionLayer,"yolov2Conv1");

Используйте analyzeNetwork(lgraph) проверять сеть и затем обучать детектор объектов YOLO v2 с помощью trainYOLOv2ObjectDetector функция.