Обучите детектор объектов Используя глубокое обучение R-CNN

В этом примере показано, как обучить детектор объектов с помощью глубокого обучения и R-CNN (области со Сверточными нейронными сетями).

Обзор

В этом примере показано, как обучить детектор объектов R-CNN обнаружению знаков Стоп. R-CNN является средой обнаружения объектов, которая использует сверточную нейронную сеть (CNN), чтобы классифицировать области изображений в изображении [1]. Вместо того, чтобы классифицировать каждую область с помощью раздвижного окна, детектор R-CNN только обрабатывает те области, которые, вероятно, будут содержать объект. Это значительно уменьшает вычислительную стоимость, понесенную при выполнении CNN.

Чтобы проиллюстрировать, как обучить детектор знака Стоп R-CNN, этот пример следует за рабочим процессом передачи обучения, который обычно используется в применении глубокого обучения. В передаче обучения сеть, обученная на большом количестве изображений, таких как ImageNet [2], используется в качестве начальной точки, чтобы решить новую классификацию или задачу обнаружения. Преимущество использования этого подхода состоит в том, что предварительно обученная сеть уже изучила богатый набор функций изображений, которые применимы к широкому спектру изображений. Это изучение передаваемо к новой задаче путем подстройки сети. Сеть подстраивается путем внесения маленьких корректировок в веса, таким образом, что представления функции, изученные для исходной задачи, немного настроены, чтобы поддержать новую задачу.

Преимущество передачи обучения состоит в том, что количество изображений, требуемых для обучения и учебное время, сокращено. Чтобы проиллюстрировать эти преимущества, этот пример обучает детектор знака Стоп с помощью рабочего процесса передачи обучения. Сначала CNN предварительно обучен с помощью набора данных CIFAR-10, который имеет 50 000 учебных изображений. Затем этот предварительно обученный CNN подстраивается для обнаружения знака Стоп, использующего всего 41 учебное изображение. Без предварительного обучения CNN обучение детектор знака Стоп потребовал бы значительно большего количества изображений.

Примечание: Этот пример требует Computer Vision Toolbox™, Image Processing Toolbox™, Deep Learning Toolbox™ и Statistics and Machine Learning Toolbox™.

Используя CUDA-способный графический процессор NVIDIA™ настоятельно рекомендован для выполнения этого примера. Использование графического процессора требует Parallel Computing Toolbox™. Для получения информации о поддерживаемом вычислите возможности, смотрите Поддержку графического процессора Релизом (Parallel Computing Toolbox).

Загрузите данные изображения CIFAR-10

Загрузите набор данных CIFAR-10 [3]. Этот набор данных содержит 50 000 учебных изображений, которые будут использоваться, чтобы обучить CNN.

Загрузите данные CIFAR-10 на временную директорию

cifar10Data = tempdir;

url = 'https://www.cs.toronto.edu/~kriz/cifar-10-matlab.tar.gz';

helperCIFAR10Data.download(url,cifar10Data);

Загрузите обучение CIFAR-10 и тестовые данные.

[trainingImages,trainingLabels,testImages,testLabels] = helperCIFAR10Data.load(cifar10Data);

Каждое изображение 32x32 изображение RGB и существует 50 000 обучающих выборок.

size(trainingImages)
ans = 1×4

          32          32           3       50000

CIFAR-10 имеет 10 категорий изображений. Перечислите категории изображений:

numImageCategories = 10;
categories(trainingLabels)
ans = 10×1 cell
    {'airplane'  }
    {'automobile'}
    {'bird'      }
    {'cat'       }
    {'deer'      }
    {'dog'       }
    {'frog'      }
    {'horse'     }
    {'ship'      }
    {'truck'     }

Можно отобразить несколько учебных изображений с помощью следующего кода.

figure
thumbnails = trainingImages(:,:,:,1:100);
montage(thumbnails)

Создайте сверточную нейронную сеть (CNN)

CNN состоит из серии слоев, где каждый слой задает определенный расчет. Deep Learning Toolbox™ обеспечивает функциональность, чтобы легко спроектировать слой слоем CNN. В этом примере следующие слои используются, чтобы создать CNN:

Сеть, заданная здесь, похожа на ту, описанную в [4], и запускается с imageInputLayer. Входной слой задает тип и размер данных, которые может обработать CNN. В этом примере CNN используется к процессу изображения CIFAR-10, которые являются 32x32 изображения RGB:

% Create the image input layer for 32x32x3 CIFAR-10 images.
[height,width,numChannels, ~] = size(trainingImages);

imageSize = [height width numChannels];
inputLayer = imageInputLayer(imageSize)
inputLayer = 
  ImageInputLayer with properties:

                      Name: ''
                 InputSize: [32 32 3]
   Hyperparameters
          DataAugmentation: 'none'
             Normalization: 'zerocenter'
    NormalizationDimension: 'auto'
                      Mean: []

Затем задайте средние слои сети. Средние слои составлены из повторных блоков сверточных, ReLU (исправил линейные модули), и слои объединения. Эти 3 слоя формируют базовые базовые блоки сверточных нейронных сетей. Сверточные слои задают наборы весов фильтра, которые обновляются во время сетевого обучения. Слой ReLU добавляет нелинейность в сеть, которые позволяют сети аппроксимировать нелинейные функции, которые сопоставляют пиксели изображения с семантическим содержимым изображения. Слои объединения прореживают данные, когда они текут через сеть. В сети с большим количеством слоев, объединяя слои должен использоваться экономно, чтобы не прореживать данные слишком рано в сети.

% Convolutional layer parameters
filterSize = [5 5];
numFilters = 32;

middleLayers = [
    
% The first convolutional layer has a bank of 32 5x5x3 filters. A
% symmetric padding of 2 pixels is added to ensure that image borders
% are included in the processing. This is important to avoid
% information at the borders being washed away too early in the
% network.
convolution2dLayer(filterSize,numFilters,'Padding',2)

% Note that the third dimension of the filter can be omitted because it
% is automatically deduced based on the connectivity of the network. In
% this case because this layer follows the image layer, the third
% dimension must be 3 to match the number of channels in the input
% image.

% Next add the ReLU layer:
reluLayer()

% Follow it with a max pooling layer that has a 3x3 spatial pooling area
% and a stride of 2 pixels. This down-samples the data dimensions from
% 32x32 to 15x15.
maxPooling2dLayer(3,'Stride',2)

% Repeat the 3 core layers to complete the middle of the network.
convolution2dLayer(filterSize,numFilters,'Padding',2)
reluLayer()
maxPooling2dLayer(3, 'Stride',2)

convolution2dLayer(filterSize,2 * numFilters,'Padding',2)
reluLayer()
maxPooling2dLayer(3,'Stride',2)

]
middleLayers = 
  9x1 Layer array with layers:

     1   ''   Convolution   32 5x5 convolutions with stride [1  1] and padding [2  2  2  2]
     2   ''   ReLU          ReLU
     3   ''   Max Pooling   3x3 max pooling with stride [2  2] and padding [0  0  0  0]
     4   ''   Convolution   32 5x5 convolutions with stride [1  1] and padding [2  2  2  2]
     5   ''   ReLU          ReLU
     6   ''   Max Pooling   3x3 max pooling with stride [2  2] and padding [0  0  0  0]
     7   ''   Convolution   64 5x5 convolutions with stride [1  1] and padding [2  2  2  2]
     8   ''   ReLU          ReLU
     9   ''   Max Pooling   3x3 max pooling with stride [2  2] and padding [0  0  0  0]

Более глубокая сеть может быть создана путем повторения этих 3 основных слоев. Однако количество объединения слоев должно быть сокращено, чтобы не прореживать данные преждевременно. Субдискретизация рано в сети отбрасывает данные изображения, которые полезны для изучения.

Последние слои CNN обычно состоят из полносвязных слоев и softmax слоя потерь.

finalLayers = [
    
% Add a fully connected layer with 64 output neurons. The output size of
% this layer will be an array with a length of 64.
fullyConnectedLayer(64)

% Add an ReLU non-linearity.
reluLayer

% Add the last fully connected layer. At this point, the network must
% produce 10 signals that can be used to measure whether the input image
% belongs to one category or another. This measurement is made using the
% subsequent loss layers.
fullyConnectedLayer(numImageCategories)

% Add the softmax loss layer and classification layer. The final layers use
% the output of the fully connected layer to compute the categorical
% probability distribution over the image classes. During the training
% process, all the network weights are tuned to minimize the loss over this
% categorical distribution.
softmaxLayer
classificationLayer
]
finalLayers = 
  5x1 Layer array with layers:

     1   ''   Fully Connected         64 fully connected layer
     2   ''   ReLU                    ReLU
     3   ''   Fully Connected         10 fully connected layer
     4   ''   Softmax                 softmax
     5   ''   Classification Output   crossentropyex

Объедините вход, середина и последние слои.

layers = [
    inputLayer
    middleLayers
    finalLayers
    ]
layers = 
  15x1 Layer array with layers:

     1   ''   Image Input             32x32x3 images with 'zerocenter' normalization
     2   ''   Convolution             32 5x5 convolutions with stride [1  1] and padding [2  2  2  2]
     3   ''   ReLU                    ReLU
     4   ''   Max Pooling             3x3 max pooling with stride [2  2] and padding [0  0  0  0]
     5   ''   Convolution             32 5x5 convolutions with stride [1  1] and padding [2  2  2  2]
     6   ''   ReLU                    ReLU
     7   ''   Max Pooling             3x3 max pooling with stride [2  2] and padding [0  0  0  0]
     8   ''   Convolution             64 5x5 convolutions with stride [1  1] and padding [2  2  2  2]
     9   ''   ReLU                    ReLU
    10   ''   Max Pooling             3x3 max pooling with stride [2  2] and padding [0  0  0  0]
    11   ''   Fully Connected         64 fully connected layer
    12   ''   ReLU                    ReLU
    13   ''   Fully Connected         10 fully connected layer
    14   ''   Softmax                 softmax
    15   ''   Classification Output   crossentropyex

Инициализируйте первые сверточные веса слоя с помощью нормально распределенных случайных чисел со стандартным отклонением 0,0001. Это помогает улучшить сходимость обучения.

layers(2).Weights = 0.0001 * randn([filterSize numChannels numFilters]);

Обучите CNN Используя данные CIFAR-10

Теперь, когда сетевая архитектура задана, она может быть обучена с помощью обучающих данных CIFAR-10. Во-первых, настройте сетевой алгоритм настройки с помощью trainingOptions функция. Сетевой алгоритм настройки использует Стохастический Градиентный спуск с Импульсом (SGDM) с начальной скоростью обучения 0,001. Во время обучения начальная скорость обучения уменьшается каждые 8 эпох (1 эпоха задана, когда одно полное проходит через целый обучающий набор данных). Алгоритм настройки запущен в течение 40 эпох.

Обратите внимание на то, что алгоритм настройки использует мини-пакетный размер 128 изображений. При использовании графического процессора для обучения этот размер, возможно, должен быть понижен из-за ограничений памяти на графический процессор.

% Set the network training options
opts = trainingOptions('sgdm', ...
    'Momentum', 0.9, ...
    'InitialLearnRate', 0.001, ...
    'LearnRateSchedule', 'piecewise', ...
    'LearnRateDropFactor', 0.1, ...
    'LearnRateDropPeriod', 8, ...
    'L2Regularization', 0.004, ...
    'MaxEpochs', 40, ...
    'MiniBatchSize', 128, ...
    'Verbose', true);

Обучите сеть с помощью trainNetwork функция. Это - в вычислительном отношении интенсивный процесс, который занимает 20-30 минут, чтобы завершиться. Чтобы сэкономить время при выполнении этого примера, предварительно обученная сеть загружается от диска. Если вы хотите обучить сеть сами, установите doTraining переменная, показанная ниже истине.

Обратите внимание на то, что CUDA-способный графический процессор NVIDIA™ настоятельно рекомендован для обучения.

% A trained network is loaded from disk to save time when running the
% example. Set this flag to true to train the network.
doTraining = false;

if doTraining    
    % Train a network.
    cifar10Net = trainNetwork(trainingImages, trainingLabels, layers, opts);
else
    % Load pre-trained detector for the example.
    load('rcnnStopSigns.mat','cifar10Net')       
end

Подтвердите сетевое обучение CIFAR-10

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

% Extract the first convolutional layer weights
w = cifar10Net.Layers(2).Weights;

% rescale the weights to the range [0, 1] for better visualization
w = rescale(w);

figure
montage(w)

Первые веса слоя должны иметь некоторую четко определенную структуру. Если веса все еще выглядят случайными, то это - индикация, что сеть может потребовать дополнительного обучения. В этом случае, как показано выше, первые фильтры слоя узнали о подобных ребру функциях из обучающих данных CIFAR-10.

Чтобы полностью подтвердить учебные результаты, используйте тестовые данные CIFAR-10, чтобы измерить точность классификации сети. Низкий счет точности указывает, что дополнительные учебные или дополнительные обучающие данные требуются. Цель этого примера не состоит в том, чтобы обязательно достигнуть 100%-й точности на наборе тестов, но достаточно обучать сеть для использования в обучении детектор объектов.

% Run the network on the test set.
YTest = classify(cifar10Net, testImages);

% Calculate the accuracy.
accuracy = sum(YTest == testLabels)/numel(testLabels)
accuracy = 0.7456

Дальнейшее обучение улучшит точность, но это не необходимо в целях обучения детектор объектов R-CNN.

Загрузите обучающие данные

Теперь, когда сеть работает хорошо на задачу классификации CIFAR-10, подход передачи обучения может использоваться, чтобы подстроить сеть для обнаружения знака Стоп.

Запустите путем загрузки достоверных данных для знаков Стоп.

% Load the ground truth data
data = load('stopSignsAndCars.mat', 'stopSignsAndCars');
stopSignsAndCars = data.stopSignsAndCars;

% Update the path to the image files to match the local file system
visiondata = fullfile(toolboxdir('vision'),'visiondata');
stopSignsAndCars.imageFilename = fullfile(visiondata, stopSignsAndCars.imageFilename);

% Display a summary of the ground truth data
summary(stopSignsAndCars)
Variables:
    imageFilename: 41×1 cell array of character vectors
    stopSign: 41×1 cell
    carRear: 41×1 cell
    carFront: 41×1 cell

Обучающие данные содержатся в рамках таблицы, которая содержит имя файла образа и метки ROI для знаков Стоп, автомобильных передних сторон и задних частей. Каждая метка ROI является ограничительной рамкой вокруг предметов интереса в изображении. Для обучения детектор знака Стоп только необходимы метки ROI знака Стоп. Метки ROI для автомобильной передней стороны и задней части должны быть удалены:

% Only keep the image file names and the stop sign ROI labels
stopSigns = stopSignsAndCars(:, {'imageFilename','stopSign'});

% Display one training image and the ground truth bounding boxes
I = imread(stopSigns.imageFilename{1});
I = insertObjectAnnotation(I,'Rectangle',stopSigns.stopSign{1},'stop sign','LineWidth',8);

figure
imshow(I)

Обратите внимание на то, что в этом наборе данных существует только 41 учебное изображение. Обучение детектор объектов R-CNN с нуля с помощью только 41 изображения не практичен и не произвел бы надежный детектор знака Стоп. Поскольку детектор знака Стоп обучен путем подстройки сети, которая была предварительно обучена на большем наборе данных (CIFAR-10 имеет 50 000 учебных изображений), использование намного меньшего набора данных выполнимо.

Обучите детектор знака Стоп R-CNN

Наконец, обучите детектор объектов R-CNN с помощью trainRCNNObjectDetector (Computer Vision Toolbox). Вход к этой функции является таблицей основной истины, которая содержит помеченные изображения знака Стоп, предварительно обученную сеть CIFAR-10 и опции обучения. Учебная функция автоматически изменяет исходную сеть CIFAR-10, которая классифицировала изображения в 10 категорий в сеть, которая может классифицировать изображения в 2 класса: знаки Стоп и типовой фоновый класс.

Во время обучения входные веса сети подстраиваются с помощью закрашенных фигур изображений, извлеченных из достоверных данных. Управление параметрами 'PositiveOverlapRange' и 'NegativeOverlapRange', которые отображают закрашенные фигуры, используется для обучения. Положительные обучающие выборки - те, которые перекрываются с основными блоками истинности 0,5 к 1,0, как измерено пересечением ограничительной рамки по метрике объединения. Отрицательные обучающие выборки - те, которые перекрываются 0 к 0,3. Оптимальные значения для этих параметров должны быть выбраны путем тестирования обученного детектора на наборе валидации.

Для обучения R-CNN использование параллельного пула работников MATLAB настоятельно рекомендовано, чтобы уменьшать учебное время. trainRCNNObjectDetector автоматически создает и использует параллельный пул на основе ваших параметров параллельных предпочтений. Убедитесь, что использование параллельного пула включено до обучения.

Чтобы сэкономить время при выполнении этого примера, предварительно обученная сеть загружается от диска. Если вы хотите обучить сеть сами, установите doTraining переменная, показанная ниже истине.

Обратите внимание на то, что CUDA-способный графический процессор NVIDIA™ настоятельно рекомендован для обучения.

% A trained detector is loaded from disk to save time when running the
% example. Set this flag to true to train the detector.
doTraining = false;

if doTraining
    
    % Set training options
    options = trainingOptions('sgdm', ...
        'MiniBatchSize', 128, ...
        'InitialLearnRate', 1e-3, ...
        'LearnRateSchedule', 'piecewise', ...
        'LearnRateDropFactor', 0.1, ...
        'LearnRateDropPeriod', 100, ...
        'MaxEpochs', 100, ...
        'Verbose', true);
    
    % Train an R-CNN object detector. This will take several minutes.    
    rcnn = trainRCNNObjectDetector(stopSigns, cifar10Net, options, ...
    'NegativeOverlapRange', [0 0.3], 'PositiveOverlapRange',[0.5 1])
else
    % Load pre-trained network for the example.
    load('rcnnStopSigns.mat','rcnn')       
end

Протестируйте детектор знака Стоп R-CNN

Детектор объектов R-CNN может теперь использоваться, чтобы обнаружить знаки Стоп в изображениях. Испытайте его на тестовом изображении:

% Read test image
testImage = imread('stopSignTest.jpg');

% Detect stop signs
[bboxes,score,label] = detect(rcnn,testImage,'MiniBatchSize',128)
bboxes = 1×4

   419   147    31    20

score = single
    0.9955
label = categorical categorical
     stopSign 

Объект R-CNN detect (Computer Vision Toolbox) метод возвращает объектные ограничительные рамки, счет обнаружения и метку класса для каждого обнаружения. Метки полезны при обнаружении нескольких объектов, e.g. остановитесь, уступите, или знаки ограничения скорости. Баллы, которые располагаются между 0 и 1, указывают на доверие к обнаружению и могут использоваться, чтобы проигнорировать низко обнаружения выигрыша.

% Display the detection results
[score, idx] = max(score);

bbox = bboxes(idx, :);
annotation = sprintf('%s: (Confidence = %f)', label(idx), score);

outputImage = insertObjectAnnotation(testImage, 'rectangle', bbox, annotation);

figure
imshow(outputImage)

Отладка советов

Сеть, используемая в детекторе R-CNN, может также использоваться, чтобы обработать целое тестовое изображение. Путем прямой обработки целого изображения, которое больше, чем входной размер сети, может быть сгенерирована 2D тепловая карта классификационных оценок. Это - полезное средство отладки, потому что оно помогает идентифицировать элементы в изображении, которые сбивают с толку сеть и могут помочь обеспечить понимание улучшения обучения.

% The trained network is stored within the R-CNN detector
rcnn.Network
ans = 
  SeriesNetwork with properties:

    Layers: [15×1 nnet.cnn.layer.Layer]

Извлеките activations от softmax слоя, который является 14-м слоем в сети. Это классификационные оценки, произведенные сетью, когда она сканирует изображение.

featureMap = activations(rcnn.Network, testImage, 14);

% The softmax activations are stored in a 3-D array.
size(featureMap)
ans = 1×3

    43    78     2

3-я размерность в featureMap соответствует классам объектов.

rcnn.ClassNames
ans = 2×1 cell
    {'stopSign'  }
    {'Background'}

Карта функции знака Стоп хранится в первом канале.

stopSignMap = featureMap(:, :, 1);

Размер активаций, выход меньше, чем вход, отображает из-за операций субдискретизации в сети. Чтобы сгенерировать более хорошую визуализацию, измените размер stopSignMap к размеру входного изображения. Это - очень грубое приближение, которое сопоставляет активации с пикселями изображения и должно только использоваться для иллюстративных целей.

% Resize stopSignMap for visualization
[height, width, ~] = size(testImage);
stopSignMap = imresize(stopSignMap, [height, width]);

% Visualize the feature map superimposed on the test image. 
featureMapOnImage = imfuse(testImage, stopSignMap); 

figure
imshow(featureMapOnImage)

Знак Стоп в тестовом изображении соответствует приятно самому большому пику в сетевых активациях. Это помогает проверить, что CNN, используемый в детекторе R-CNN, эффективно учился идентифицировать знаки Стоп. Был другой peaks, это может указать, что обучение требует, чтобы дополнительные отрицательные данные помогли предотвратить ложные положительные стороны. Если это так, затем можно увеличить 'MaxEpochs' в trainingOptions и переобучиться.

Сводные данные

Этот пример показал, как обучить детектор объектов знака Стоп R-CNN с помощью сети, обученной с данными CIFAR-10. Подобные шаги могут быть выполнены, чтобы обучить другие детекторы объектов с помощью глубокого обучения.

Ссылки

[1] Girshick, R., Дж. Донахью, Т. Даррелл и Дж. Малик. "Богатые Иерархии Функции для Точного Обнаружения объектов и Семантической Сегментации". Продолжения 2 014 Конференций по IEEE по Компьютерному зрению и Распознаванию образов. Колумбус, OH, июнь 2014, стр 580-587.

[2] Дэн, J., В. Дун, Р. Сокэр, L.-J. Ли, К. Ли и Л. Фэй-Фэй. "ImageNet: Крупномасштабная Иерархическая База данных Изображений". Продолжения 2 009 Конференций по IEEE по Компьютерному зрению и Распознаванию образов. Майами, FL, июнь 2009, стр 248-255.

[3] Krizhevsky, A. и Г. Хинтон. "Изучая несколько слоев функций от крошечных изображений". Магистерская диссертация. Университет Торонто, Торонто, Канада, 2009.

[4] https://code.google.com/p/cuda-convnet/

Смотрите также

(Computer Vision Toolbox) | | | (Computer Vision Toolbox) | (Computer Vision Toolbox) | (Computer Vision Toolbox) | (Computer Vision Toolbox) | (Computer Vision Toolbox) | | (Computer Vision Toolbox) |

Похожие темы