Этот пример демонстрирует генерацию кода для приложения сегментации изображений, которое использует глубокое обучение. Это использует команду codegen
, чтобы сгенерировать MEX-функцию, которая запускает прогноз на Сетевом объекте DAG для U-Net, популярной нейронной сети для глубокого обучения для сегментации изображений.
Для подобного примера, покрывающего сегментацию изображений с помощью U-Net без codegen, смотрите Семантическую Сегментацию Многоспектральных Изображений Используя Глубокое обучение.
CUDA® включил NVIDIA®, графический процессор с вычисляет возможность 3.2 или выше.
NVIDIA инструментарий CUDA и драйвер.
Библиотека NVIDIA cuDNN (v7 и выше).
Deep Learning Toolbox™, чтобы использовать Сетевой объект DAG.
Image Processing Toolbox™ для чтения и отображения изображений.
Система Компьютерного зрения Toolbox™ для функции labeloverlay
используется в этом примере.
Переменные окружения для компиляторов и библиотек. Для получения информации о поддерживаемых версиях компиляторов и библиотек, смотрите Сторонние продукты. Для подготовки переменных окружения смотрите Подготовку Необходимых как условие продуктов.
Интерфейс GPU Coder для Библиотек Глубокого обучения поддерживает пакет. Чтобы установить этот пакет поддержки, используйте Add-On Explorer.
Используйте coder.checkGpuInstall
, функционируют и проверяют, что компиляторы и библиотеки, необходимые для выполнения этого примера, настраиваются правильно.
coder.checkGpuInstall('gpu','codegen','cudnn','quiet');
U-Net [1] является популярным типом сверточной нейронной сети (CNN), разработанной для семантической сегментации изображений. В U-Net начальные серии сверточных слоев вкраплены макс. слоями объединения, последовательно уменьшив разрешение входного изображения. Эти слои сопровождаются серией сверточных слоев, вкрапленных повышающей дискретизацией операторов, последовательно увеличивая разрешение входного изображения. Объединение этих двух серийных путей формирует U-образный график, отсюда имя U-Net. Сеть первоначально обучалась для и использовалась, чтобы запустить прогноз на биомедицинских приложениях сегментации изображений. Однако этот пример демонстрирует способность сети отслеживать изменения в лесном покрове в зависимости от времени. Экологические агентства отслеживают вырубку леса, чтобы оценить и квалифицировать экологическое и экологическое здоровье области.
Основанная на глубоком обучении семантическая сегментация может привести к точному измерению растительного покрова из воздушных фотографий с высоким разрешением. Одна проблема дифференцирует классы с подобными визуальными характеристиками, такими как попытка классифицировать зеленый пиксель как траву, кустарник или дерево. Чтобы увеличить точность классификации, некоторые наборы данных содержат многоспектральные изображения, которые предоставляют дополнительную информацию о каждом пикселе. Например, набор данных национального парка 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.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 patches-wise on patches of size PATCHSIZE. % % Copyright 2018 The MathWorks, Inc. function out = segmentImageUnet(im, patchSize) %#codegen coder.gpu.kernelfun; 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 слоев включая свертку, макс. объединение, конкатенацию глубины и классификацию пикселей выходные слои. Используйте команду net.Layers
, чтобы видеть слои сети.
Загрузите данные о национальном парке 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
Обратите внимание на то, что изображение имеет 7 каналов. Цветовые каналы RGB являются 4-ми, 5-ми, и 6-ми каналами изображений. Первые три канала соответствуют почти инфракрасным полосам и подсвечивают различные компоненты изображения на основе их подписей тепла. Канал 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
, чтобы создать объект настройки глубокого обучения cuDNN
и присвоить ее свойству DeepLearningConfig
объекта настройки графического процессора кода. Запустите команду codegen
, задающую вход размера (test_data) = [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');
Warning: Image is too big to fit on screen; displaying at 6%
[1] Ronneberger, Олаф, Филипп Фишер и Томас Брокс. "U-Net: Сверточные Сети для Биомедицинской Сегментации Изображений". arXiv предварительно распечатывают arXiv:1505.04597, 2015.
[2] Kemker, R., К. Сальвагхио и К. Кэнэн. "Многоспектральный Набор данных с высоким разрешением для Семантической Сегментации". CoRR, abs/1703.01918. 2017.