В этом примере показано, как сегментировать отдельные образцы людей и автомобилей с помощью многоклассовой сверточной нейронной сети на основе региона Маска (R-CNN).
Сегментация образца является методом компьютерного зрения, в котором вы обнаруживаете и локализуете объекты с одновременной генерацией карты сегментации для каждого из обнаруженных образцов.
Этот пример сначала показывает, как выполнить сегментацию образца с помощью предварительно обученной Mask R-CNN, которая обнаруживает два класса. Затем можно опционально загрузить набор данных и обучить мультикласс Mask R-CNN.
Загрузите предварительно обученную Mask R-CNN.
dataFolder = fullfile(tempdir,"coco"); trainedMaskRCNN_url = 'https://www.mathworks.com/supportfiles/vision/data/maskrcnn_pretrained_person_car.mat'; helper.downloadTrainedMaskRCNN(trainedMaskRCNN_url,dataFolder); pretrained = load(fullfile(dataFolder,'maskrcnn_pretrained_person_car.mat')); net = pretrained.net;
Извлечь подсеть сегментации маски можно используя extractMaskNetwork
вспомогательная функция, которая присоединена к этому примеру как вспомогательный файл в папке helper
.
maskSubnet = helper.extractMaskNetwork(net);
Сеть обучена обнаруживать людей и автомобили. Задайте имена классов, включая 'background'
класс, а также количество классов, исключая 'background'
класс.
classNames = {'person','car','background'}; numClasses = length(classNames)-1;
Чтение тестового изображения, содержащего объекты целевых классов.
imTest = imread('visionteam.jpg');
Определите целевой размер изображения для вывода.
targetSizeTest = [700 700 3];
Измените размер изображения, сохраняя соотношение сторон и масштабируя наибольшую размерность до целевого размера.
if size(imTest,1) > size(imTest,2) imTest = imresize(imTest,[targetSizeTest(1) NaN]); else imTest = imresize(imTest,[NaN targetSizeTest(2)]); end
Задайте параметры конфигурации сети, используя createMaskRCNNConfig
вспомогательная функция, которая присоединена к этому примеру как вспомогательный файл.
imageSizeTrain = [800 800 3]; params = createMaskRCNNConfig(imageSizeTrain,numClasses,classNames);
Обнаружите объекты и их маски с помощью функции helper detectMaskRCNN
, который присоединен к этому примеру как вспомогательный файл.
[boxes,scores,labels,masks] = detectMaskRCNN(net,maskSubnet,imTest,params);
Визуализируйте предсказания путем наложения обнаруженных масок на изображение с помощью insertObjectMask
функция.
if(isempty(masks)) overlayedImage = imTest; else overlayedImage = insertObjectMask(imTest,masks); end imshow(overlayedImage)
Отображение ограничивающих рамок и меток на объектах.
showShape("rectangle",gather(boxes),"Label",labels,"LineColor",'r')
Набор данных обучающих изображений COCO 2014 [2] состоит из 82 783 изображений. Данные аннотаций содержат по меньшей мере пять подписей, соответствующих каждому изображению.
Создайте директории для хранения обучающих изображений COCO и данных аннотации.
imageFolder = fullfile(dataFolder,"images"); captionsFolder = fullfile(dataFolder,"annotations"); if ~exist(imageFolder,'dir') mkdir(imageFolder) mkdir(captionsFolder) end
Загрузите обучающие изображения и подписи COCO 2014 из https://cocodataset.org/#download, нажав на ссылки «2014 Train image» и «2014 Train/Val annotations» соответственно. Извлеките файлы изображений в папку, заданную imageFolder
. Извлеките файлы аннотации в папку, заданную captionsFolder
.
annotationFile = fullfile(captionsFolder,"instances_train2014.json");
str = fileread(annotationFile);
Чтобы обучить Mask R-CNN, вам нужны эти данные.
Изображения RGB, которые служат входом в сеть, заданные как H-by-W-by-3 числовые массивы.
Ограничительные рамки для объектов в изображениях RGB, заданные как NumObjects-by-4 матрицы, с строками в формате [x y w h]).
Метки образцов, заданные как NumObjects-by-1 строковые векторы.
Образцы. Каждая маска является сегментацией одного образца в изображении. Набор данных COCO задает образцы объекта с помощью координат многоугольников, форматированных как NumObjects-by-2 массивов ячеек. Каждая строка массива содержит (x, y) координаты многоугольника вдоль контура одного образца на изображении. Однако Mask R-CNN в этом примере требует двоичных масок, заданных как логические массивы размера H-на-W-на-NumObjects.
COCO API для MATLAB позволяет вам получить доступ к данным аннотации. Загрузите COCO API для MATLAB из https://github.com/cocodataset/cocoapi, нажав кнопку « Код» и выбрав «Загрузить ZIP». Извлечение cocoapi-master
директория и его содержимое в папку, заданную dataFolder
. Если это необходимо для вашей операционной системы, скомпилируйте gason parser, следуя инструкциям в gason.m
файл в MatlabAPI
подкаталог.
Укажите расположение директории для COCO API для MATLAB и добавьте директорию к пути.
cocoAPIDir = fullfile(dataFolder,"cocoapi-master","MatlabAPI"); addpath(cocoAPIDir);
Укажите папку, в которой будут храниться файлы MAT.
unpackAnnotationDir = fullfile(dataFolder,"annotations_unpacked","matFiles"); if ~exist(unpackAnnotationDir,'dir') mkdir(unpackAnnotationDir) end
Извлеките аннотации COCO в файлы MAT с помощью unpackAnnotations
вспомогательная функция, которая присоединена к этому примеру как вспомогательный файл в папке helper
. Каждый файл MAT соответствует одному обучающему изображению и содержит имя файла, ограничивающие рамки, метки образцов и маски образцов для каждого обучающего изображения. Функция преобразует образцы объектов, заданные как многоугольники, в двоичные маски с помощью poly2mask
функция.
trainClassNames = {'person','car'}; helper.unpackAnnotations(trainClassNames,annotationFile,imageFolder,unpackAnnotationDir);
Mask R-CNN ожидает входные данные как массив ячеек 1 на 4, содержащий обучающее изображение RGB, ограничительные рамки, метки образцов и маски образцов.
Создайте файловый datastore с пользовательской функцией чтения, c ocoAnnotationMATReader
, который считывает содержимое распакованных файлов MAT аннотации, преобразует обучающие изображения полутонового цвета в RGB и возвращает данные как массив ячеек 1 на 4 в необходимом формате. Пользовательская функция чтения присоединена к этому примеру как вспомогательный файл в папке helper
.
ds = fileDatastore(unpackAnnotationDir, ... 'ReadFcn',@(x)helper.cocoAnnotationMATReader(x,imageFolder));
Задайте размер входа сети.
imageSize = [800 800 3];
Предварительно обработайте обучающие изображения, ограничительные рамки и маски образцов до размера, ожидаемого сетью с помощью transform
функция. The transform
функция обрабатывает данные с помощью операций, заданных в preprocessData
вспомогательная функция. Функция helper присоединена к примеру как вспомогательный файл в папке helper
.
The preprocessData
Функция helper выполняет эти операции с обучающими изображениями, ограничивающими рамками и масками образцов:
Измените размер изображений и масок RGB с помощью imresize
выполнять функцию и перерассчитывать ограничительные рамки с помощью bboxresize
функция. Функция helper выбирает однородный масштабный коэффициент, так что меньшая размерность изображения, ограничивающего прямоугольника или маски равен размеру входа целевой сети.
Обрезка изображений и масок RGB с помощью imcrop
функции и обрезка ограничивающих рамок с помощью bboxcrop
функция. Функция helper обрабатывает изображение, ограничивающий прямоугольник или маску так, что больший размерность равен целевому размеру входа сети.
Масштабируйте пиксельные значения изображений RGB в области значений [0, 1].
dsTrain = transform(ds,@(x)helper.preprocessData(x,imageSize));
Предварительный просмотр данных, возвращенных преобразованным datastore.
data = preview(dsTrain)
data=1×4 cell array
{800×800×3 uint8} {16×4 double} {16×1 categorical} {800×800×16 logical}
Mask R-CNN основывается на Faster R-CNN с ResNet-101 базовой сетью. Получите слои Faster R-CNN с помощью fasterRCNNLayers
функция.
netFasterRCNN = fasterRCNNLayers(params.ImageSize,numClasses,params.AnchorBoxes,'resnet101');
Измените сеть для Mask R-CNN с помощью createMaskRCNN
вспомогательная функция. Эта функция присоединена к примеру как вспомогательный файл. Функция helper выполняет следующие модификации сети:
Замените rpnSoftmaxLayer
с пользовательским слоем программного обеспечения RPM, заданным вспомогательным файлом RPNSoftmax
в папке layer
.
Замените regionProposalLayer
со слоем предложения пользовательской области, заданным вспомогательным файлом RegionProposal
в папке layer
.
Замените roiMaxPooling2dLayer
с roiAlignLayer
.
Добавьте заголовок сегментации маски для сегментации на уровне пикселей.
netMaskRCNN = createMaskRCNN(netFasterRCNN,numClasses,params);
Преобразуйте сеть в dlnetwork
(Deep Learning Toolbox) объект.
dlnet = dlnetwork(netMaskRCNN);
Визуализация сети с помощью Deep Network Designer.
deepNetworkDesigner(netMaskRCNN)
Задайте опции для оптимизации SGDM. Обучите сеть на 30 эпох.
initialLearnRate = 0.01; momentum = 0.9; decay = 0.0001; velocity = []; maxEpochs = 30; miniBatchSize = 2;
Создайте minibatchqueue
(Deep Learning Toolbox) объект, который управляет мини-пакетированием наблюдений в пользовательском цикле обучения. The minibatchqueue
объект также переводит данные в dlarray
(Deep Learning Toolbox) объект, который включает автоматическую дифференциацию в применениях глубокого обучения.
Задайте пользовательскую функцию дозирования с именем miniBatchFcn
. Изображения сгруппированы по четвертой размерности, чтобы получить сформированный пакет H-на-W-на-C-на-miniBatchSize. Для других достоверных данных сконфигурирован массив ячеек длиной, равной размеру мини-пакета.
miniBatchFcn = @(img,boxes,labels,masks) deal(cat(4,img{:}),boxes,labels,masks);
Задайте мини-пакетный формат извлечения данных для данных изображения как "SSCB"
(пространственный, пространственный, канальный, пакетный). Если поддерживаемый графический процессор доступен для расчетов, то minibatchqueue
объект обрабатывает мини-пакеты в фоновом режиме в параллельном пуле во время обучения.
mbqTrain = minibatchqueue(dsTrain,4, ... "MiniBatchFormat",["SSCB","","",""], ... "MiniBatchSize",miniBatchSize, ... "OutputCast",["single","","",""], ... "OutputAsDlArray",[true,false,false,false], ... "MiniBatchFcn",miniBatchFcn, ... "OutputEnvironment",["auto","cpu","cpu","cpu"]);
Чтобы обучить сеть, установите doTraining
переменная в следующем коде, для true
. Обучите модель в пользовательском цикле обучения. Для каждой итерации:
Считайте данные для текущего мини-пакета с помощью next
(Deep Learning Toolbox) функция.
Оцените градиенты модели с помощью dlfeval
(Deep Learning Toolbox) функцию и networkGradients
вспомогательная функция. Функция networkGradients
, перечисленная как вспомогательная функция, возвращает градиенты потерь относительно настраиваемых параметров, соответствующих потерь мини-пакета и состояния текущей партии.
Обновляйте параметры сети с помощью sgdmupdate
(Deep Learning Toolbox) функция.
Обновление state
параметры сети с скользящим средним значением.
Обновите график процесса обучения.
Обучите на графическом процессоре, если он доступен. Для использования GPU требуется Parallel Computing Toolbox™ и графический процессор с поддержкой CUDA ® NVIDIA ®. Для получения дополнительной информации смотрите Поддержку GPU by Release (Parallel Computing Toolbox).
doTraining = false; if doTraining iteration = 1; start = tic; % Create subplots for the learning rate and mini-batch loss fig = figure; [lossPlotter] = helper.configureTrainingProgressPlotter(fig); % Initialize verbose output helper.initializeVerboseOutput([]); % Custom training loop for epoch = 1:maxEpochs reset(mbqTrain) shuffle(mbqTrain) while hasdata(mbqTrain) % Get next batch from minibatchqueue [X,gtBox,gtClass,gtMask] = next(mbqTrain); % Evaluate the model gradients and loss [gradients,loss,state] = dlfeval(@networkGradients,X,gtBox,gtClass,gtMask,dlnet,params); dlnet.State = state; % Compute the learning rate for the current iteration learnRate = initialLearnRate/(1 + decay*iteration); if(~isempty(gradients) && ~isempty(loss)) [dlnet.Learnables,velocity] = sgdmupdate(dlnet.Learnables,gradients,velocity,learnRate,momentum); else continue; end helper.displayVerboseOutputEveryEpoch(start,learnRate,epoch,iteration,loss); % Plot loss/accuracy metric D = duration(0,0,toc(start),'Format','hh:mm:ss'); addpoints(lossPlotter,iteration,double(gather(extractdata(loss)))) subplot(2,1,2) title(strcat("Epoch: ",num2str(epoch),", Elapsed: "+string(D))) drawnow iteration = iteration + 1; end end net = dlnet; % Save the trained network modelDateTime = string(datetime('now','Format',"yyyy-MM-dd-HH-mm-ss")); save(strcat("trainedMaskRCNN-",modelDateTime,"-Epoch-",num2str(maxEpochs),".mat"),'net'); end
Используя обученную сеть, можно выполнить сегментацию образцов на тестовых изображениях, как показано в разделе Выполните сегментацию образцов Используя предварительно обученную маску R-CNN.
[1] Он, Кайминг, Джорджия Гкиоксари, Пётр Доллар и Росс Гиршик. «Маска R-CNN». Препринт, представленный 24 января 2018 года. https://arxiv.org/abs/1703.06870.
[2] Лин, Цунг-И, Майкл Мэйр, Серж Рэйни, Любомир Бурдев, Росс Гиршик, Джеймс Хейс, Пьетро Перона, Дева Раманан, К. Лоуренс Зитник и Пётр Доллар. «Microsoft COCO: общие объекты в контексте», 1 мая 2014 года. https://arxiv.org/abs/1405.0312v3.
fasterRCNNLayers
| insertObjectMask
| transform
| dlfeval
(Deep Learning Toolbox) | sgdmupdate
(Deep Learning Toolbox)FileDatastore
| roiAlignLayer
| dlarray
(Deep Learning Toolbox) | dlnetwork
(Deep Learning Toolbox) | minibatchqueue
(Deep Learning Toolbox)