exponenta event banner

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

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

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

Предварительные условия для сторонних производителей

  • Процессор 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-образный граф. Первоначально сеть была обучена выполнять прогнозирование для биомедицинских приложений сегментации изображений. Этот пример демонстрирует способность сети отслеживать изменения лесного покрова с течением времени. Природоохранные учреждения отслеживают обезлесение для оценки и оценки состояния окружающей среды и состояния окружающей среды в регионе.

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

В этом примере используются данные парка штата Хэмлин-Бич [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

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

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);

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

Функция начальной точки segureImageUnet.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 представляет собой маску, которая указывает допустимую область сегментации.

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

test_data  = switchChannelsToThirdPlane(test_data);

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

whos test_data
  Name               Size                     Bytes  Class     Attributes

  test_data      12446x7654x7            1333663576  uint16              

В этом примере используется обрезанная версия полного набора данных парка штата Хэмлин-Бич, который 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 для функции точки входа segiveImageUnet.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

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 препринт arXiv:1505.04597, 2015.

[2] Кемкер, Р., С. Сальваджо и К. Канан. «Многоспектральный набор данных высокого разрешения для семантической сегментации». CoRR, abs/1703.01918, 2017.

См. также

| | (инструментарий для глубокого обучения)

Связанные темы