Этот пример показывает, как обучить объектный детектор с помощью глубокого обучения и 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™ с вычисляют возможность 3.0, или выше настоятельно рекомендован для выполнения этого примера. Использование графического процессора требует Parallel Computing Toolbox™.
Загрузите набор данных 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 array
{'airplane' }
{'automobile'}
{'bird' }
{'cat' }
{'deer' }
{'dog' }
{'frog' }
{'horse' }
{'ship' }
{'truck' }
Отобразите несколько учебных изображений.
figure thumbnails = trainingImages(:,:,:,1:100); montage(thumbnails)
CNN состоит из серии слоев, где каждый слой задает определенное вычисление. Deep Learning Toolbox™ обеспечивает функциональность, чтобы легко разработать слой слоем CNN. В этом примере следующие слои используются, чтобы создать CNN:
Слой входа imageInputLayer
- Image
convolution2dLayer
- 2D слой свертки для Сверточных Нейронных сетей
reluLayer
- Исправленный линейный модульный слой (ReLU)
maxPooling2dLayer
- Слой объединения Max
fullyConnectedLayer
- Полносвязный слой
Слой softmaxLayer
- Softmax
classificationLayer
- Classification слой вывода для нейронной сети
Сеть, заданная здесь, подобна той, описанной в [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' AverageImage: []
Затем, задайте средние слои сети. Средние слои составлены из повторных блоков сверточных, 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]);
Теперь, когда сетевая архитектура задана, она может быть обучена с помощью данных тренировки 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™ с вычисляет возможность 3.0, или выше настоятельно рекомендован для обучения.
% 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
После того, как сеть обучена, она должна быть подтверждена, чтобы гарантировать, что обучение было успешно. Во-первых, быстрая визуализация весов фильтра первого сверточного слоя может помочь идентифицировать любые мгновенные проблемы с обучением.
% 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 с помощью trainRCNNObjectDetector
. Вход к этой функции является наземной таблицей истинности, которая содержит маркированные изображения знака Стоп, предварительно обученную сеть CIFAR-10 и опции обучения. Учебная функция автоматически изменяет исходную сеть CIFAR-10, которая классифицировала изображения в 10 категорий в сеть, которая может классифицировать изображения в 2 класса: знаки Стоп и типичный фоновый класс.
Во время обучения входные веса сети подстраиваются с помощью закрашенных фигур изображений, извлеченных от наземных данных об истине. Управление параметрами 'PositiveOverlapRange' и 'NegativeOverlapRange', которые отображают закрашенные фигуры, используется для обучения. Положительные учебные выборки - те, которые накладываются с наземными полями истины 0,5 к 1,0, как измерено пересечением ограничительной рамки по метрике объединения. Отрицательные учебные выборки - те, которые накладываются 0 к 0,3. Оптимальные значения для этих параметров должны быть выбраны путем тестирования обученного детектора на наборе валидации.
Для обучения R-CNN использование параллельного пула работников MATLAB настоятельно рекомендовано, чтобы уменьшать учебное время. trainRCNNObjectDetector
автоматически создает и использует параллельный пул на основе ваших параллельных настроек настройки. Гарантируйте, что использование параллельного пула включено до обучения.
Чтобы сэкономить время при выполнении этого примера, предварительно обученная сеть загружается от диска. Если вы хотите обучить сеть сами, установите переменную doTraining
, показанную ниже истине.
Обратите внимание на то, что CUDA-способный графический процессор NVIDIA™ с вычисляет возможность 3.0, или выше настоятельно рекомендован для обучения.
% 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 может теперь использоваться, чтобы обнаружить знаки Стоп в изображениях. Испытайте его на тестовом изображении:
% 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
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, может также использоваться, чтобы обработать целое тестовое изображение. Путем прямой обработки целого изображения, которое больше, чем входной размер сети, может быть сгенерирована 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 array
{'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/
activations
| classify
| detect
| fastRCNNObjectDetector
| fasterRCNNObjectDetector
| rcnnObjectDetector
| trainFastRCNNObjectDetector
| trainFasterRCNNObjectDetector
| trainNetwork
| trainRCNNObjectDetector
| trainingOptions