В этом примере показано, как обучить сеть PointPillars для обнаружения объектов в облаках точек.
Данные облака точек Lidar могут быть получены различными датчиками лидара, включая датчики Velodyne ®, Pandar и Ouster. Эти датчики захватывают 3-D информацию о положении объектов в сцене, что полезно для многих приложений в автономном управлении автомобилем и дополненной реальности. Однако подготовка устойчивых детекторов с данными облака точек является сложной проблемой из-за разреженности данных по объекту, окклюзий объектов и шума датчика. Было показано, что методы глубокого обучения решают многие из этих проблем, изучая устойчивые представления функций непосредственно из данных облака точек. Одним из методов глубокого обучения для обнаружения 3-D объектов является PointPillars [1]. Используя архитектуру, подобную PointNet, сеть PointPillars извлекает плотные, устойчивые функции из разреженных облаков точек, называемых столбцами, затем использует 2-D нейронную сеть для глубокого обучения с измененной сетью обнаружения объектов SSD, чтобы оценить соединения 3-D ограничивающие рамки, ориентации и предсказания классов.
В этом примере используется набор данных PandaSet [2] из Hesai и Scale. PandaSet содержит 8240 неорганизованные сканы облака точек лидара различных городских сцен, захваченных с помощью Pandar64 датчика. Набор данных обеспечивает 3-D метки для 18 различных классов объектов, включая автомобиль, грузовик и пешехода.
Этот пример использует подмножество PandaSet, которое содержит 2560 предварительно обработанных организованных облаков точек. Каждое облако точек покрывает представления, и задается как матрица 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
D- ownloadPretrainedPointPillarsNet
вспомогательная функция, заданная в конце этого примера. Предварительно обученная модель позволяет вам запустить весь пример, не дожидаясь завершения обучения. Если вы хотите обучить сеть, установите 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}};
Используйте ropFrontViewFromLidarData
c вспомогательная функция, присоединенная к этому примеру в качестве вспомогательного файла, с:
Обрезка вида спереди из входа облака точек полного представления.
Выберите прямоугольные метки, которые находятся внутри информация только для чтения, заданный как 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 box label 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, pi/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);
Можно применить 2-D архитектуру свертки к облакам точек для более быстрой обработки. Для этого сначала преобразуйте облака точек 3-D в 2-D представление. Используйте 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
, присоединенный к этому примеру как вспомогательный файл. Сеть затем обрабатывает псевдоизображение с помощью 2-D сверточной магистрали, за которой следуют различные головки обнаружения SSD, чтобы предсказать 3-D ограничительные коробки вместе с ее классами.
Определите размерности анкерного ящика на основе классов, которые нужно обнаружить. Как правило, эти размеры являются средствами всех значений ограничивающих прямоугольников в набор обучающих данных [1]. Также можно использовать calculateAnchorBoxes
вспомогательная функция, присоединенная к примеру, для получения соответствующих якорных коробок из любого набора обучающих данных. Анкерные рамки заданы в формате {length, width, height, z-center, yaw angle}.
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.
Инициализируйте среднее значение градиентов до []. Это используется оптимизатором Adam.
Инициализируйте среднее значение квадратов градиентов до []. Это используется оптимизатором Adam.
numEpochs = 60; miniBatchSize = 2; learningRate = 0.0002; learnRateDropPeriod = 15; learnRateDropFactor = 0.8; gradientDecayFactor = 0.9; squaredGradientDecayFactor = 0.999; trailingAvg = []; trailingAvgSq = [];
Обучите сеть с помощью CPU или GPU. Для использования GPU требуется Parallel Computing Toolbox™ и графический процессор с поддержкой CUDA ® NVIDIA ®. Для получения дополнительной информации смотрите Поддержку GPU by Release (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
функция. The 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) функция.
Сгенерируйте цели для расчета потерь с помощью достоверных данных, параметров сетки и анкерных коробок.
Вычислите функцию потерь для всех шести предсказаний от сети.
Вычислите общие потери как сумму всех потерь.
Вычислите градиенты обучаемых относительно общей потери.
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] Lang, Alex H., Sourabh Vora, Holger Caesar, Lubing Zhou, Jiong Yang, and Oscar Beijbom. «PointPillars: быстрые энкодеры для обнаружения объектов из облаков точек». В 2019 году IEEE/CVF Conference on Компьютерное Зрение and Pattern Recognition (CVPR), 12689-12697. Лонг Бич, Калифорния, США: IEEE, 2019. https://doi.org/10.1109/CVPR.2019.01298.
[2] Хесаи и шкала. PandaSet. https://scale.com/open-datasets/pandaset.