Этот пример показывает генерацию кода для приложения сегментации изображений что глубокое обучение использования. Это использует codegen
команда, чтобы сгенерировать MEX-функцию, которая выполняет предсказание на Сетевом объекте DAG для U-Net, нейронной сети для глубокого обучения для сегментации изображений.
Для подобного примера, покрывающего сегментацию изображений при помощи U-Net без codegen
команда, смотрите Семантическую Сегментацию Многоспектральных Изображений Используя Глубокое обучение (Image Processing Toolbox).
Необходимый
Этот пример генерирует MEX CUDA и имеет следующие сторонние требования.
CUDA® включил NVIDIA® графический процессор и совместимый драйвер.
Дополнительный
Для сборок неMEX, таких как статические, динамические библиотеки или исполняемые файлы, этот пример имеет следующие дополнительные требования.
Инструментарий NVIDIA.
Библиотека NVIDIA cuDNN.
Переменные окружения для компиляторов и библиотек. Для получения дополнительной информации смотрите Стороннее Оборудование (GPU Coder) и Подготовка Необходимых как условие продуктов (GPU Coder).
Используйте coder.checkGpuInstall
Функция (GPU Coder), чтобы проверить, что компиляторы и библиотеки, необходимые для выполнения этого примера, настраиваются правильно.
envCfg = coder.gpuEnvConfig('host'); envCfg.DeepLibTarget = 'cudnn'; envCfg.DeepCodegen = 1; envCfg.Quiet = 1; coder.checkGpuInstall(envCfg);
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
segmentImageUnet
Функция точки входаsegmentImageUnet.m
функция точки входа выполняет patchwise семантическую сегментацию на входном изображении при помощи 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);
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;
Загрузите данные о национальном парке Hamlin Beach.
if ~exist(fullfile(pwd,'data')) 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); % Confirm data has the correct structure (channels last). whos test_data
Name Size Bytes Class Attributes test_data 12446x7654x7 1333663576 uint16
Сгенерировать код CUDA для segmentImageUnet.m
функция точки входа, создайте объект GPU Configuration для цели MEX установка выходного языка на C++. Используйте coder.DeepLearningConfig
(GPU Coder) функция, чтобы создать CuDNN
объект настройки глубокого обучения и присвоение это к DeepLearningConfig
свойство объекта настройки графического процессора кода. Запустите codegen
команда, задающая входной размер [12446,7654,7] и размер закрашенной фигуры [1024,1024]. Эти значения соответствуют целому test_data размеру. Меньшие размеры закрашенной фигуры ускоряют вывод. Чтобы видеть, как закрашенные фигуры вычисляются, смотрите segmentImageUnet.m
функция точки входа.
cfg = coder.gpuConfig('mex'); cfg.TargetLang = 'C++'; cfg.DeepLearningConfig = coder.DeepLearningConfig('cudnn'); codegen -config cfg segmentImageUnet -args {ones(size(test_data),'uint16'),coder.Constant([1024 1024])} -report
Code generation successful: To view the report, open('codegen/mex/segmentImageUnet/html/report.mldatx').
Этот segmentImageUnet
функционируйте берет в данных, чтобы протестировать (test_data) и вектор, содержащий размерности размера закрашенной фигуры, чтобы использовать. Возьмите закрашенные фигуры изображения, предскажите пиксели в конкретной закрашенной фигуре, затем объедините все закрашенные фигуры вместе. Из-за размера test_data (12446x7654x7), легче обработать такое большое изображение в закрашенных фигурах.
segmentedImage = segmentImageUnet_mex(test_data,[1024 1024]);
Чтобы извлечь только допустимый фрагмент сегментации, умножьте сегментированное изображение на канал маски тестовых данных.
segmentedImage = uint8(test_data(:,:,7)~=0) .* segmentedImage;
Поскольку выход семантической сегментации является шумным, удалите шум и случайные пиксели при помощи medfilt2
функция.
segmentedImage = medfilt2(segmentedImage,[5,5]);
Следующая строка кода создает вектор из имен классов.
classNames = [ "RoadMarkings","Tree","Building","Vehicle","Person", ... "LifeguardChair","PicnicTable","BlackWoodPanel",... "WhiteWoodPanel","OrangeLandingPad","Buoy","Rocks",... "LowLevelVegetation","Grass_Lawn","Sand_Beach",... "Water_Lake","Water_Pond","Asphalt"];
Наложите метки на сегментированном тесте RGB, отображают и добавляют цветную полосу в изображение сегментации.
cmap = jet(numel(classNames)); B = labeloverlay(imadjust(test_data(:,:,4:6),[0 0.6],[0.1 0.9],0.55),segmentedImage,'Transparency',0.8,'Colormap',cmap); figure imshow(B) 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');
[1] Ronneberger, Олаф, Филипп Фишер и Томас Брокс. "U-Net: Сверточные Сети для Биомедицинской Сегментации Изображений". arXiv предварительно распечатывают arXiv:1505.04597, 2015.
[2] Kemker, R., К. Сальвагхио и К. Кэнэн. "Многоспектральный Набор данных с высоким разрешением для Семантической Сегментации". CoRR, abs/1703.01918, 2017.