В этом примере показано, как сгенерировать код CUDA® MEX для нейронной сети для глубокого обучения для семантической сегментации лидара. Этот пример использует предварительно обученную сеть SqueezeSegV2 [1], которая может сегментировать организованные облака точек лидара, принадлежащие трем классам (фон, автомобиль и грузовик). Для получения информации о методе обучения для сети смотрите, что Семантическая Сегментация Облака точек Лидара Использует Нейронную сеть для глубокого обучения SqueezeSegV2. Сгенерированный код MEX берет облако точек в качестве входа и выполняет предсказание на облаке точек при помощи DAGNetwork
объект для сети SqueezeSegV2.
Этот пример генерирует MEX CUDA и имеет следующие сторонние требования.
CUDA включил NVIDIA® графический процессор и совместимый драйвер.
Для сборок неMEX, таких как статические, динамические библиотеки или исполняемые файлы, этот пример имеет следующие дополнительные требования.
Инструментарий NVIDIA.
Библиотека NVIDIA cuDNN.
Библиотека NVIDIA TensorRT.
Переменные окружения для компиляторов и библиотек. Для получения дополнительной информации смотрите Стороннее Оборудование (GPU Coder) и Подготовка Необходимых как условие продуктов (GPU Coder).
Чтобы проверить, что компиляторы и библиотеки для выполнения этого примера настраиваются правильно, используйте coder.checkGpuInstall
(GPU Coder) функция.
envCfg = coder.gpuEnvConfig('host'); envCfg.DeepLibTarget = 'cudnn'; envCfg.DeepCodegen = 1; envCfg.Quiet = 1; coder.checkGpuInstall(envCfg);
SqueezeSegV2 является сверточной нейронной сетью (CNN), спроектированной для семантической сегментации организованных облаков точек лидара. Это - глубокая сеть сегментации декодера энкодера, обученная на наборе данных лидара и импортированная в MATLAB® для вывода. В SqueezeSegV2 подсеть энкодера состоит из слоев свертки, которые вкраплены макс. объединяющими слоями. Это расположение последовательно уменьшает разрешение входного изображения. Подсеть декодера состоит из серии транспонированных слоев свертки, которые последовательно увеличивают разрешение входного изображения. Кроме того, сеть SqueezeSegV2 смягчает удар недостающих данных включением модулей агрегации контекста (БЕГУНКИ). CAM является сверточной подсетью с filterSize значения [7, 7], который агрегировал контекстную информацию от более крупного восприимчивого поля, которое улучшает робастность сети к недостающим данным. Сеть SqueezeSegV2 в этом примере обучена, чтобы сегментировать точки, принадлежащие трем классам (фон, автомобиль и грузовик).
Для получения дополнительной информации об обучении сети семантической сегментации в MATLAB® при помощи MathWorks лоцируйте набор данных, смотрите, что Семантическая Сегментация Облака точек Лидара Использует Нейронную сеть для глубокого обучения PointSeg.
Загрузите предварительно обученную Сеть SqueezeSegV2.
net = getSqueezeSegV2Net();
Downloading pretrained SqueezeSegV2 (2 MB)...
Сеть DAG содержит 238 слоев, включая свертку, ReLU, и слои нормализации партии. и фокальную потерю выходной слой. Чтобы отобразить интерактивную визуализацию архитектуры нейронной сети для глубокого обучения, используйте analyzeNetwork
(Deep Learning Toolbox) функция.
analyzeNetwork(net);
squeezesegv2_predict
Функция точки входаsqueezesegv2_predict.m
функция точки входа, которая присоединена к этому примеру, берет облако точек в качестве входа и выполняет предсказание на нем при помощи нейронной сети для глубокого обучения, сохраненной в SqueezeSegV2Net.mat
файл. Функция загружает сетевой объект от SqueezeSegV2Net.mat
файл в персистентную переменную mynet
и повторные использования персистентная переменная в последующих вызовах предсказания.
type('squeezesegv2_predict.m');
function out = squeezesegv2_predict(in) %#codegen % A persistent object mynet is used to load the DAG network object. At % the first call to this function, the persistent object is constructed and % setup. When the function is called subsequent times, the same object is % reused to call predict on inputs, thus avoiding reconstructing and % reloading the network object. % Copyright 2020 The MathWorks, Inc. persistent mynet; if isempty(mynet) mynet = coder.loadDeepLearningNetwork('SqueezeSegV2Net.mat'); end % pass in input out = predict(mynet,in);
Сгенерировать код MEX CUDA для squeezesegv2_predict.m
функция точки входа, создайте объект настройки графического процессора кода для цели MEX и установите выходной язык на C++. Используйте coder.DeepLearningConfig
(GPU Coder) функция, чтобы создать CuDNN
объект настройки глубокого обучения и присвоение это к DeepLearningConfig
свойство объекта настройки графического процессора кода. Запустите codegen
команда, задавая входной размер [64, 1024, 5]. Это значение соответствует размеру входного слоя сети SqueezeSegV2.
cfg = coder.gpuConfig('mex'); cfg.TargetLang = 'C++'; cfg.DeepLearningConfig = coder.DeepLearningConfig('cudnn'); codegen -config cfg squeezesegv2_predict -args {ones(64,1024,5,'uint8')} -report
Code generation successful: View report
Чтобы сгенерировать Код С++ CUDA, который использует в своих интересах библиотеки NVIDIA TensorRT в коде, задают coder.DeepLearningConfig('tensorrt')
вместо coder.DeepLearningConfig('cudnn')
.
Для получения информации о том, как сгенерировать код MEX для нейронных сетей для глубокого обучения на процессорах Intel®, смотрите Генерацию кода для Нейронных сетей для глубокого обучения с MKL-DNN (MATLAB Coder).
Загрузите организованное облако тестовой точки в MATLAB®. Преобразуйте облако точек в изображение с пятью каналами для предсказания.
ptCloud = pcread('ousterLidarDrivingData.pcd'); I = pointCloudToImage(ptCloud); % Examine converted data whos I
Name Size Bytes Class Attributes I 64x1024x5 327680 uint8
Изображение имеет пять каналов. (x, y, z) координаты точки включают первые три канала. Четвертый канал содержит измерение интенсивности лидара. Пятый канал содержит информацию об области значений, которая вычисляется как .
Визуализируйте канал интенсивности изображения.
intensityChannel = I(:,:,4);
figure;
imshow(intensityChannel);
title('Intensity Image');
Вызовите squeezesegv2_predict_mex
на изображении с пятью каналами.
predict_scores = squeezesegv2_predict_mex(I);
predict_scores
переменная является 3D матрицей, которая имеет три канала, соответствующие мудрой пикселем музыке предсказания к каждому классу. Вычислите канал при помощи максимального счета предсказания, чтобы получить мудрые пикселем метки
[~,argmax] = max(predict_scores,[],3);
Наложите сегментированные метки на канале интенсивности, отображают и отображают сегментированную область. Измените размер сегментированного выхода и добавьте шкалу палитры для лучшей визуализации.
classes = [ "background" "car" "truck" ]; cmap = lidarColorMap(); SegmentedImage = labeloverlay(intensityChannel,argmax,'ColorMap',cmap); SegmentedImage = imresize(SegmentedImage, 'Scale', [2 1], 'method', 'nearest'); figure; imshow(SegmentedImage); N = numel(classes); ticks = 1/(N*2):1/N:1; colorbar('TickLabels',cellstr(classes),'Ticks',ticks,'TickLength',0,'TickLabelInterpreter','none'); colormap(cmap) title('Semantic Segmentation Result');
Считайте последовательность облака точки ввода. Последовательность содержит 10, организовал pointCloud
системы координат собрали использование Изгнания датчик лидара OS1. Входные данные имеют высоту 64 и ширину 1 024, таким образом, каждый объект pointCloud имеет размер 64 1024.
dataFile = 'highwaySceneData.mat'; % Load data in workspace. load(dataFile);
Setup различные цвета, чтобы визуализировать мудрые точкой метки для различных классов интереса.
% Apply the color red to cars. carClassCar = zeros(64, 1024, 3, 'uint8'); carClassCar(:,:,1) = 255*ones(64, 1024, 'uint8'); % Apply the color blue to trucks. truckClassColor = zeros(64, 1024, 3, 'uint8'); truckClassColor(:,:,3) = 255*ones(64, 1024, 'uint8'); % Apply the color gray to background. backgroundClassColor = 153*ones(64, 1024, 3, 'uint8');
Установите pcplayer
функциональные свойства отобразить последовательность и выходные предсказания. Считайте входную систему координат последовательности системой координат и обнаружьте классы интереса с помощью модели.
xlimits = [0 120.0]; ylimits = [-80.7 80.7]; zlimits = [-8.4 27]; player = pcplayer(xlimits, ylimits, zlimits); set(get(player.Axes,'parent'), 'units','normalized','outerposition',[0 0 1 1]); zoom(get(player.Axes,'parent'),2); set(player.Axes,'XColor','none','YColor','none','ZColor','none'); for i = 1 : numel(inputData) ptCloud = inputData{i}; % Convert point cloud to five-channel image for prediction. I = pointCloudToImage(ptCloud); % Call squeezesegv2_predict_mex on the 5-channel image. predict_scores = squeezesegv2_predict_mex(I); % Convert the numeric output values to categorical labels. [~,predictedOutput] = max(predict_scores,[],3); predictedOutput = categorical(predictedOutput, 1:3, classes); % Extract the indices from labels. carIndices = predictedOutput == 'car'; truckIndices = predictedOutput == 'truck'; backgroundIndices = predictedOutput == 'background'; % Extract a point cloud for each class. carPointCloud = select(ptCloud, carIndices, 'OutputSize','full'); truckPointCloud = select(ptCloud, truckIndices, 'OutputSize','full'); backgroundPointCloud = select(ptCloud, backgroundIndices, 'OutputSize','full'); % Fill the colors to different classes. carPointCloud.Color = carClassCar; truckPointCloud.Color = truckClassColor; backgroundPointCloud.Color = backgroundClassColor; % Merge and add all the processed point clouds with class information. coloredCloud = pcmerge(carPointCloud, truckPointCloud, 0.01); coloredCloud = pcmerge(coloredCloud, backgroundPointCloud, 0.01); % View the output. view(player, coloredCloud); drawnow; end
Функции помощника, используемые в этом примере, следуют.
type pointCloudToImage.m
function image = pointCloudToImage(ptcloud) %pointCloudToImage Converts organized 3-D point cloud to 5-channel % 2-D image. image = ptcloud.Location; image(:,:,4) = ptcloud.Intensity; rangeData = iComputeRangeData(image(:,:,1),image(:,:,2),image(:,:,3)); image(:,:,5) = rangeData; % Cast to uint8. image = uint8(image); end %-------------------------------------------------------------------------- function rangeData = iComputeRangeData(xChannel,yChannel,zChannel) rangeData = sqrt(xChannel.*xChannel+yChannel.*yChannel+zChannel.*zChannel); end
type lidarColorMap.m
function cmap = lidarColorMap() cmap = [ 0.00 0.00 0.00 % background 0.98 0.00 0.00 % car 0.00 0.00 0.98 % truck ]; end
[1] Ву, Bichen, Сюаньюй Чжоу, Сычэн Чжао, Сянюй Юэ и Курт Койцер. “SqueezeSegV2: Улучшенная Структура модели и Безнадзорная Доменная Адаптация к Дорожно-объектной Сегментации от Облака точек LiDAR”. Предварительно распечатайте, представленный 22 сентября 2018. http://arxiv.org/abs/1809.08495.