PointRCNN
PointRCNN是CVPR2019中3D目标检测的文章。3D目标检测是一个计算机视觉中比较新的任务,其他的文献综述可以参考我的另外一篇博客3D Object Detection 3D目标检测综述
该文章使用two-stage方式,利用PointNet++作为主干网络,先完成segmentation任务,判断每个三维点的label。对分为前景的每个点,使用feature生成框。然后对框进行roi crop,进行框的优化。该论文网络复杂,代码量巨大,真是佩服论文作者的代码功底,自愧不如。本文着重对网络结构的理解。代码来源是文章作者给出的代码,用的是pytorch,github传送门
接下来,我将先对运算过程进行可视化,然后再列出部分本篇论文我注意到的点。
PointRCNN网络结构
由于PointRCNN使用PointNet++作为主干网络,所以对PointNet++的具体网络结构不是很了解的同学可以参考我的另一篇博客PointNet++具体实现详解,其中也是着重对网络结构的理解。先看PointRCNN的网络结构的可视化:
- 图的解释
- 虚线大框:一个虚线框代表一个完整的子网络,对应代码中的一个class
- 红色小框:每个子网络的名称
- 蓝色小块:大多数一个蓝色小块代表一个tensor,蓝色小框的第一行为tensor的名称,第二行为tensor的尺寸。少量未标注尺寸的为一个子网络
- 橘色小块:一个子网络的输出
- 箭头:一种操作,没有标的大部分为resize或者permutation操作,也有concatenate操作
- RPN
- RPN.BackBone
- 输入:点云(batch,number of points,number of channels)
- 输出:xyz,每个点的 feature,每个点的分类结果 rpn_cls,每个点对框的回归结果 rpn_reg
- 三维点云xyz经过主干网络得到point-wise的特征feature
- feature经过分类头和回归头得到point-wise的分类结果rpn_cls和回归结果rpn_reg,分类头和回归头由Conv1d组成
- cls_rpn经过sigmoid变换到[0, 1]之间,表示该点为车的score,score大于阈值thres的点被认为是属于车的点,从而构造seg_mask,用于构造RCNN的输入
- 通过每个点的三维信息xyz计算点距离原点的深度信息depth,用于RCNN的输入
- RPN.ProposalLayer
- 输入:rpn_reg,rpn_cls
- 输出:roi
- 将rpn_reg分解,并与三维点xyz和anchor计算proposals
- 使用Distance Proposal 减小proposal的数量。Distance Proposal:
- 用雷达点的y坐标以40为界分为两块区域,[0, 40] 和 [40, 80]
- 按照rpn_cls(代表是box的置信度)进行排序,[0, 40]的区域选取6300个框,[40, 80]选取2700个框
- 将框转为BEV,然后使用nms,两个区域分别选取前358和154个框(nms后如果框的数量少于这两个值就全部选取,用0补足到512个框)
- 输出每个batch的512个框roi
- RPN.BackBone
- RCNN
- RCNN.ProposalTargetLayer
- 输入:roi,gt_boxes,xyz,seg_mask,depth,feature
- 输出:采样过后的roi,roi_iou,对应的roi_gt_boxes,roi中包括的pts_sample和feature_sample,batch_cls_mask,reg_valid_mask
- 使用RoISample再次采样RoI,RoISample:
- 计算所有roi与真值之间的IoU,并按照IoU分为fg(前景),easy bg(简单背景)和 hard bg(困难背景),中sample数64个,fg最多32个,剩余的由bg补充,其中hard bg占比0.8。
- 然后对roi做augmentation,更新roi和对应的IoU
- 将xyz,seg_mask,depth和feature进行concatenate,得到pts_feature
- 对pts_feature进行RoIPooling,每个RoI中取512个点,得到pooled_feature,并得到不包含点的RoI的flag
- 将pooled_feature中的坐标和feature分离,然后做roi的augmentation,并将坐标系转到roi中心,更新roi中点的三维坐标和gt_box的坐标
- 计算batch_cls_mask,reg_valid_mask用于计算loss,batch_cls_mask统计roi不为hard bg且其中包含点的mask,作为cls_label在计算loss中使用;reg_valid_mask统计roi属于fg的mask
- pts_sample和feature_sample重组,提取直接由三维点云获得的信息xyz_feature(包括xyz,seg_mask和depth),然后使用xyz_up_layer进行特征提取,与rpn得到的feature进行concatenate,然后使用merged_down_layer进行merge,得到merged_feature
- 将merged_feature送入3个PointNet++中提出的SA层中,得到高级特征
- 然后使用分类头和回归头进行预测
- RCNN.ProposalTargetLayer
训练过程
PointRCNN是two-stage结构的网络,所以训练过程也是先训练RPN,再训练RCNN。
- RPN
- label:在通过dataloader构建训练数据的同时,构建label
- cls_label:将gt_box内的点置1,gt_box之外extended_gt_box之内的点置-1(表示忽略)
- reg_label:计算gt_box之内的点的reg量
- loss:SigmoidFocalLoss + Full-bin Loss(CrossEntropyLoss + SmoothL1Loss)
- label:在通过dataloader构建训练数据的同时,构建label
- RCNN
- label:
- cls_label:在RCNN.ProposalTargetLayer中的batch_cls_mask为label
- reg_label:使用RCNN.ProposalTargetLayer中的roi_gt_boxes计算
- loss:SigmoidFocalLoss + Full-bin Loss(CrossEntropyLoss + SmoothL1Loss)
- label:
思考
- 文章使用two-stage的方法,在proposal的过程中,每个个三维点都回归一个proposal,使得理论上所有的box都能够被找到
- 文章使用bin based回归方式,而且是在所有回归的地方都使用bin based的方式,提高了网络的收敛速度和准确率。
- 文章使用PointNet++作为主干框架,使得不需要在体素化阶段损失信息
- 其他3D物体检测的文章可以参考我的另一篇博客另外一篇博客3D Object Detection 3D目标检测综述