В этом примере показано, как сгенерировать CUDA® MEX для детектора объектов PointPillars с пользовательскими слоями. Для получения дополнительной информации смотрите Лидар 3-D Обнаружение объектов Используя пример Глубокого обучения PointPillars от Lidar Toolbox™.
CUDA включил NVIDIA® графический процессор и совместимый драйвер.
Для сборок неMEX, таких как статические и динамические библиотеки или исполняемые файлы, этот пример имеет следующие дополнительные требования.
NVIDIA инструментарий CUDA.
Библиотека 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);
Загрузите предварительно обученный детектор PointPillars, обученный в Лидаре 3-D Обнаружение объектов Используя пример Глубокого обучения PointPillars. Чтобы обучить сеть самостоятельно, смотрите Лидар 3-D Обнаружение объектов Используя Глубокое обучение PointPillars.
pretrainedDetector = load('pretrainedPointPillarsDetector.mat','detector'); detector = pretrainedDetector.detector;
Извлеките предварительно обученную сеть.
net = detector.Network;
Поля точек функциональность слоя реализована с помощью functionLayer
. Но, functionLayer
не поддерживает генерацию кода. Используйте helperReplaceFunctionLayer
функция помощника, чтобы заменить functionLayer
в сети с helperScatterLayer
пользовательский слой, который сделал, чтобы генерация кода поддержала и сохранила сеть как pointPillarsCodegenNet.mat
файл.
[net, matFile] = helperReplaceFunctionLayer(net);
pointpillarsDetect
Функция точки входаpointpillarsDetect
функция точки входа берет функции столба и индексы столба, как введено и передает их обучившему сеть для предсказания через pointpillarPredict
функция. pointpillarsDetect
функционируйте загружает сетевой объект из файла MAT в персистентную переменную и снова использует постоянный объект для последующих вызовов предсказания. А именно, функция использует dlnetwork
представление сети, обученной в Лидаре 3-D Обнаружение объектов Используя Глубокое обучение PointPillars.
type('pointpillarsDetect.m')
function [bboxes,scores,labels] = pointpillarsDetect(matFile, pillarFeatures, pillarIndices, gridParams, numOutputs, confidenceThreshold, overlapThreshold, classNames) % The pointpillarsDetect function detects the bounding boxes, scores, and % labels in the point cloud. coder.extrinsic('helpergeneratePointPillarDetections'); % Define Anchor Boxes anchorBoxes = {{1.92, 4.5, 1.69, -1.78, 0}, {1.92, 4.5, 1.69, -1.78, pi/2}, {2.1575, 6.0081, 2.3811, -1.78, 0}, {2.1575, 6.0081, 2.3811, -1.78, pi/2}}; % Predict the output predictions = pointpillarPredict(matFile,pillarFeatures,pillarIndices,numOutputs); % Generate Detections [bboxes,scores,labels] = helpergeneratePointPillarDetections(predictions,gridParams,pillarIndices,... anchorBoxes,confidenceThreshold,overlapThreshold,classNames); end function YPredCell = pointpillarPredict(matFile,pillarFeatures,pillarIndices,numOutputs) % Predict the output of network and extract the following confidence, % x, y, z, l, w, h, yaw and class. % load the deep learning network for prediction persistent net; if isempty(net) net = coder.loadDeepLearningNetwork(matFile); end YPredCell = cell(1,numOutputs); [YPredCell{:}] = predict(net,pillarIndices,pillarFeatures); end
Выполните функцию точки входа на облаке точек.
Задайте параметры сетки и параметры экстракции столба.
Считайте облако точек и генерируйте признаки столба и индексы с помощью createPillars
функция помощника, присоединенная к этому примеру как вспомогательный файл.
Задайте порог доверия как 0,7, чтобы сохранить только обнаружения с оценками достоверности больше, чем это значение.
Задайте порог перекрытия как 0,1, чтобы удалить перекрывающиеся обнаружения.
Используйте функцию точки входа pointpillarsDetect
получить предсказанные ограничительные рамки, оценки достоверности и метки класса.
Отобразите облако точек с ограничительными рамками.
Задайте параметры сетки.
xMin = detector.PointCloudRange(1,1); % Minimum value along X-axis. xMax = detector.PointCloudRange(1,2); % Maximum value along X-axis. yMin = detector.PointCloudRange(1,3); % Minimum value along Y-axis. yMax = detector.PointCloudRange(1,4); % Maximum value along Y-axis. zMin = detector.PointCloudRange(1,5); % Minimum value along Z-axis. zMax = detector.PointCloudRange(1,6); % Maximum value along Z-axis. xStep = detector.VoxelSize(1,1); % Resolution along X-axis. yStep = detector.VoxelSize(1,2); % Resolution along Y-axis. dsFactor = 2.0; % DownSampling factor.
Вычислите размерности для псевдоизображения.
Xn = round(((xMax - xMin) / xStep)); Yn = round(((yMax - yMin) / yStep)); gridParams = {{xMin,yMin,zMin},{xMax,yMax,zMax},{xStep,yStep,dsFactor},{Xn,Yn}};
Задайте параметры экстракции столба.
P = detector.NumPillars; % Define number of prominent pillars. N = detector.NumPointsPerPillar; % Define number of points per pillar.
Вычислите количество сетевых выходных параметров.
networkOutputs = numel(net.OutputNames);
Считайте облако точек из набора данных Pandaset [2] и преобразуйте его в формат M-4.
pc = pcread('pandasetDrivingData.pcd');
ptCloud = cat(2,pc.Location,pc.Intensity);
Создайте функции столба и индексы столба от облаков точек с помощью createPillars
функция помощника, присоединенная к этому примеру как вспомогательный файл.
processedPtCloud = createPillars({ptCloud,'',''}, gridParams,P,N);
Извлеките функции столба и индексы столба.
pillarFeatures = dlarray(single(processedPtCloud{1,1}),'SSCB'); pillarIndices = dlarray(single(processedPtCloud{1,2}),'SSCB');
Задайте имена классов.
classNames = cellstr(detector.ClassNames);
Задайте желаемые пороги.
confidenceThreshold = 0.7; overlapThreshold = 0.1;
Используйте обнаружить метод в сети PointPillars и отобразите результаты.
[bboxes,~,labels] = pointpillarsDetect(matFile, pillarFeatures, pillarIndices,... gridParams, networkOutputs, confidenceThreshold, overlapThreshold, classNames); bboxesCar = bboxes(labels == 'Car',:); bboxesTruck = bboxes(labels == 'Truck',:);
Отобразите обнаружения на облаке точек.
helperDisplay3DBoxesOverlaidPointCloud(pc.Location, bboxesCar, 'green',... bboxesTruck, 'magenta', 'Predicted bounding boxes');
Сгенерировать код CUDA® для pointpillarsDetect
функция точки входа, создайте объект настройки графического процессора кода для цели MEX и установите выходной язык на C++. Используйте coder.DeepLearningConfig
(GPU Coder) функция, чтобы создать cuDNN настройку глубокого обучения возражает и присвоить ее DeepLearningConfig
свойство объекта настройки графического процессора кода.
cfg = coder.gpuConfig('mex'); cfg.TargetLang = 'C++'; cfg.DeepLearningConfig = coder.DeepLearningConfig(TargetLibrary='cudnn'); args = {coder.Constant(matFile), pillarFeatures, pillarIndices, gridParams,... coder.Constant(networkOutputs), confidenceThreshold, overlapThreshold, classNames}; codegen -config cfg pointpillarsDetect -args args -report
Code generation successful: View report
Вызовите сгенерированный MEX CUDA с теми же функциями столба и индексами как прежде. Отобразите результаты.
[bboxes, ~, labels] = pointpillarsDetect_mex(matFile, pillarFeatures, ... pillarIndices, gridParams, networkOutputs, confidenceThreshold,... overlapThreshold, classNames); bboxesCar = bboxes(labels == 'Car',:); bboxesTruck = bboxes(labels == 'Truck',:); helperDisplay3DBoxesOverlaidPointCloud(pc.Location, bboxesCar, 'green',... bboxesTruck, 'magenta', 'Predicted bounding boxes');
function helperDisplay3DBoxesOverlaidPointCloud(ptCld, labelsCar, carColor,... labelsTruck, truckColor, titleForFigure) % Display the point cloud with different colored bounding boxes for different % classes figure; ax = pcshow(ptCld); showShape('cuboid', labelsCar, 'Parent', ax, 'Opacity', 0.1, 'Color',... carColor, 'LineWidth', 0.5); hold on; showShape('cuboid', labelsTruck, 'Parent', ax, 'Opacity', 0.1, 'Color',... truckColor, 'LineWidth', 0.5); title(titleForFigure); zoom(ax,1.5); end function [net, matFile] = helperReplaceFunctionLayer(net) % Replace the scatter functionLayer present in the pretrained Pointpillars % network with custom layer having code generation support. matFile = './pointPillarsCodegenNet.mat'; lgraph = net.layerGraph; id = find(... arrayfun( @(x)isa(x,'nnet.cnn.layer.FunctionLayer'), ... net.Layers)); fcnLayer = net.Layers(id); customLayer = helperScatterLayer(2,"pillars|scatter_nd",[432 496]); lgraph = replaceLayer(lgraph,fcnLayer.Name,customLayer); net = dlnetwork(lgraph); save(matFile,'net'); end
[1] Ленг, Алекс Х., Sourabh Vora, Хольгер Цезарь, Лубин Чжоу, Цзюн Ян и Оскар Бейджбом. "PointPillars: Быстрые Энкодеры для Обнаружения объектов От Облаков точек". На 2019 Конференциях IEEE/CVF по Компьютерному зрению и Распознаванию образов (CVPR), 12689-12697. Лонг-Бич, CA, США: IEEE, 2019. https://doi.org/10.1109/CVPR.2019.01298.
[2] Hesai и Scale. PandaSet. https://scale.com/open-datasets/pandaset.