Создайте Сеть обнаружения объектов 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'
        AverageImage: []

% 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 function.