对PointRCNN第一阶段的前景点网络分割细节和精度比较好奇,同时好奇PointRCNN在第一阶段只是对每个点预测前景背景还是预测了具体的物体类别?(是后者)
写了个简单的精度测试函数。
一、流程梳理:
Label:
PointRCNN第一阶段里点的原始cls label有5个 :
-1:ignore 0:背景点 1:Car 2:Pedestrian 3:Cyclist
在get_cls_layer_loss函数中,把ignore类合并到了背景点类中,所以最终用于train和eval的是4类,其对应的onehot为:
000:背景 001:Car 010:Pedestrian 001:Cyclist
one_hot_targets.scatter_(-1, (point_cls_labels * (point_cls_labels >= 0).long()).unsqueeze(dim=-1).long(), 1.0)
Predict:
PointRCNN第一阶段的point_head对每个point有三个输出,可以视为当前点属于Car、Pedestrian、Cyclist的概率,若三个值都很小(000)则此点为背景。PointRCNN选取了预测概率最大的前K个点,这些点由于预测概率都很大所以都是前景点。因此,理论上PointRCNN的前景点分割精度应该随着K的增加而下降,下面用简单程序验证下:
二、PointRCNN前景点分割精度测试代码:
在PointHeadBox的forward里添加eval_cls
def eval_cls(self, batch_dict):
writer = SummaryWriter("cls_eval_logs")
# 评估二分类精确率
targets_dict = self.assign_targets(batch_dict)
point_cls_labels = targets_dict['point_cls_labels']
# 分析predict中的类别数量
choose_num = 10 # 取前k个cls得分最高的点算精度
while choose_num < 200:
predict_cls = torch.sigmoid(batch_dict['batch_cls_preds']) # 预测结果
# 网络对每个point有三个输出,取出最大的输出值和其对应的索引 0:car 1:Pedestrian 2:Cyclist
predict_cls_score, predict_cls_max_index = predict_cls.max(dim=-1)
# 所有点的预测结果中取前choose_num个得分最高的参与精度计算
predict_cls_max_score, predict_cls_index = torch.topk(predict_cls_score, choose_num, dim=-1)
# 得分最高的choose_num个点的label
point_cls_labels_max_index = point_cls_labels[predict_cls_index]
# 得分最高的choose_num个点的预测类别 label里0:背景点 1:car 2:Pedestrian 3:Cyclist 所以+1
predict_cls_max_index_index = predict_cls_max_index[predict_cls_index] + 1
out = torch.where(point_cls_labels_max_index == predict_cls_max_index_index)
out = len(out[0])
socre = out / choose_num
choose_num = choose_num + 10
writer.add_scalar("eval cls", socre, choose_num)
writer.close()
三、结果分析
果不其然,精度随着选中的K增大而下降,不同帧点云的曲线差距可能较大。
第一阶段的网络就能区分出Car、Pedestrian、Cyclist