Обучите детектор объектов с помощью глубокого обучения 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™.

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

Загрузка CIFAR-10 Image Данных

Загрузите 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);

Каждое изображение представляет собой изображение RGB размером 32x32, и существуют 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 используются следующие слои:

  • imageInputLayer (Deep Learning Toolbox) - Входной слой изображения

  • convolution2dLayer (Deep Learning Toolbox) - 2D слой свертки для сверточных нейронных сетей

  • reluLayer (Deep Learning Toolbox) - слой с исправленным линейным модулем измерения (ReLU)

  • maxPooling2dLayer (Deep Learning Toolbox) - Максимальный слой объединения

  • fullyConnectedLayer (Deep Learning Toolbox) - Полносвязный слой

  • softmaxLayer (Deep Learning Toolbox) - слой Softmax

  • classificationLayer (Deep Learning Toolbox) - Классификационный выходной слой для нейронной сети

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

% 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 (Deep Learning Toolbox) функция. Алгоритм настройки использует Стохастический Градиентный Спуск с Импульсом (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 (Deep Learning Toolbox) функция. Это вычислительно интенсивный процесс, который занимает 20-30 минут. Чтобы сэкономить время при запуске этого примера, предварительно обученная сеть загружается с диска. Если вы хотите обучить сеть самостоятельно, установите doTraining переменная, показанная ниже, в значение true.

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

% 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)

Веса первого слоя должны иметь определенную структуру. Если веса все еще выглядят случайными, это указывает на то, что сеть может потребовать дополнительного обучения. В этом случае, как показано выше, фильтры первого слоя получают edge-like функций из 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

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

% 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. Вход этой функции является таблица основной истины, которая содержит маркированные изображения знака остановки, предварительно обученную сеть CIFAR-10 и параметры обучения. Функция обучения автоматически изменяет исходную CIFAR-10 сеть, которая классифицировала изображения по 10 категориям, в сеть, которая может классифицировать изображения по 2 классам: знакам стопа и типовому фоновому классу.

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

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

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

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

% 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 Stop Sign Detector

Теперь детектор объектов 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 метод возвращает ограничивающие объекты рамки, счет обнаружения и метку класса для каждого обнаружения. Метки применяются при обнаружении нескольких объектов, например, знаков остановки, выражения или предела скорости. Счета, которые варьируются от 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, также может использоваться для обработки всего тестового изображения. Путем непосредственной обработки всего изображения, которое больше, чем размер входа сети, может быть сгенерирована 2-D тепловая карта классификационных оценок. Это полезный инструмент отладки, поскольку он помогает идентифицировать элементы изображения, которые путают сеть, и может помочь получить представление об улучшении обучения.

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

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

Извлечение activations (Deep Learning Toolbox) из слоя 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] Гиршик, Р., Дж. Донахью, Т. Даррелл и Дж. Малик. «Богатые иерархии функций для точного обнаружения объектов и семантической сегментации». Материалы Конференции IEEE по компьютерному зрению и распознаванию шаблонов 2014 года. Columbus, OH, июнь 2014, стр. 580-587.

[2] Deng, J., W. Dong, R. Socher, L.-J. Ли, К. Ли и Л. Фэй-Фэй. ImageNet: крупномасштабная иерархическая база данных изображений. Материалы Конференции IEEE по компьютерному зрению и распознаванию шаблонов 2009 года. Майами, ФЛ, июнь 2009, стр. 248-255.

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

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

См. также

| | | | | | | (Deep Learning Toolbox) | (Deep Learning Toolbox) | (Deep Learning Toolbox) | (Deep Learning Toolbox)

Похожие темы