В этом примере показано, как обучить сеть PointPillars для обнаружения объектов в облаках точек.
Данные об облаке точек лидара могут быть получены множеством датчиков лидара, включая Velodyne®, Pandar и датчики Изгнания. Эти датчики получают 3-D информацию о положении об объектах в сцене, которая полезна для многих приложений в автономном управлении автомобилем и дополненной реальности. Однако учебные устойчивые детекторы с данными об облаке точек сложны из-за разреженности данных на объект, объектные поглощения газов и шум датчика. Методы глубокого обучения, как показывали, обратились ко многим из этих проблем путем изучения устойчивых представлений функции непосредственно от данных об облаке точек. Один метод глубокого обучения для 3-D обнаружения объектов является PointPillars [1]. Используя подобную архитектуру к PointNet, извлечения сети PointPillars плотные, устойчивые функции от разреженных облаков точек вызвали столбы, затем используют 2D нейронную сеть для глубокого обучения с модифицированной сетью обнаружения объектов SSD, чтобы оценить объединенные 3-D ограничительные рамки, ориентации и предсказания класса.
Этот пример использует набор данных PandaSet [2] от Hesai и Scale. PandaSet содержит 8 240 неорганизованных сканов облака точек лидара различных городских сцен, полученных с помощью датчика Pandar64. Набор данных обеспечивает 3-D метки ограничительной рамки для 18 различных классов объектов, включая автомобиль, грузовик и пешехода.
Этот пример использует подмножество PandaSet, который содержит 2 560 предварительно обработанных организованных облаков точек. Каждое облако точек покрытия из представления, и задан как 64 1856 матрица. Облака точек хранятся в формате PCD, и их соответствующие достоверные данные хранится в PandaSetLidarGroundTruth.mat
файл. Файл содержит 3-D информацию об ограничительной рамке для трех классов, которые являются автомобилем, грузовиком и пешеходом. Размер набора данных составляет 5,2 Гбайт.
Загрузите набор данных Pandaset с данного URL с помощью helperDownloadPandasetData
функция помощника, заданная в конце этого примера.
outputFolder = fullfile(tempdir,'Pandaset'); lidarURL = ['https://ssd.mathworks.com/supportfiles/lidar/data/' ... 'Pandaset_LidarData.tar.gz']; helperDownloadPandasetData(outputFolder,lidarURL);
В зависимости от вашего Интернет-соединения может занять время процесс загрузки. Код приостанавливает выполнение MATLAB®, пока процесс загрузки не завершен. В качестве альтернативы можно загрузить набор данных на локальный диск с помощью веб-браузера и извлечь файл. Если вы делаете так, изменяете outputFolder
переменная в коде к местоположению загруженного файла.
Загрузите предварительно обученную сеть с данного URL с помощью helper
DownloadPretrainedPointPillarsNet
функция помощника, заданная в конце этого примера. Предварительно обученная модель позволяет вам запускать целый пример, не имея необходимость ожидать обучения завершиться. Если вы хотите обучить сеть, установите doTraining
переменная к true
.
pretrainedNetURL = ['https://ssd.mathworks.com/supportfiles/lidar/data/' ... 'trainedPointPillarsPandasetNet.zip']; doTraining = false; if ~doTraining helperDownloadPretrainedPointPillarsNet(outputFolder,pretrainedNetURL); end
Создайте datastore файла, чтобы загрузить файлы PCD от заданного пути с помощью pcread
функция.
path = fullfile(outputFolder,'Lidar'); lidarData = fileDatastore(path,'ReadFcn',@(x) pcread(x));
Загрузите 3-D метки ограничительной рамки объектов автомобиля и грузовика.
gtPath = fullfile(outputFolder,'Cuboids','PandaSetLidarGroundTruth.mat'); data = load(gtPath,'lidarGtLabels'); Labels = timetable2table(data.lidarGtLabels); boxLabels = Labels(:,2:3);
Отобразите облако полной точки наблюдения.
figure ptCld = read(lidarData); ax = pcshow(ptCld.Location); set(ax,'XLim',[-50 50],'YLim',[-40 40]); zoom(ax,2.5); axis off;
reset(lidarData);
Данные PandaSet состоят из облаков полной точки наблюдения. В данном примере обрежьте облака полной точки наблюдения к облакам точек вида спереди с помощью стандартных параметров [1]. Эти параметры решают, что размер входа передал сети. Выбирание меньшей области значений облаков точек вдоль x, y, и оси z помогает обнаружить объекты, которые более близки началу координат, и также уменьшает полное учебное время сети.
xMin = 0.0; % Minimum value along X-axis. yMin = -39.68; % Minimum value along Y-axis. zMin = -5.0; % Minimum value along Z-axis. xMax = 69.12; % Maximum value along X-axis. yMax = 39.68; % Maximum value along Y-axis. zMax = 5.0; % Maximum value along Z-axis. xStep = 0.16; % Resolution along X-axis. yStep = 0.16; % Resolution along Y-axis. dsFactor = 2.0; % Downsampling factor. % Calculate the dimensions for the pseudo-image. Xn = round(((xMax - xMin) / xStep)); Yn = round(((yMax - yMin) / yStep)); % Define the pillar extraction parameters. gridParams = {{xMin,yMin,zMin},{xMax,yMax,zMax},{xStep,yStep,dsFactor},{Xn,Yn}};
Используйте cropFrontViewFromLidarData
функция помощника, присоединенная к этому примеру как вспомогательный файл, к:
Обрежьте вид спереди от входного облака полной точки наблюдения.
Выберите метки поля, которые являются в ROI, заданном gridParams
.
[croppedPointCloudObj,processedLabels] = cropFrontViewFromLidarData(...
lidarData,boxLabels,gridParams);
Processing data 100% complete
Отобразите обрезанное облако точек и метки основного блока истинности с помощью helperDisplay3DBoxesOverlaidPointCloud
функция, определяемая помощника в конце примера.
pc = croppedPointCloudObj{1,1}; gtLabelsCar = processedLabels.Car{1}; gtLabelsTruck = processedLabels.Truck{1}; helperDisplay3DBoxesOverlaidPointCloud(pc.Location,gtLabelsCar,... 'green',gtLabelsTruck,'magenta','Cropped Point Cloud');
reset(lidarData);
Разделите набор данных в наборы обучающих данных и наборы тестов. Выберите 70% данных для того, чтобы обучить сеть и остальных для оценки.
rng(1); shuffledIndices = randperm(size(processedLabels,1)); idx = floor(0.7 * length(shuffledIndices)); trainData = croppedPointCloudObj(shuffledIndices(1:idx),:); testData = croppedPointCloudObj(shuffledIndices(idx+1:end),:); trainLabels = processedLabels(shuffledIndices(1:idx),:); testLabels = processedLabels(shuffledIndices(idx+1:end),:);
Так, чтобы можно было легко получить доступ к хранилищам данных, сохраните обучающие данные как файлы PCD при помощи saveptCldToPCD
функция помощника, присоединенная к этому примеру как вспомогательный файл. Можно установить writeFiles
к "false"
если ваши обучающие данные сохраняются в папке и поддерживаются pcread
функция.
writeFiles = true; dataLocation = fullfile(outputFolder,'InputData'); [trainData,trainLabels] = saveptCldToPCD(trainData,trainLabels,... dataLocation,writeFiles);
Processing data 100% complete
Создайте datastore файла с помощью fileDatastore
загружать файлы PCD с помощью pcread
функция.
lds = fileDatastore(dataLocation,'ReadFcn',@(x) pcread(x));
Поле Createa помечает datastore с помощью boxLabelDatastore
для загрузки 3-D меток ограничительной рамки.
bds = boxLabelDatastore(trainLabels);
Используйте combine
функционируйте, чтобы объединить облака точек и 3-D метки ограничительной рамки в один datastore для обучения.
cds = combine(lds,bds);
Этот пример использует увеличение достоверных данных и несколько других методов увеличения глобальных данных, чтобы добавить больше разнообразия в обучающие данные и соответствующие поля. Для получения дополнительной информации о типичных методах увеличения данных, используемых в 3-D рабочих процессах обнаружения объектов с данными о лидаре, смотрите Увеличения Данных для Обнаружения объектов Лидара Используя Глубокое обучение.
Считайте и отобразите облако точек перед увеличением с помощью helperDisplay3DBoxesOverlaidPointCloud
функция помощника, заданная в конце примера..
augData = read(cds); augptCld = augData{1,1}; augLabels = augData{1,2}; augClass = augData{1,3}; labelsCar = augLabels(augClass=='Car',:); labelsTruck = augLabels(augClass=='Truck',:); helperDisplay3DBoxesOverlaidPointCloud(augptCld.Location,labelsCar,'green',... labelsTruck,'magenta','Before Data Augmentation');
reset(cds);
Используйте generateGTDataForAugmentation
функция помощника, присоединенная к этому примеру как вспомогательный файл, чтобы извлечь все ограничительные рамки основной истины из обучающих данных.
gtData = generateGTDataForAugmentation(trainData,trainLabels);
Используйте groundTruthDataAugmentation
функция помощника, присоединенная к этому примеру как вспомогательный файл, чтобы случайным образом добавить постоянное число объектов класса автомобиля и грузовика к каждому облаку точек. Используйте transform
функция, чтобы применить основную истину и пользовательские увеличения данных к обучающим данным.
samplesToAdd = struct('Car',10,'Truck',10); cdsAugmented = transform(cds,@(x) groundTruthDataAugmenation(x,gtData,samplesToAdd));
Кроме того, примените следующие увеличения данных к каждому облаку точек.
Случайное зеркальное отражение вдоль оси X
Случайное масштабирование на 5 процентов
Случайное вращение вдоль оси z от [-pi/4, пи/4]
Случайный перевод [0.2, 0.2, 0.1] метры вдоль x-, y-, и ось z соответственно
cdsAugmented = transform(cdsAugmented,@(x) augmentData(x));
Отобразитесь увеличенное облако точек наряду с основной истиной увеличило поля с помощью helperDisplay3DBoxesOverlaidPointCloud
функция помощника, заданная в конце примера.
augData = read(cdsAugmented); augptCld = augData{1,1}; augLabels = augData{1,2}; augClass = augData{1,3}; labelsCar = augLabels(augClass=='Car',:); labelsTruck = augLabels(augClass=='Truck',:); helperDisplay3DBoxesOverlaidPointCloud(augptCld(:,1:3),labelsCar,'green',... labelsTruck,'magenta','After Data Augmentation');
reset(cdsAugmented);
Можно применить 2D архитектуру свертки к облакам точек для более быстрой обработки. Для этого сначала преобразуйте 3-D облака точек в 2D представление. Используйте transform
функция с createPillars
функция помощника, присоединенная к этому примеру как вспомогательный файл, чтобы создать функции столба и индексы столба от облаков точек. Функция помощника выполняет следующие операции:
Дискретизируйте 3-D облака точек в равномерно расположенные с интервалами сетки в x-y плоскости, чтобы создать набор названных столбов вертикальных столбцов.
Выберите видные столбы (P) на основе числа точек на столб (N).
Вычислите расстояние до среднего арифметического всех точек в столбе.
Вычислите смещение из центра столба.
Используйте x, y, z местоположение, интенсивность, расстояние, и возместите значения, чтобы создать девять размерных (9-D) векторов для каждой точки в столбе.
% Define number of prominent pillars. P = 12000; % Define number of points per pillar. N = 100; cdsTransformed = transform(cdsAugmented,@(x) createPillars(x,gridParams,P,N));
Сеть PointPillars использует упрощенную версию сети PointNet, которая берет функции столба в качестве входа. Для каждой функции столба сеть применяет линейный слой, сопровождаемый слоями ReLU и нормализацией партии. Наконец, сеть применяет макс. объединяющую операцию по каналам, чтобы получить высокоуровневые закодированные функции. Эти закодированные функции рассеиваются назад к исходным местоположениям столба, чтобы создать псевдоизображение с помощью пользовательского слоя helperscatterLayer
, присоединенный к этому примеру как вспомогательный файл. Сеть затем обрабатывает псевдоизображение с 2D сверточной магистралью, сопровождаемой различными головами обнаружения SSD, чтобы предсказать 3-D ограничительные рамки наряду с его классами.
Задайте размерности поля привязки на основе классов, чтобы обнаружить. Как правило, эти размерности являются средними значениями всех значений ограничительной рамки в наборе обучающих данных [1]. В качестве альтернативы можно также использовать calculateAnchorBoxes
функция помощника, присоединенная к примеру, для получения соответствующих полей привязки от любого набора обучающих данных. Поля привязки заданы в формате {длина, ширина, высота, z-центр, угол рыскания}.
anchorBoxes = calculateAnchorsPointPillars(trainLabels); numAnchors = size(anchorBoxes,2); classNames = trainLabels.Properties.VariableNames; numClasses = numel(classNames);
Затем создайте сеть PointPillars с помощью pointpillarNetwork
функция помощника, присоединенная к этому примеру как вспомогательный файл.
lgraph = pointpillarNetwork(numAnchors,gridParams,P,N,numClasses);
Задайте следующие опции обучения.
Определите номер эпох к 60.
Установите мини-пакетный размер на 2. Можно установить мини-пакетный размер на более высокое значение, если у вас есть более доступная память.
Установите скорость обучения на 0,0002.
Установите learnRateDropPeriod
к 15. Этот параметр обозначает номер эпох, после которых можно пропустить скорость обучения на основе формулы .
Установите learnRateDropFactor
к 0,8. Этот параметр обозначает уровень, которым можно пропустить скорость обучения после каждого learnRateDropPeriod
.
Установитесь коэффициент затухания градиента на 0,9.
Установитесь коэффициент затухания градиента в квадрате на 0,999.
Инициализируйте среднее значение градиентов к []. Это используется оптимизатором Адама.
Инициализируйте среднее значение градиентов в квадрате к []. Это используется оптимизатором Адама.
numEpochs = 60; miniBatchSize = 2; learningRate = 0.0002; learnRateDropPeriod = 15; learnRateDropFactor = 0.8; gradientDecayFactor = 0.9; squaredGradientDecayFactor = 0.999; trailingAvg = []; trailingAvgSq = [];
Обучите сеть с помощью центрального процессора или графического процессора. Используя графический процессор требует Parallel Computing Toolbox™, и CUDA® включил NVIDIA® графический процессор. Для получения дополнительной информации смотрите Поддержку графического процессора Релизом (Parallel Computing Toolbox). Чтобы автоматически обнаружить, если вы имеете графический процессор в наличии, установите executionEnvironment
к "auto"
. Если вы не имеете графического процессора или не хотите использовать один для обучения, устанавливать executionEnvironment
к "cpu"
. Чтобы гарантировать использование графического процессора для обучения, установите executionEnvironment
к "gpu"
.
Затем создайте minibatchqueue
(Deep Learning Toolbox), чтобы загрузить данные в пакетах miniBatchSize
во время обучения.
executionEnvironment = "auto"; if canUseParallelPool dispatchInBackground = true; else dispatchInBackground = false; end mbq = minibatchqueue(... cdsTransformed,3,... "MiniBatchSize",miniBatchSize,... "OutputEnvironment",executionEnvironment,... "MiniBatchFcn",@(features,indices,boxes,labels) ... helperCreateBatchData(features,indices,boxes,labels,classNames),... "MiniBatchFormat",["SSCB","SSCB",""],... "DispatchInBackground",true);
Чтобы обучить сеть с пользовательским учебным циклом и включить автоматическое дифференцирование, преобразуйте график слоев в dlnetwork
Объект (Deep Learning Toolbox). Затем создайте плоттер процесса обучения с помощью helperConfigureTrainingProgressPlotter
функция помощника, заданная в конце этого примера.
Наконец, задайте пользовательский учебный цикл. Для каждой итерации:
Считайте облака точек и основные блоки истинности от minibatchqueue
Объект (Deep Learning Toolbox) с помощью next
(Deep Learning Toolbox) функция.
Оцените градиенты модели с помощью dlfeval
(Deep Learning Toolbox) и modelGradients
функция. modelGradients
функция помощника, заданная в конце примера, возвращает градиенты потери относительно настраиваемых параметров в net
, соответствующая мини-пакетная потеря и состояние текущего пакета.
Обновите сетевые параметры с помощью adamupdate
(Deep Learning Toolbox) функция.
Обновите параметры состояния net
.
Обновите график процесса обучения.
if doTraining % Convert layer graph to dlnetwork. net = dlnetwork(lgraph); % Initialize plot. fig = figure; lossPlotter = helperConfigureTrainingProgressPlotter(fig); iteration = 0; % Custom training loop. for epoch = 1:numEpochs % Reset datastore. reset(mbq); while(hasdata(mbq)) iteration = iteration + 1; % Read batch of data. [pillarFeatures,pillarIndices,boxLabels] = next(mbq); % Evaluate the model gradients and loss using dlfeval % and the modelGradients function. [gradients,loss,state] = dlfeval(@modelGradients,net,... pillarFeatures,pillarIndices,boxLabels,gridParams,... anchorBoxes,numClasses,executionEnvironment); % Do not update the network learnable parameters if NaN values % are present in gradients or loss values. if helperCheckForNaN(gradients,loss) continue; end % Update the state parameters of dlnetwork. net.State = state; % Update the network learnable parameters using the Adam % optimizer. [net.Learnables,trailingAvg,trailingAvgSq] = ... adamupdate(net.Learnables,gradients,trailingAvg,... trailingAvgSq,iteration,learningRate,... gradientDecayFactor,squaredGradientDecayFactor); % Update training plot with new points. addpoints(lossPlotter,iteration,double(gather(extractdata(loss)))); title("Training Epoch " + epoch +" of " + numEpochs); drawnow; end % Update the learning rate after every learnRateDropPeriod. if mod(epoch,learnRateDropPeriod) == 0 learningRate = learningRate * learnRateDropFactor; end end else preTrainedMATFile = fullfile(outputFolder,'trainedPointPillarsPandasetNet.mat'); pretrainedNetwork = load(preTrainedMATFile,'net'); net = pretrainedNetwork.net; end
Используйте обучивший сеть, чтобы обнаружить объекты в тестовых данных:
Считайте облако точек из тестовых данных.
Используйте generatePointPillarDetections
функция помощника, присоединенная к этому примеру как вспомогательный файл, чтобы получить предсказанные ограничительные рамки и оценки достоверности.
Отобразите облако точек с ограничительными рамками с помощью helperDisplay3DBoxesOverlaidPointCloud
функция помощника, заданная в конце примера.
ptCloud = testData{45,1}; gtLabels = testLabels(45,:); % The generatePointPillarDetections function detects the % bounding boxes, and scores for a given point cloud. confidenceThreshold = 0.5; overlapThreshold = 0.1; [box,score,labels] = generatePointPillarDetections(net,ptCloud,anchorBoxes,... gridParams,classNames,confidenceThreshold,overlapThreshold,P,N,... executionEnvironment); boxlabelsCar = box(labels'=='Car',:); boxlabelsTruck = box(labels'=='Truck',:); % Display the predictions on the point cloud. helperDisplay3DBoxesOverlaidPointCloud(ptCloud.Location,boxlabelsCar,'green',... boxlabelsTruck,'magenta','Predicted Bounding Boxes');
Computer Vision Toolbox™ обеспечивает функции оценки детектора объектов, чтобы измерить общие метрики, такие как средняя точность (
evaluateDetectionAOS
)
. В данном примере используйте среднюю метрику точности. Средняя точность обеспечивает один номер, который включает способность детектора сделать правильные классификации (точность) и способность детектора найти все соответствующие объекты (отзыв).
Оцените обученный dlnetwork
Объект (Deep Learning Toolbox) net
на тестовых данных путем выполнения этих шагов.
Задайте порог доверия, чтобы использовать только обнаружения с оценками достоверности выше этого значения.
Задайте порог перекрытия, чтобы удалить перекрывающиеся обнаружения.
Используйте generatePointPillarDetections
функция помощника, присоединенная к этому примеру как вспомогательный файл, чтобы получить ограничительные рамки, возражает оценкам достоверности и меткам класса.
Вызовите evaluateDetectionAOS
с detectionResults
и groundTruthData
в качестве аргументов.
numInputs = numel(testData); % Generate rotated rectangles from the cuboid labels. bds = boxLabelDatastore(testLabels); groundTruthData = transform(bds,@(x) createRotRect(x)); % Set the threshold values. nmsPositiveIoUThreshold = 0.5; confidenceThreshold = 0.25; overlapThreshold = 0.1; % Set numSamplesToTest to numInputs to evaluate the model on the entire % test data set. numSamplesToTest = 50; detectionResults = table('Size',[numSamplesToTest 3],... 'VariableTypes',{'cell','cell','cell'},... 'VariableNames',{'Boxes','Scores','Labels'}); for num = 1:numSamplesToTest ptCloud = testData{num,1}; [box,score,labels] = generatePointPillarDetections(net,ptCloud,anchorBoxes,... gridParams,classNames,confidenceThreshold,overlapThreshold,... P,N,executionEnvironment); % Convert the detected boxes to rotated rectangle format. if ~isempty(box) detectionResults.Boxes{num} = box(:,[1,2,4,5,7]); else detectionResults.Boxes{num} = box; end detectionResults.Scores{num} = score; detectionResults.Labels{num} = labels; end metrics = evaluateDetectionAOS(detectionResults,groundTruthData,... nmsPositiveIoUThreshold); disp(metrics(:,1:2))
AOS AP _______ _______ Car 0.86746 0.86746 Truck 0.61463 0.61463
Функциональный modelGradients
берет в качестве входа dlnetwork
Объект (Deep Learning Toolbox) net
и мини-пакет входных данных pillarFeatures
и pillarIndices
с соответствующими основными блоками истинности, полями привязки и параметрами сетки. Функция возвращает градиенты потери относительно настраиваемых параметров в net
, соответствующая мини-пакетная потеря и состояние текущего пакета.
Функция градиентов модели вычисляет общую сумму убытков и градиенты путем выполнения этих операций.
Извлеките предсказания из сети с помощью forward
(Deep Learning Toolbox) функция.
Сгенерируйте цели для расчета потерь при помощи достоверных данных, параметров сетки и полей привязки.
Вычислите функцию потерь для всех шести предсказаний от сети.
Вычислите общую сумму убытков как сумму всех потерь.
Вычислите градиенты learnables относительно общей суммы убытков.
function [gradients,loss,state] = modelGradients(net,pillarFeatures,... pillarIndices,boxLabels,gridParams,anchorBoxes,... numClasses,executionEnvironment) numAnchors = size(anchorBoxes,2); % Extract the predictions from the network. YPredictions = cell(size(net.OutputNames)); [YPredictions{:},state] = forward(net,pillarIndices,pillarFeatures); % Generate target for predictions from the ground truth data. YTargets = generatePointPillarTargets(YPredictions,boxLabels,pillarIndices,... gridParams,anchorBoxes,numClasses); YTargets = cellfun(@ dlarray,YTargets,'UniformOutput',false); if (executionEnvironment=="auto" && canUseGPU) || executionEnvironment=="gpu" YTargets = cellfun(@ gpuArray,YTargets,'UniformOutput',false); end [angLoss,occLoss,locLoss,szLoss,hdLoss,clfLoss] = ... computePointPillarLoss(YPredictions,YTargets,gridParams,... numClasses,numAnchors); % Compute the total loss. loss = angLoss + occLoss + locLoss + szLoss + hdLoss + clfLoss; % Compute the gradients of the learnables with regard to the loss. gradients = dlgradient(loss,net.Learnables); end function [pillarFeatures,pillarIndices,labels] = helperCreateBatchData(... features,indices,groundTruthBoxes,groundTruthClasses,classNames) % Return pillar features and indices combined along the batch dimension % and bounding boxes concatenated along batch dimension in labels. % Concatenate features and indices along batch dimension. pillarFeatures = cat(4,features{:,1}); pillarIndices = cat(4,indices{:,1}); % Get class IDs from the class names. classNames = repmat({categorical(classNames')},size(groundTruthClasses)); [~,classIndices] = cellfun(@(a,b)ismember(a,b),groundTruthClasses,... classNames,'UniformOutput',false); % Append the class indices and create a single array of responses. combinedResponses = cellfun(@(bbox,classid) [bbox,classid],... groundTruthBoxes,classIndices,'UniformOutput',false); len = max(cellfun(@(x)size(x,1),combinedResponses)); paddedBBoxes = cellfun(@(v) padarray(v,[len-size(v,1),0],0,'post'),... combinedResponses,'UniformOutput',false); labels = cat(4,paddedBBoxes{:,1}); end function helperDownloadPandasetData(outputFolder,lidarURL) % Download the data set from the given URL to the output folder. lidarDataTarFile = fullfile(outputFolder,'Pandaset_LidarData.tar.gz'); if ~exist(lidarDataTarFile,'file') mkdir(outputFolder); disp('Downloading PandaSet Lidar driving data (5.2 GB)...'); websave(lidarDataTarFile,lidarURL); untar(lidarDataTarFile,outputFolder); end % Extract the file. if (~exist(fullfile(outputFolder,'Lidar'),'dir'))... &&(~exist(fullfile(outputFolder,'Cuboids'),'dir')) untar(lidarDataTarFile,outputFolder); end end function helperDownloadPretrainedPointPillarsNet(outputFolder,pretrainedNetURL) % Download the pretrained PointPillars network. preTrainedMATFile = fullfile(outputFolder,'trainedPointPillarsPandasetNet.mat'); preTrainedZipFile = fullfile(outputFolder,'trainedPointPillarsPandasetNet.zip'); if ~exist(preTrainedMATFile,'file') if ~exist(preTrainedZipFile,'file') disp('Downloading pretrained detector (8.4 MB)...'); websave(preTrainedZipFile,pretrainedNetURL); end unzip(preTrainedZipFile,outputFolder); end end function lossPlotter = helperConfigureTrainingProgressPlotter(f) % This function configures training progress plots for various losses. figure(f); clf ylabel('Total Loss'); xlabel('Iteration'); lossPlotter = animatedline; end function retValue = helperCheckForNaN(gradients,loss) % The last convolution head 'occupancy|conv2d' is known to contain NaNs % the gradients. This function checks whether gradient values contain % NaNs. Add other convolution head values to the condition if NaNs % are present in the gradients. gradValue = gradients.Value((gradients.Layer == 'occupancy|conv2d') & ... (gradients.Parameter == 'Bias')); if (sum(isnan(extractdata(loss)),'all') > 0) || ... (sum(isnan(extractdata(gradValue{1,1})),'all') > 0) retValue = true; else retValue = false; end end 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
[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.