В этом примере показано, как сегментировать отдельные экземпляры людей и автомобилей, используя многоклассовую сверточную нейронную сеть на основе области Маска (R-CNN).
Сегментация экземпляров - это метод компьютерного зрения, при котором объекты обнаруживаются и локализуются при одновременном создании карты сегментации для каждого из обнаруженных экземпляров.
В этом примере сначала показано, как выполнить сегментацию экземпляра с использованием предварительно обученной маски R-CNN, которая обнаруживает два класса. Затем можно загрузить набор данных и обучить мультиклассную маску R-CNN.
Загрузите предварительно подготовленную маску 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);
Обнаружение объектов и их масок с помощью функции помощника 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» и «Аннотации поезда/вала 2014» соответственно. Извлеките файлы изображений в папку, указанную в imageFolder. Извлечение файлов аннотаций в папку, указанную в captionsFolder.
annotationFile = fullfile(captionsFolder,"instances_train2014.json");
str = fileread(annotationFile);Чтобы обучить маску 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) многоугольника вдоль границы одного экземпляра изображения. Однако маска R-CNN в этом примере требует двоичных масок, указанных как логические массивы размера H-by-W-by-NumObjects.
API COCO для MATLAB позволяет получить доступ к данным аннотации. Загрузите API COCO для MATLAB из https://github.com/cocodataset/cocoapi, нажав кнопку «Код» и выбрав «Загрузить ZIP». Извлеките cocoapi-master каталог и его содержимое в папку, указанную в dataFolder. При необходимости для вашей операционной системы скомпилируйте газоанализатор, следуя инструкциям в gason.m файл в пределах MatlabAPI подкаталога.
Укажите расположение каталога для API COCO для 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);Маска R-CNN ожидает входные данные в виде массива ячеек 1 на 4, содержащего обучающее изображение RGB, ограничивающие рамки, метки экземпляров и маски экземпляров.
Создание хранилища данных файла с пользовательской функцией чтения, cocoAnnotationMATReader, которая считывает содержимое распакованных файлов MAT аннотаций, преобразует обучающие изображения в градациях серого в RGB и возвращает данные в виде массива ячеек 1 на 4 в требуемом формате. Пользовательская функция чтения присоединена к этому примеру как вспомогательный файл в папке helper.
ds = fileDatastore(unpackAnnotationDir, ... 'ReadFcn',@(x)helper.cocoAnnotationMATReader(x,imageFolder));
Укажите входной размер сети.
imageSize = [800 800 3];
Предварительная обработка обучающих изображений, ограничивающих рамок и масок экземпляров до размера, ожидаемого сетью, с помощью transform функция. transform обрабатывает данные с помощью операций, указанных в preprocessData функция помощника. Вспомогательная функция прикрепляется к примеру как вспомогательный файл в папке helper.
preprocessData функция помощника выполняет следующие операции с обучающими изображениями, ограничивающими рамками и масками экземпляров:
Изменение размеров RGB-изображений и масок с помощью imresize и масштабировать ограничивающие рамки с помощью bboxresize функция. Вспомогательная функция выбирает однородный масштабный коэффициент таким образом, что меньший размер изображения, ограничивающей рамки или маски равен размеру входного сигнала целевой сети.
Обрезка изображений и масок RGB с помощью imcrop и обрезать ограничивающие рамки с помощью bboxcrop функция. Вспомогательная функция отсекает изображение, ограничивающую рамку или маску таким образом, что больший размер равен размеру входного сигнала целевой сети.
Масштабируйте значения пикселей изображений RGB в диапазоне [0, 1].
dsTrain = transform(ds,@(x)helper.preprocessData(x,imageSize));
Предварительный просмотр данных, возвращенных преобразованным хранилищем данных.
data = preview(dsTrain)
data=1×4 cell array
{800×800×3 uint8} {16×4 double} {16×1 categorical} {800×800×16 logical}
Маска R-CNN основана на более быстрой R-CNN с базовой сетью ResNet-101. Получите более быстрые уровни R-CNN с помощью fasterRCNNLayers функция.
netFasterRCNN = fasterRCNNLayers(params.ImageSize,numClasses,params.AnchorBoxes,'resnet101');Изменение сети для маски R-CNN с помощью createMaskRCNN функция помощника. Эта функция присоединена к примеру как вспомогательный файл. Вспомогательная функция выполняет следующие изменения сети:
Замените rpnSoftmaxLayer с пользовательским уровнем RPM softmax, определяемым поддерживающим файлом RPNSoftmax в папке layer.
Замените regionProposalLayer со слоем предложения пользовательской области, определяемым поддерживающим файлом RegionProposal в папке layer.
Замените roiMaxPooling2dLayer с roiAlignLayer.
Добавление головки сегментации маски для сегментации на уровне пикселей.
netMaskRCNN = createMaskRCNN(netFasterRCNN,numClasses,params);
Преобразование сети в dlnetwork(Панель инструментов глубокого обучения).
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), который управляет мини-пакетами наблюдений в пользовательском цикле обучения. minibatchqueue объект также передает данные в dlarray Объект (Deep Learning Toolbox), позволяющий автоматически дифференцировать приложения для глубокого обучения.
Определение пользовательской функции дозирования с именем miniBatchFcn. Изображения объединяются вдоль четвертого измерения, чтобы получить партию в форме H-by-W-by-C-by-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, если он доступен. Для использования графического процессора требуются параллельные вычислительные Toolbox™ и графический процессор NVIDIA ® с поддержкой CUDA ®. Дополнительные сведения см. в разделе Поддержка графического процессора по выпуску (Панель инструментов параллельных вычислений).
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 (инструментарий для глубокого обучения) | sgdmupdate (инструментарий для глубокого обучения)FileDatastore | roiAlignLayer | dlarray (инструментарий глубокого обучения) | dlnetwork (инструментарий для глубокого обучения) | minibatchqueue (инструментарий для глубокого обучения)