Семантическая сегментация Используя расширенные свертки

Этот пример показывает, как обучить семантическую сеть сегментации использование расширенных сверток.

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

Семантические сети сегментации как DeepLab [1] делают широкое применение расширенных сверток (также известный atrous свертки), потому что они могут увеличить восприимчивое поле слоя (область входа, который слои видят), не увеличивая число параметров или вычислений.

Загрузите данные тренировки

Пример использует простой набор данных 32x32 треугольные изображения в целях рисунка. Набор данных включает сопроводительные пиксельные наземные данные об истине метки. Загрузите данные тренировки с помощью imageDatastore и pixelLabelDatastore.

dataFolder = fullfile(toolboxdir('vision'),'visiondata','triangleImages');
imageFolderTrain = fullfile(dataFolder,'trainingImages');
labelFolderTrain = fullfile(dataFolder,'trainingLabels');

Создайте datastore изображений для изображений.

imdsTrain = imageDatastore(imageFolderTrain);

Создайте pixelLabelDatastore для заземляющих пиксельных меток истины.

classNames = ["triangle" "background"];
labels = [255 0];
pxdsTrain = pixelLabelDatastore(labelFolderTrain,classNames,labels)
pxdsTrain = 
  PixelLabelDatastore with properties:

                       Files: {200×1 cell}
                  ClassNames: {2×1 cell}
                    ReadSize: 1
                     ReadFcn: @readDatastoreImage
    AlternateFileSystemRoots: {}

Создайте семантическую сеть сегментации

Этот пример использует простую семантическую сеть сегментации на основе расширенных сверток.

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

pximdsTrain = pixelLabelImageDatastore(imdsTrain,pxdsTrain);
tbl = countEachLabel(pximdsTrain)
tbl=2×3 table
        Name        PixelCount    ImagePixelCount
    ____________    __________    _______________

    'triangle'           10326       2.048e+05   
    'background'    1.9447e+05       2.048e+05   

Большинство пиксельных меток для фона. Эта неустойчивость класса смещает процесс обучения в пользу доминирующего класса. Чтобы зафиксировать это, используйте взвешивание класса, чтобы сбалансировать классы. Существует несколько методов для вычислительных весов класса. Одна общепринятая методика является обратным взвешиванием частоты, где веса класса являются инверсией частот класса. Это увеличивает вес, данный недостаточно представленным классам. Вычислите веса класса с помощью обратного взвешивания частоты.

numberPixels = sum(tbl.PixelCount);
frequency = tbl.PixelCount / numberPixels;
classWeights = 1 ./ frequency;

Создайте сеть для пикселя classificaiton с входным слоем изображений с входным размером, соответствующим размеру входных изображений. Затем, задайте три блока свертки, обработайте в пакетном режиме нормализацию и слои ReLU. Для каждого сверточного слоя задайте 32 3х3 фильтра с увеличивающимися факторами расширения и задайте, чтобы заполнить входные параметры, чтобы быть одного размера как выходные параметры путем установки опции 'Padding' на 'same'. Чтобы классифицировать пиксели, включайте сверточный слой с K свертки 1 на 1, где K является количеством классов, сопровождаемых softmax слоем и pixelClassificationLayer с обратными весами класса.

inputSize = [32 32 1];
filterSize = 3;
numFilters = 32;
numClasses = numel(classNames);

layers = [
    imageInputLayer(inputSize)
    
    convolution2dLayer(filterSize,numFilters,'DilationFactor',1,'Padding','same')
    batchNormalizationLayer
    reluLayer
    
    convolution2dLayer(filterSize,numFilters,'DilationFactor',2,'Padding','same')
    batchNormalizationLayer
    reluLayer
    
    convolution2dLayer(filterSize,numFilters,'DilationFactor',4,'Padding','same')
    batchNormalizationLayer
    reluLayer
    
    convolution2dLayer(1,numClasses)
    softmaxLayer
    pixelClassificationLayer('Classes',classNames,'ClassWeights',classWeights)];

Обучение сети

Задайте опции обучения. Используя решатель SGDM, обучайтесь в течение 100 эпох, мини-пакетный размер 64, и изучите уровень 0.001.

options = trainingOptions('sgdm', ...
    'MaxEpochs', 100, ...
    'MiniBatchSize', 64, ... 
    'InitialLearnRate', 1e-3);

Обучите сеть с помощью trainNetwork.

net = trainNetwork(pximdsTrain,layers,options);
Training on single GPU.
Initializing image normalization.
|========================================================================================|
|  Epoch  |  Iteration  |  Time Elapsed  |  Mini-batch  |  Mini-batch  |  Base Learning  |
|         |             |   (hh:mm:ss)   |   Accuracy   |     Loss     |      Rate       |
|========================================================================================|
|       1 |           1 |       00:00:00 |       67.54% |       0.7098 |          0.0010 |
|      17 |          50 |       00:00:03 |       84.60% |       0.3851 |          0.0010 |
|      34 |         100 |       00:00:06 |       89.85% |       0.2536 |          0.0010 |
|      50 |         150 |       00:00:09 |       93.39% |       0.1959 |          0.0010 |
|      67 |         200 |       00:00:11 |       95.89% |       0.1559 |          0.0010 |
|      84 |         250 |       00:00:14 |       97.29% |       0.1188 |          0.0010 |
|     100 |         300 |       00:00:18 |       98.28% |       0.0970 |          0.0010 |
|========================================================================================|

Тестирование сети

Загрузите тестовые данные. Создайте datastore изображений для изображений. Создайте pixelLabelDatastore для заземляющих пиксельных меток истины.

imageFolderTest = fullfile(dataFolder,'testImages');
imdsTest = imageDatastore(imageFolderTest);
labelFolderTest = fullfile(dataFolder,'testLabels');
pxdsTest = pixelLabelDatastore(labelFolderTest,classNames,labels);

Сделайте прогнозы с помощью тестовых данных, и обучил сеть.

pxdsPred = semanticseg(imdsTest,net,'WriteLocation',tempdir);
Running semantic segmentation network
-------------------------------------
* Processing 100 images.
* Progress: 100.00%

Оцените точность прогноза с помощью evaluateSemanticSegmentation.

metrics = evaluateSemanticSegmentation(pxdsPred,pxdsTest);
Evaluating semantic segmentation results
----------------------------------------
* Selected metrics: global accuracy, class accuracy, IoU, weighted IoU, BF score.
* Processing 100 images...
[==================================================] 100%
Elapsed time: 00:00:00
Estimated time remaining: 00:00:00
* Finalizing... Done.
* Data set metrics:

    GlobalAccuracy    MeanAccuracy    MeanIoU    WeightedIoU    MeanBFScore
    ______________    ____________    _______    ___________    ___________

       0.98334          0.99107       0.85869      0.97109        0.68197  

Для получения дополнительной информации об оценке семантических сетей сегментации смотрите evaluateSemanticSegmentation.

Сегмент новое изображение

Читайте и отобразитесь, тест отображают triangleTest.jpg.

imgTest = imread('triangleTest.jpg');
figure
imshow(imgTest)

Сегментируйте тестовое изображение с помощью semanticseg и отобразите результаты с помощью labeloverlay.

C = semanticseg(imgTest,net);
B = labeloverlay(imgTest,C);
figure
imshow(B)

Ссылки

  1. Чен, Лян-Чие, Георгиос Папандреу, Iasonas Kokkinos, Кевин Мерфи и Алан Л. Юилл. "Deeplab: Семантическая сегментация изображений с глубокими сверточными сетями, atrous свертка и полностью соединенный crfs". Транзакции IEEE согласно анализу шаблона и искусственному интеллекту 40, № 4 (2018): 834-848.