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

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

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

Сторонние необходимые условия

  • Процессор Xeon с поддержкой Intel Усовершенствованные Векторные Расширения 2 (Intel AVX2) инструкции

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

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

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

Обзор U-Net

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

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

Этот пример использует Данные о национальном парке Hamlin Beach [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 функция.

%   analyzeNetwork(net);

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

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

Загрузите данные о национальном парке Hamlin Beach.

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 шириной массивами высоты. В MATLAB многоканальные изображения располагаются как ширина высотой numChannels массивами. Чтобы изменить данные так, чтобы каналы были в третьей размерности, используйте функцию помощника, switchChannelsToThirdPlane.

test_data  = switchChannelsToThirdPlane(test_data);

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

whos test_data
  Name               Size                     Bytes  Class     Attributes

  test_data      12446x7654x7            1333663576  uint16              

Этот пример использует обрезанную версию полного набора данных 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

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

Отобразите U-Net Сегментированный input_data

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

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] Ronneberger, Олаф, Филипп Фишер и Томас Брокс. "U-Net: Сверточные Сети для Биомедицинской Сегментации Изображений". arXiv предварительно распечатывают arXiv:1505.04597, 2015.

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

Смотрите также

(MATLAB Coder) | (MATLAB Coder) |

Похожие темы