主要内容

列车分类网络以在3-D点云中对象进行分类

此示例删除了[1其中,其中将云数据预处理地被预处成了一种体内编码,然后用简单的3-D卷积神经网络架构直接使用以执行对象分类。在更新的方法(如[2[点云数据的编码可以更复杂,可以学习训练端到端的编码以及执行分类/对象检测/分段任务的网络。然而,从不规则无序点移动到可以馈送到脉冲集的网格结构的一般模式在所有这些估算中保持相似。

导入和分析数据

在此示例中,我们与悉尼城市对象数据集一起使用。在此示例中,我们将折叠1-3从数据中作为训练集和折叠4作为验证集。

datapath = downloadsydneybanobjects(tempdir);dstrain = loadsydneyurnanobjectsdata(DataPath,[1 2 3]);dsval = loadsydneyurnanobjectsdata(DataPath,4);

分析培训集以了解数据中存在的标签和标签的整体分布。

dslabels =变换(dstrain,@(数据)数据{2});标签= READALL(DSLABELS);图直方图(标签)

从直方图中,很明显,培训数据中存在类别不平衡问题,其中某些对象类行人比频繁的班级更常见ut

数据增强管道

为避免对分类器的过度装备并增加稳健性,在培训网络时,某些量的随机数据增强通常是一个好主意。功能ronceaffine2d.并且PCTransform使得在点云数据上易于定义随机仿射变换。我们还在每个点云中添加了一些随机的每点抖动。功能AugmentPointCloudData.包含在下面的支持功能部分。金宝app

dstrain =变换(dstrain,@ augmentpointclouddata);

验证点云数据的增强看起来合理。

dataout = preview(dstrain);图pcshow(dataout {1});标题(DataOut {2});

接下来,如前一个示例中所讨论的,将简单的Voxelization变换添加到每个输入点云,将输入点云转换为可与卷积神经网络一起使用的伪图像。使用简单的占用网格。

dstrain =变换(dstrain,@ formoccupancygrid);DSVAL =变换(DSVAL,@ FormoCcupancyGrid);

检查我们将进入网络的最终体积化体积的样本,以验证Voxelixation正在正常工作。

数据=预览(DStrain);图P =补丁(Isosurface(数据{1},0.5));p.facecolor ='红色的';p.edgecolor ='没有任何';DASPED([1 1 1])视图(45,45)套光;灯光ph标题(数据{2});

定义网络架构

在此示例中,我们使用如[1]中所述的简单3-D分类架构。

图层= [image3dinputlayer([32 32 32],'名称''InputLayer''正常化''没有任何'),......卷积3dlayer(5,32,'走吧'2,'名称''conv1'),......Liquidyrel3(0.1,'名称''leakyrelu1'),......卷积3dlayer(3,32,'走吧',1,'名称''conv2'),......Liquidyrel3(0.1,'名称''漏狼土'),......maxpooling3dlayer(2,'走吧'2,'名称''maxpool'),......全康统计(128,'名称''fc1'),......Rululayer('名称''relu'),......DropoutLayer(0.5,'名称''dropout1'),......全协调层(14,'名称''fc2'),......softmaxlayer('名称''softmax'),......ClassificationLayer('名称''frossentropyls')];Voxnet = LayerGraph(层);图绘图(Voxnet);

设置培训选项

使用随机梯度下降,势头具有分段调整的动量。此示例在Titanx GPU上运行,对于具有较少内存的GPU,可能需要减少批量大小。虽然3D Councnets具有概念简单的优势,但它们在训练时间内具有大量内存级别的缺点。

minibatchsize = 32;dslength = length(dstrain.underwingdatastore.files);iterationsperepoch =地板(dslength / minibatchsize);Dropperiod =地板(8000 / iterationsPerepoch);选项=培训选项('sgdm''italllearnrate',0.01,'minibatchsize',小匹马,......'shownrateschedule''分段'......'学习ropperiod',Dropperiod,......'vightationdata',dsval,'maxepochs'60,......'disparctinbackground',错误的,......'洗牌''绝不');

火车网络

VoxNet = Trainnetwork(Dstrain,Voxnet,选项);
单个GPU培训。| ====================================================================================================================== ||时代|迭代|经过时间的时间迷你批量|验证|迷你批量|验证| Base Learning | | | | (hh:mm:ss) | Accuracy | Accuracy | Loss | Loss | Rate | |======================================================================================================================| | 1 | 1 | 00:00:03 | 9.38% | 20.65% | 2.6408 | 2.6300 | 0.0100 | | 4 | 50 | 00:00:25 | 31.25% | 29.03% | 2.2892 | 2.2954 | 0.0100 | | 8 | 100 | 00:00:45 | 37.50% | 37.42% | 1.9256 | 2.0372 | 0.0100 | | 12 | 150 | 00:01:05 | 53.12% | 47.10% | 1.6398 | 1.7396 | 0.0100 | | 16 | 200 | 00:01:24 | 43.75% | 55.48% | 1.9551 | 1.5172 | 0.0100 | | 20 | 250 | 00:01:44 | 40.62% | 61.29% | 1.7413 | 1.3598 | 0.0100 | | 24 | 300 | 00:02:04 | 50.00% | 60.00% | 1.4652 | 1.2962 | 0.0100 | | 27 | 350 | 00:02:23 | 43.75% | 64.52% | 1.5017 | 1.1762 | 0.0100 | | 31 | 400 | 00:02:42 | 53.12% | 69.03% | 1.2488 | 1.1132 | 0.0100 | | 35 | 450 | 00:03:02 | 50.00% | 69.03% | 1.3160 | 1.0272 | 0.0100 | | 39 | 500 | 00:03:23 | 59.38% | 69.03% | 1.1753 | 1.1366 | 0.0100 | | 43 | 550 | 00:03:44 | 56.25% | 65.81% | 1.1546 | 1.1086 | 0.0100 | | 47 | 600 | 00:04:03 | 68.75% | 65.81% | 0.9808 | 1.0251 | 0.0100 | | 50 | 650 | 00:04:22 | 65.62% | 69.68% | 1.1245 | 1.0136 | 0.0100 | | 54 | 700 | 00:04:42 | 62.50% | 65.16% | 1.2860 | 1.0934 | 0.0100 | | 58 | 750 | 00:05:01 | 59.38% | 68.39% | 1.2466 | 1.0271 | 0.0100 | | 60 | 780 | 00:05:13 | 56.25% | 64.52% | 1.1676 | 1.0798 | 0.0100 | |======================================================================================================================|

评估网络

遵循[1此示例仅形成从悉尼城市对象的培训和验证。使用验证评估训练网络的性能,因为它不用于培训网络。

vallabelset =变换(DSVAL,@(数据)数据{2});vallabels = Readall(Vallabelset);outputlabels =分类(VoxNet,DSVal);精度= nnz(outputlabels == vallabels)/ numel(outputlabels);DISP(准确性)
0.6452

查看混淆矩阵以研究各种标签类别的准确性

图拼图(Vallabels,OutputLabels)

培训集中注意的标签不平衡是分类准确性的问题。混乱图表说明了行人,最常见的班级的更高精度和召回,而不是常见的常见类别。由于该示例的目的是通过点云数据来扩张基本分类网络训练方法,可以采取可以采取的下一步骤来提高分类性能,例如重新采样训练集或实现更好的标签余额或使用损耗函数更强大label imbalance (e.g. weighted cross-entropy) will not be explored.

参考

1)VoxNet:用于实时对象识别的3D卷积神经网络,Daniel Maturana,Sebastian Scherer,2015年IEEE / RSJ智能机器人和系统国际会议(IROS)

2)PointPillars:来自点云的对象检测的快速编码器,Alex H. Lang,Sourabh Vora,等,CVPR 2019

3)悉尼城市对象数据集,Alastair Quadros,詹姆斯·安德伍德,Bertrand Doularard,悉尼城市对象

金宝app支持功能

功能datasetpath = downloadsydneyurbanobjects(dataloc)如果nargin == 0 dataloc = pwd();结尾dataloc = string(dataloc);URL =.“http://www.acfr.usyd.edu.au/papers/data/”;名称=“悉尼城市 - 对象-TATASET.TAR.GZ”;如果〜存在(fullfile(dataLoc,'悉尼城市 - 物体 - 数据集'),'dir')disp('下载悉尼城市对象数据集......');Untar(FullFile(URL,Name),DataLoc);结尾datasetpath = dataloc.append('悉尼城市 - 物体 - 数据集');结尾功能DS = loadsydneyurnanobjectsdata(DataPath,Folds)%loadydneybanobjectsdata数据存储与点云和悉尼城市对象数据集的%相关分类标签。%ds = loadydneyurnanobjectsdata(datapath)构造一个数据存储%代表悉尼城市的点云和相关类别%对象数据集。输入,datapath是一个字符串或char数组%代表悉尼城市对象的根目录的路径%dataSet。%ds = loadsydneyurnanobjectsdata(___,folds)可选择允许您希望包含在内的所需折叠的%规范%输出DS。例如,[1 2 4]指定您想要的第一个,%秒和数据集的第四个折叠。默认值:[1 2 3 4]。如果nargin <2折= 1:4;结尾DataPath = String(DataPath);path = fullfile(datapath,'物体',filesep);百分比现在包括数据存储区中的所有折叠foldnames {1} = ImportData(FullFile(DataPath,'折叠''fold0.txt'));foldnames {2} = ImportData(FullFile(DataPath,'折叠''fold1.txt'));foldnames {3} = ImportData(FullFile(DataPath,'折叠''fold2.txt'));foldnames {4} = ImportData(FullFile(DataPath,'折叠''fold3.txt'));名称= foldnames(折叠);名称= VertCAT(名称{:});fullfilenames =附加(路径,名称);ds = filedataStore(fullfilenames,'readfcn',@ extractTrainingData,'fileextensions''.bin');%洗牌ds.files = ds.files(randperm(长度(ds.files)));结尾功能dataout = zhothtrationdata(fname)[pointdata,强度] = readbin(fname);[〜,name] = fileparts(fname);name = string(name);name = extractBefore(名称,'。');名称=替换(名称,'_''');labelnames = [“4WD”“建造”“公共汽车”“车”“行人”“支柱”......“极”“红绿灯”“交通标志”“树”“卡车”“树干”“ute”“van”];标签=分类(名称,标签名称);dataout = {pointcloud(pointdata,'强度',强度),标签};结尾功能[Pointdata,强度] = reavbin(fname)悉尼城市对象二进制的%储存读点和强度数据%文件。%name = ['t','强度','id',...%'x','y','z',...%'方句','范围','pid']%格式= ['int64','uint8','uint8',...%'float32','float32','float32',...%'float32','float32','int32']fid = fopen(fname,'r');c = oncleanup(@()fclose(fid));FSEEK(FID,10,-1);%从头开始移动到第一个X点位置10个字节x = fread(fid,inf,'单身的',30);FSEEK(FID,14,-1);y = fread(fid,inf,'单身的',30);FSEEK(FID,18,-1);z = fread(fid,inf,'单身的',30);FSEEK(FID,8,-1);强度=欺诈(FID,INF,'uint8',33);PointData = [x,y,z];结尾功能dataout = formoccupancygrid(data)grid = pcbin(数据{1},[32 32 32]);占用=零(大小(栅格),'单身的');为了II = 1:NUMER(网格)占用格(II)=〜isempty(网格{II});结尾标签=数据{2};dataout = {itepancyGrid,label};结尾功能dataout = augmentpointclouddata(data)ptcloud = data {1};标签=数据{2};%Apply关于Z轴的随机旋转。tform = ronsomaffine3d('回转',@()交易([0 0 1],360 * rand),'规模',[0.98,1.02],'Xreflection',真的,'yreflection',真的);关于Z轴的%随机旋转ptcloud = pctransform(ptcloud,tform);%将抖动应用于点云中的每个点Quantofjitter = 0.01;numpoints = size(ptcloud.location,1);d = zeros(大小(ptcloud.location),'像',ptcloud.location);d(:,1)= diff(ptcloud.xlimits)* rand(nuitpoints,1);d(:,2)= diff(ptcloud.ylimits)* rand(nuitpoints,1);d(:,3)= diff(ptcloud.zlimits)* rand(nuitpoints,1);d = QuanteOfjitter。* D;ptcloud = pctransform(ptcloud,d);dataout = {ptcloud,label};结尾