exponenta event banner

Обнаружение объектов с помощью глубокого обучения YOLO v2

В этом примере показано, как обучить детектор объектов только один раз (YOLO) версии 2.

Глубокое обучение - это мощный метод машинного обучения, который можно использовать для обучения надежных детекторов объектов. Существует несколько методов обнаружения объектов, включая более быстрый R-CNN, и вы смотрите только один раз (YOLO) v2. В этом примере выполняется подготовка детектора транспортного средства YOLO v2 с использованием trainYOLOv2ObjectDetector функция. Дополнительные сведения см. в разделе Начало работы с YOLO v2 (Панель инструментов компьютерного зрения).

Загрузить предварительно обученный детектор

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

doTraining = false;
if ~doTraining && ~exist('yolov2ResNet50VehicleExample_19b.mat','file')    
    disp('Downloading pretrained detector (98 MB)...');
    pretrainedURL = 'https://www.mathworks.com/supportfiles/vision/data/yolov2ResNet50VehicleExample_19b.mat';
    websave('yolov2ResNet50VehicleExample_19b.mat',pretrainedURL);
end

Загрузить набор данных

В этом примере используется небольшой набор данных транспортного средства, содержащий 295 изображений. Многие из этих изображений получены из наборов данных Caltech Cars 1999 и 2001, доступных на веб-сайте Caltech Computational Vision, созданном Пьетро Пероной и используемом с разрешения. Каждое изображение содержит один или два помеченных экземпляра транспортного средства. Небольшой набор данных полезен для изучения процедуры обучения YOLO v2, но на практике для обучения надежного детектора требуется больше маркированных изображений. Распакуйте изображения транспортного средства и загрузите данные об истинности грунта транспортного средства.

unzip vehicleDatasetImages.zip
data = load('vehicleDatasetGroundTruth.mat');
vehicleDataset = data.vehicleDataset;

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

% Display first few rows of the data set.
vehicleDataset(1:4,:)
ans=4×2 table
              imageFilename                vehicle   
    _________________________________    ____________

    {'vehicleImages/image_00001.jpg'}    {1×4 double}
    {'vehicleImages/image_00002.jpg'}    {1×4 double}
    {'vehicleImages/image_00003.jpg'}    {1×4 double}
    {'vehicleImages/image_00004.jpg'}    {1×4 double}

% Add the fullpath to the local vehicle data folder.
vehicleDataset.imageFilename = fullfile(pwd,vehicleDataset.imageFilename);

Разбейте набор данных на обучающие, проверочные и тестовые наборы. Выберите 60% данных для обучения, 10% для проверки и остальные для тестирования обученного детектора.

rng(0);
shuffledIndices = randperm(height(vehicleDataset));
idx = floor(0.6 * length(shuffledIndices) );

trainingIdx = 1:idx;
trainingDataTbl = vehicleDataset(shuffledIndices(trainingIdx),:);

validationIdx = idx+1 : idx + 1 + floor(0.1 * length(shuffledIndices) );
validationDataTbl = vehicleDataset(shuffledIndices(validationIdx),:);

testIdx = validationIdx(end)+1 : length(shuffledIndices);
testDataTbl = vehicleDataset(shuffledIndices(testIdx),:);

Использовать imageDatastore и boxLabelDatastore создание хранилищ данных для загрузки данных изображения и метки во время обучения и оценки.

imdsTrain = imageDatastore(trainingDataTbl{:,'imageFilename'});
bldsTrain = boxLabelDatastore(trainingDataTbl(:,'vehicle'));

imdsValidation = imageDatastore(validationDataTbl{:,'imageFilename'});
bldsValidation = boxLabelDatastore(validationDataTbl(:,'vehicle'));

imdsTest = imageDatastore(testDataTbl{:,'imageFilename'});
bldsTest = boxLabelDatastore(testDataTbl(:,'vehicle'));

Объединение хранилищ данных меток изображений и полей.

trainingData = combine(imdsTrain,bldsTrain);
validationData = combine(imdsValidation,bldsValidation);
testData = combine(imdsTest,bldsTest);

Отображение одного из обучающих изображений и наклеек.

data = read(trainingData);
I = data{1};
bbox = data{2};
annotatedImage = insertShape(I,'Rectangle',bbox);
annotatedImage = imresize(annotatedImage,2);
figure
imshow(annotatedImage)

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

Сеть обнаружения объектов YOLO v2 состоит из двух подсетей. Сеть извлечения элементов, за которой следует сеть обнаружения. Сеть извлечения функций обычно представляет собой предварительно обученный CNN (для получения более подробной информации см. Предварительно обученные глубокие нейронные сети). В этом примере для извлечения элементов используются ResNet-50. Вы также можете использовать другие предварительно обученные сети, такие как StartNet v2 или ResNet-18 также могут использоваться в зависимости от требований приложений. Подсеть обнаружения является небольшим CNN по сравнению с сетью извлечения признаков и состоит из нескольких сверточных слоев и слоев, специфичных для YOLO v2.

Используйте yolov2Layers Функция (Computer Vision Toolbox) позволяет автоматически создавать сеть обнаружения объектов YOLO v2 с предварительно подготовленной сетью извлечения элементов ResNet-50. yolov2Layers требуется указать несколько входов для параметризации сети YOLO v2:

  • Размер сетевого входа

  • Якорные ящики

  • Сеть извлечения элементов

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

inputSize = [224 224 3];

Определите количество обнаруживаемых классов объектов.

numClasses = width(vehicleDataset)-1;

Обратите внимание, что учебные изображения, используемые в этом примере, больше 224 на 224 и различаются по размеру, поэтому перед началом обучения необходимо изменить размер изображений на этапе предварительной обработки.

Далее используйте estimateAnchorBoxes (Computer Vision Toolbox) для оценки полей привязки на основе размера объектов в данных обучения. Чтобы учесть изменение размеров изображений перед обучением, измените размер обучающих данных для оценки полей привязки. Использовать transform для предварительной обработки данных обучения, затем определите количество анкерных ящиков и оцените их. Изменение размера обучающих данных в соответствии с размером входного изображения сети с помощью функции поддержки preprocessData.

trainingDataForEstimation = transform(trainingData,@(data)preprocessData(data,inputSize));
numAnchors = 7;
[anchorBoxes, meanIoU] = estimateAnchorBoxes(trainingDataForEstimation, numAnchors)
anchorBoxes = 7×2

   162   136
    85    80
   149   123
    43    32
    65    63
   117   105
    33    27

meanIoU = 0.8472

Дополнительные сведения о выборе анкерных ящиков см. в разделах Оценка анкерных ящиков по учебным данным (панель инструментов компьютерного зрения) (Toolbox™ компьютерного зрения) и Анкерные ящики для обнаружения объектов (панель инструментов компьютерного зрения).

Теперь используйте resnet50 для загрузки предварительно подготовленной модели ResNet-50.

featureExtractionNetwork = resnet50;

Выбрать 'activation_40_relu' в качестве слоя извлечения элементов для замены слоев после 'activation_40_relu' с подсетью обнаружения. Этот слой извлечения элементов выводит карты элементов, которые понижаются в 16 раз. Эта величина понижающей дискретизации является хорошим компромиссом между пространственным разрешением и прочностью выделенных признаков, поскольку признаки, извлеченные далее вниз по сети, кодируют более сильные признаки изображения за счет пространственного разрешения. Выбор оптимального слоя извлечения элементов требует эмпирического анализа.

featureLayer = 'activation_40_relu';

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

lgraph = yolov2Layers(inputSize,numClasses,anchorBoxes,featureExtractionNetwork,featureLayer);

Можно визуализировать сеть с помощью analyzeNetwork или Deep Network Designer из Deep Learning Toolbox™.

Если требуется дополнительный контроль над сетевой архитектурой YOLO v2, используйте Deep Network Designer для разработки сети обнаружения YOLO v2 вручную. Дополнительные сведения см. в разделе Проектирование сети обнаружения YOLO v2 (панель инструментов компьютерного зрения).

Увеличение объема данных

Увеличение данных используется для повышения точности сети путем случайного преобразования исходных данных во время обучения. С помощью увеличения данных можно добавить большее разнообразие к обучающим данным без фактического увеличения количества маркированных обучающих образцов.

Использовать transform для увеличения обучающих данных путем случайного разворота изображения и связанных меток полей по горизонтали. Обратите внимание, что увеличение данных не применяется к данным тестирования и проверки. В идеале, данные тестирования и проверки должны быть репрезентативными для исходных данных и оставлены неизмененными для объективной оценки.

augmentedTrainingData = transform(trainingData,@augmentData);

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

% Visualize the augmented images.
augmentedData = cell(4,1);
for k = 1:4
    data = read(augmentedTrainingData);
    augmentedData{k} = insertShape(data{1},'Rectangle',data{2});
    reset(augmentedTrainingData);
end
figure
montage(augmentedData,'BorderSize',10)

Предварительные данные обучения

Предварительная обработка дополненных данных обучения и данных проверки для подготовки к обучению.

preprocessedTrainingData = transform(augmentedTrainingData,@(data)preprocessData(data,inputSize));
preprocessedValidationData = transform(validationData,@(data)preprocessData(data,inputSize));

Прочитайте предварительно обработанные данные обучения.

data = read(preprocessedTrainingData);

Отображение изображения и ограничивающих рамок.

I = data{1};
bbox = data{2};
annotatedImage = insertShape(I,'Rectangle',bbox);
annotatedImage = imresize(annotatedImage,2);
figure
imshow(annotatedImage)

Детектор объектов канала YOLO v2

Использовать trainingOptions для указания параметров сетевого обучения. Набор 'ValidationData' к предварительно обработанным данным проверки. Набор 'CheckpointPath' во временное место. Это позволяет экономить частично обученные детекторы в процессе обучения. Если обучение прервано, например, из-за отключения питания или сбоя системы, вы можете возобновить обучение с сохраненной контрольной точки.

options = trainingOptions('sgdm', ...
        'MiniBatchSize',16, ....
        'InitialLearnRate',1e-3, ...
        'MaxEpochs',20, ... 
        'CheckpointPath',tempdir, ...
        'ValidationData',preprocessedValidationData);

Использовать trainYOLOv2ObjectDetector Функция (Computer Vision Toolbox) для обучения детектора объектов YOLO v2, если doTraining является правдой. В противном случае загрузите предварительно подготовленную сеть.

if doTraining       
    % Train the YOLO v2 detector.
    [detector,info] = trainYOLOv2ObjectDetector(preprocessedTrainingData,lgraph,options);
else
    % Load pretrained detector for the example.
    pretrained = load('yolov2ResNet50VehicleExample_19b.mat');
    detector = pretrained.detector;
end

Этот пример был подтвержден графическим процессором NVIDIA™ Titan X с 12 ГБ памяти. Если на графическом процессоре меньше памяти, может не хватить памяти. Если это произойдет, опустите 'MiniBatchSize' с использованием trainingOptions функция. Обучение этой сети заняло около 7 минут. Время обучения зависит от используемого оборудования.

В качестве быстрого теста запустите детектор на тестовом изображении. Убедитесь, что размер изображения совпадает с размером учебных изображений.

I = imread('highway.png');
I = imresize(I,inputSize(1:2));
[bboxes,scores] = detect(detector,I);

Просмотрите результаты.

I = insertObjectAnnotation(I,'rectangle',bboxes,scores);
figure
imshow(I)

Оценка детектора с помощью тестового набора

Оцените обученный детектор объектов на большом наборе изображений для измерения производительности. Computer Vision Toolbox™ предоставляет функции оценки детекторов объектов для измерения общих метрик, таких как средняя точность (evaluateDetectionPrecision) и средние по журналу показатели промахов (evaluateDetectionMissRate). Для этого примера используйте метрику средней точности для оценки производительности. Средняя точность обеспечивает одно число, которое включает в себя способность детектора делать правильные классификации (точность) и способность детектора находить все соответствующие объекты (вспомним).

Примените к тестовым данным то же преобразование предварительной обработки, что и к учебным данным. Обратите внимание, что увеличение данных не применяется к данным теста. Тестовые данные должны быть репрезентативными для исходных данных и оставляться неизмененными для объективной оценки.

preprocessedTestData = transform(testData,@(data)preprocessData(data,inputSize));

Запустите детектор на всех тестовых изображениях.

detectionResults = detect(detector, preprocessedTestData);

Вычислите детектор объекта с помощью метрики средней точности.

[ap,recall,precision] = evaluateDetectionPrecision(detectionResults, preprocessedTestData);

Кривая точности/отзыва (PR) показывает, насколько точен детектор при различных уровнях отзыва. Идеальная точность - 1 на всех уровнях отзыва. Использование большего количества данных может помочь повысить среднюю точность, но может потребовать больше времени на обучение. Постройте график кривой PR.

figure
plot(recall,precision)
xlabel('Recall')
ylabel('Precision')
grid on
title(sprintf('Average Precision = %.2f',ap))

Создание кода

После обучения и оценки детектора можно создать код для yolov2ObjectDetector с использованием графического процессора Coder™. Дополнительные сведения см. в примере Создание кода для обнаружения объектов с помощью кодера графического процессора YOLO v2 (GPU Coder).

Вспомогательные функции

function B = augmentData(A)
% Apply random horizontal flipping, and random X/Y scaling. Boxes that get
% scaled outside the bounds are clipped if the overlap is above 0.25. Also,
% jitter image color.

B = cell(size(A));

I = A{1};
sz = size(I);
if numel(sz)==3 && sz(3) == 3
    I = jitterColorHSV(I,...
        'Contrast',0.2,...
        'Hue',0,...
        'Saturation',0.1,...
        'Brightness',0.2);
end

% Randomly flip and scale image.
tform = randomAffine2d('XReflection',true,'Scale',[1 1.1]);
rout = affineOutputView(sz,tform,'BoundsStyle','CenterOutput');
B{1} = imwarp(I,tform,'OutputView',rout);

% Sanitize box data, if needed.
A{2} = helperSanitizeBoxes(A{2}, sz);

% Apply same transform to boxes.
[B{2},indices] = bboxwarp(A{2},tform,rout,'OverlapThreshold',0.25);
B{3} = A{3}(indices);

% Return original data only when all boxes are removed by warping.
if isempty(indices)
    B = A;
end
end

function data = preprocessData(data,targetSize)
% Resize image and bounding boxes to the targetSize.
sz = size(data{1},[1 2]);
scale = targetSize(1:2)./sz;
data{1} = imresize(data{1},targetSize(1:2));

% Sanitize box data, if needed.
data{2} = helperSanitizeBoxes(data{2},sz);

% Resize boxes to new image size.
data{2} = bboxresize(data{2},scale);
end

Ссылки

[1] Редмон, Джозеф и Али Фархади. «YOLO9000: лучше, быстрее, сильнее». В 2017 году Конференция IEEE по компьютерному зрению и распознаванию образов (CVPR), 6517-25. Гонолулу, HI: IEEE, 2017. https://doi.org/10.1109/CVPR.2017.690.