Генерация кода для сети сегментации облака точек лидара

В этом примере показано, как сгенерировать код CUDA® MEX для нейронной сети для глубокого обучения для семантической сегментации лидара. Этот пример использует предварительно обученную сеть SqueezeSegV2 [1], которая может сегментировать организованные облака точек лидара, принадлежащие трем классам (фон, автомобиль и грузовик). Для получения информации о методе обучения для сети смотрите, что Семантическая Сегментация Облака точек Лидара Использует Нейронную сеть для глубокого обучения SqueezeSegV2. Сгенерированный код MEX берет облако точек в качестве входа и выполняет предсказание на облаке точек при помощи DAGNetwork объект для сети SqueezeSegV2.

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

Необходимый

Этот пример генерирует MEX CUDA и имеет следующие сторонние требования.

  • CUDA включил NVIDIA® графический процессор и совместимый драйвер.

Дополнительный

Для сборок неMEX, таких как статические, динамические библиотеки или исполняемые файлы, этот пример имеет следующие дополнительные требования.

Проверьте среду графического процессора

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

Сгенерировать код 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) координаты точки включают первые три канала. Четвертый канал содержит измерение интенсивности лидара. Пятый канал содержит информацию об области значений, которая вычисляется как r=x2+y2+z2.

Визуализируйте канал интенсивности изображения.

intensityChannel = I(:,:,4);    

figure;
imshow(intensityChannel);
title('Intensity Image');

Запустите сгенерированный MEX на данных

Вызовите 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');

Запустите сгенерированный код MEX по последовательности облака точек

Считайте последовательность облака точки ввода. Последовательность содержит 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.