Генерация кода для семантической сегментации на центральных процессорах Intel, использующих U-Net

Этот пример демонстрирует генерацию кода для приложения сегментации изображений, которое использует глубокое обучение. Он использует codegen команда для генерации MEX-функции, которая выполняет предсказание с помощью нейронной сети для глубокого обучения U-Net для сегментации изображений.

Для аналогичного примера, который демонстрирует сегментацию изображений при помощи U-Net, но не использует codegen команда, см. Семантическая сегментация мультиспектральных изображений с использованием глубокого обучения (Image Processing Toolbox).

Необходимые условия для третьих лиц

  • Процессор Xeon с поддержкой инструкций Intel Advanced Vector Extensions 2 (Intel AVX2)

Этот пример поддерживается на платформах Linux ®, Windows ® и macOS.

Этот пример использует библиотеку Intel MKL-DNN, которая поставляется с MATLAB и генерирует MEX-функцию для семантической сегментации.

Этот пример не поддерживается в MATLAB Online.

Обзор U-Net

U-Net [1] является типом сверточной нейронной сети (CNN), которая предназначена для семантической сегментации изображений. В U-Net начальная серия сверточных слоев перемежается с максимальными слоями объединения, последовательно уменьшая разрешение входного изображения. Эти слои сопровождаются серией сверточных слоев, чередующихся с операторами повышающей дискретизации, последовательно увеличивая разрешение входного изображения. Комбинация этих двух последовательных путей образует U-образный график. Сеть была первоначально обучена для выполнения предсказания для биомедицинских приложений сегментации изображений. Этот пример демонстрирует способность сети отслеживать изменения лесного покрова с течением времени. Природоохранные учреждения отслеживают обезлесение для оценки и квалификации экологического и экологического здоровья области.

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

Этот пример использует Данные парка штата Хэмлин-Бич [2] вместе с предварительно обученной сетью U-Net в порядок, чтобы правильно классифицировать каждый пиксель.

U-Net, который использует этот пример, обучен сегментировать пиксели, принадлежащие 18 классам, которые включают:

0. Other Class/Image Border      7. Picnic Table         14. Grass
1. Road Markings                 8. Black Wood Panel     15. Sand
2. Tree                          9. White Wood Panel     16. Water (Lake)
3. Building                     10. Orange Landing Pad   17. Water (Pond)
4. Vehicle (Car, Truck, or Bus) 11. Water Buoy           18. Asphalt (Parking Lot/Walkway)
5. Person                       12. Rocks
6. Lifeguard Chair              13. Other Vegetation

Получите предварительно обученный сетевой объект U-Net DAG

trainedUnet_url = 'https://www.mathworks.com/supportfiles/vision/data/multispectralUnet.mat';
downloadTrainedUnet(trainedUnet_url,pwd);
Downloading Pre-trained U-net for Hamlin Beach dataset...
This will take several minutes to download...
done.

ld = load("trainedUnet/multispectralUnet.mat");
net = ld.net;

Сеть DAG содержит 58 слоев, включая свертку, максимальное объединение, конкатенацию глубин и выходные слои классификации пикселей. Чтобы отобразить интерактивную визуализацию архитектуры нейронной сети для глубокого обучения, используйте analyzeNetwork (Deep Learning Toolbox) функция.

%   analyzeNetwork(net);

The segmentImageUnet Функция точки входа

Функция точки входа segmentImageUnet.m выполняет семантическую сегментацию входного изображения для каждой закрашенной фигуры фиксированного размера с помощью сети multispectralUnet, содержащейся в multispectralUnet.mat файл. Эта функция загружает сетевой объект из multispectralUnet.mat файл в постоянную переменную mynet. Функция повторно использует эту постоянную переменную в последующих вызовах предсказания.

type('segmentImageUnet.m')
%  OUT = segmentImageUnet(IM, PATCHSIZE) returns a semantically segmented
%  image, segmented using the network multispectralUnet. The segmentation
%  is performed over each patch of size PATCHSIZE.
%
% Copyright 2019-2020 The MathWorks, Inc.
function out = segmentImageUnet(im, patchSize)

%#codegen

persistent mynet;

if isempty(mynet)
    mynet = coder.loadDeepLearningNetwork('trainedUnet/multispectralUnet.mat');
end

[height, width, nChannel] = size(im);
patch = coder.nullcopy(zeros([patchSize, nChannel-1]));

% pad image to have dimensions as multiples of patchSize
padSize = zeros(1,2);
padSize(1) = patchSize(1) - mod(height, patchSize(1));
padSize(2) = patchSize(2) - mod(width, patchSize(2));

im_pad = padarray (im, padSize, 0, 'post');
[height_pad, width_pad, ~] = size(im_pad);

out = zeros([size(im_pad,1), size(im_pad,2)], 'uint8');

for i = 1:patchSize(1):height_pad    
    for j =1:patchSize(2):width_pad        
        for p = 1:nChannel-1              
            patch(:,:,p) = squeeze( im_pad( i:i+patchSize(1)-1,...
                                            j:j+patchSize(2)-1,...
                                            p));            
        end
         
        % pass in input
        segmentedLabels = activations(mynet, patch, 'Segmentation-Layer');
        
        % Takes the max of each channel (6 total at this point)
        [~,L] = max(segmentedLabels,[],3);
        patch_seg = uint8(L);
        
        % populate section of output
        out(i:i+patchSize(1)-1, j:j+patchSize(2)-1) = patch_seg;
       
    end
end

% Remove the padding
out = out(1:height, 1:width);

Подготовка данных

Загрузите данные о государственном парке Хамлин-Бич.

if ~exist(fullfile(pwd,'data'),'dir')
    url = 'http://www.cis.rit.edu/~rmk6217/rit18_data.mat';
    downloadHamlinBeachMSIData(url,pwd+"/data/");
end
Downloading Hamlin Beach dataset...
This will take several minutes to download...
done.

Загрузите и исследуйте данные в MATLAB.

load(fullfile(pwd,'data','rit18_data','rit18_data.mat'));

% Examine data
whos test_data
  Name           Size                         Bytes  Class     Attributes

  test_data      7x12446x7654            1333663576  uint16              

Изображение имеет семь каналов. Цветовые каналы RGB являются четвертым, пятым и шестым каналами изображений. Первые три канала соответствуют ближним инфракрасным полосам и подсвечивают различные компоненты изображения на основе их тепловых сигнатур. Канал 7 является маской, которая указывает на допустимую область сегментации.

Мультиспектральные данные изображения расположены как массивы numChannels-by-width-by-height. В MATLAB многоканальные изображения расположены как массивы width-by-height-by-numChannels. Чтобы изменить форму данных так, чтобы каналы находились в третьей размерности, используйте функцию helper, switchChannelsToThirdPlane.

test_data  = switchChannelsToThirdPlane(test_data);

Подтвердите, что данные имеют правильную структуру (последние каналы).

whos test_data
  Name               Size                     Bytes  Class     Attributes

  test_data      12446x7654x7            1333663576  uint16              

Этот пример использует обрезанную версию полного набора данных Hamlin Beach State Park, который test_data переменная содержит. Обрезка высоты и ширины test_data чтобы создать переменную input_data который использует этот пример.

test_datacropRGB = imcrop(test_data(:,:,1:3),[2600, 3000, 2000, 2000]);
test_datacropInfrared = imcrop(test_data(:,:,4:6),[2600, 3000, 2000, 2000]);
test_datacropMask = imcrop(test_data(:,:,7),[2600, 3000, 2000, 2000]);
input_data(:,:,1:3) = test_datacropRGB;
input_data(:,:,4:6) = test_datacropInfrared;
input_data(:,:,7) = test_datacropMask;

Исследуйте переменную input_data.

whos('input_data');
  Name               Size                   Bytes  Class     Attributes

  input_data      2001x2001x7            56056014  uint16              

Сгенерируйте MEX

Чтобы сгенерировать MEX-функцию для функции точки входа segmentImageUnet.m, создайте объект строения кода cfg для генерации кода MEX. Установите целевой язык на C++. Используйте coder.DeepLearningConfig (GPU Coder) для создания объекта строения глубокого обучения MKL-DNN и назначения его DeepLearningConfig свойство cfg. Запуск codegen команда, задающая размер входа [12446 7654 7] и закрашенной фигуры размер [1024 1024]. Эти значения соответствуют размеру всего input_data переменная. Меньшие размеры закрашенной фигуры ускоряют вывод. Чтобы увидеть, как вычисляются закрашенные фигуры, смотрите segmentImageUnet функция точки входа.

cfg = coder.config('mex');
cfg.TargetLang = 'C++';
cfg.DeepLearningConfig = coder.DeepLearningConfig('mkldnn');
codegen -config cfg segmentImageUnet -args {ones(size(input_data),'uint16'),coder.Constant([1024 1024])} -report
Code generation successful: To view the report, open('codegen\mex\segmentImageUnet\html\report.mldatx').

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

The segmentImageUnet функция принимает input_data и вектор, содержащий размерности закрашенной фигуры в качестве входов. Функция разделяет изображение на закрашенные фигуры, предсказывает пиксели в конкретной закрашенной фигуре и, наконец, объединяет все закрашенные фигуры. Из-за большого размера input_data (12446x7654x7), легче обработать изображение в закрашенных фигурах.

segmentedImage = segmentImageUnet_mex(input_data,[1024 1024]);

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

segmentedImage = uint8(input_data(:,:,7)~=0) .* segmentedImage;

Удалите шум и бродячие пиксели с помощью medfilt2 функция.

segmentedImage = medfilt2(segmentedImage,[5,5]);

Отображение сегментированных input_data U-Net

Эта строка кода создает вектор имен классов:

classNames = net.Layers(end).Classes;

Наложите метки на сегментированное тестовое изображение RGB и добавьте цветовую панель к сегментационному изображению.

% Display input data

figure(1);
imshow(histeq(input_data(:,:,1:3)));
title('Input Image');
cmap = jet(numel(classNames));
segmentedImageOut = labeloverlay(imadjust(input_data(:,:,4:6),[0 0.6],[0.1 0.9],0.55),segmentedImage,'Transparency',0,'Colormap',cmap);

% Display segmented data

figure(2);
imshow(segmentedImageOut);
title('Segmented Image Output');
N = numel(classNames);
ticks = 1/(N*2):1/N:1;
colorbar('TickLabels',cellstr(classNames),'Ticks',ticks,'TickLength',0,'TickLabelInterpreter','none');
colormap(cmap)
title('Segmented Image using Mkldnn');
segmentedImageOverlay = labeloverlay(imadjust(input_data(:,:,4:6),[0 0.6],[0.1 0.9],0.55),segmentedImage,'Transparency',0.7,'Colormap',cmap);
figure(3);
imshow(segmentedImageOverlay);
title('Segmented Overlay Image');

Ссылки

[1] Роннебергер, Олаф, Филипп Фишер и Томас Брокс. «U-Net: Сверточные сети для сегментации биомедицинских изображений». arXiv preprint arXiv:1505.04597, 2015.

[2] Kemker, R., C. Salvaggio, and C. Kanan. «Мультиспектральный набор данных высокого разрешения для семантической сегментации». CoRR, abs/1703.01918, 2017.

См. также

| | (Deep Learning Toolbox)

Похожие темы