下载
中文
注册

迁移修改

一键迁移

修改“tools/train.py”脚本。

在import torch部分后添加一键迁移逻辑:

import torch_npu
from torch_npu.contrib import transfer_to_npu

修改RotateIOU算子

RotateIOU在PointPillars模型推理阶段使用到,由于NPU不支持RotateIOU算子,将该算子使用CPU上运算会非常慢,因此使用多进程程序多核跑加速推理。

修改“pcdet/datasets/kitti/kitti_object_eval_python/eval.py”脚本。

修改前:

def calculate_iou_partly(gt_annos, dt_annos, metric, num_parts=50):    
for num_part in split_parts:
        gt_annos_part = gt_annos[example_idx:example_idx + num_part]
        dt_annos_part = dt_annos[example_idx:example_idx + num_part]
        if metric == 0:
            gt_boxes = np.concatenate([a["bbox"] for a in gt_annos_part], 0)
            dt_boxes = np.concatenate([a["bbox"] for a in dt_annos_part], 0)
            overlap_part = image_box_overlap(gt_boxes, dt_boxes)
        elif metric == 1:
            loc = np.concatenate(
                [a["location"][:, [0, 2]] for a in gt_annos_part], 0)
            dims = np.concatenate(
                [a["dimensions"][:, [0, 2]] for a in gt_annos_part], 0)
            rots = np.concatenate([a["rotation_y"] for a in gt_annos_part], 0)
            gt_boxes = np.concatenate(
                [loc, dims, rots[..., np.newaxis]], axis=1)
            loc = np.concatenate(
                [a["location"][:, [0, 2]] for a in dt_annos_part], 0)
            dims = np.concatenate(
                [a["dimensions"][:, [0, 2]] for a in dt_annos_part], 0)
            rots = np.concatenate([a["rotation_y"] for a in dt_annos_part], 0)
            dt_boxes = np.concatenate(
                [loc, dims, rots[..., np.newaxis]], axis=1)
            overlap_part = bev_box_overlap(gt_boxes, dt_boxes).astype(
                np.float64)
        elif metric == 2:
            loc = np.concatenate([a["location"] for a in gt_annos_part], 0)
            dims = np.concatenate([a["dimensions"] for a in gt_annos_part], 0)
            rots = np.concatenate([a["rotation_y"] for a in gt_annos_part], 0)
            gt_boxes = np.concatenate(
                [loc, dims, rots[..., np.newaxis]], axis=1)
            loc = np.concatenate([a["location"] for a in dt_annos_part], 0)
            dims = np.concatenate([a["dimensions"] for a in dt_annos_part], 0)
            rots = np.concatenate([a["rotation_y"] for a in dt_annos_part], 0)
            dt_boxes = np.concatenate(
                [loc, dims, rots[..., np.newaxis]], axis=1)
            overlap_part = d3_box_overlap(gt_boxes, dt_boxes).astype(
                np.float64)
        else:
            raise ValueError("unknown metric")
        parted_overlaps.append(overlap_part)
        example_idx += num_part
overlaps = []
        example_idx = 0
        for j, num_part in enumerate(split_parts):
            parted_overlaps[i] = overlap_part

修改后:

def calculate_iou_partly_single(gt_annos, dt_annos, example_idx, split_parts, i, parted_overlaps, metric):
    gt_annos_part = gt_annos[example_idx: example_idx + split_parts[i]]
    dt_annos_part = dt_annos[example_idx: example_idx + split_parts[i]]
    if metric == 0:
        gt_boxes = np.concatenate([a["bbox"] for a in gt_annos_part], 0)
        dt_boxes = np.concatenate([a["bbox"] for a in dt_annos_part], 0)
        overlap_part = image_box_overlap(gt_boxes, dt_boxes)
    elif metric == 1:
        loc = np.concatenate(
            [a["location"][:, [0, 2]] for a in gt_annos_part], 0)
        dims = np.concatenate(
            [a["dimensions"][:, [0, 2]] for a in gt_annos_part], 0)
        rots = np.concatenate([a["rotation_y"] for a in gt_annos_part], 0)
        gt_boxes = np.concatenate(
            [loc, dims, rots[..., np.newaxis]], axis=1)
        loc = np.concatenate(
            [a["location"][:, [0, 2]] for a in dt_annos_part], 0)
        dims = np.concatenate(
            [a["dimensions"][:, [0, 2]] for a in dt_annos_part], 0)
        rots = np.concatenate([a["rotation_y"] for a in dt_annos_part], 0)
        dt_boxes = np.concatenate(
            [loc, dims, rots[..., np.newaxis]], axis=1)
        overlap_part = bev_box_overlap(gt_boxes, dt_boxes).astype(
            np.float64)
    elif metric == 2:
        loc = np.concatenate([a["location"] for a in gt_annos_part], 0)
        dims = np.concatenate([a["dimensions"] for a in gt_annos_part], 0)
        rots = np.concatenate([a["rotation_y"] for a in gt_annos_part], 0)
        gt_boxes = np.concatenate([loc, dims, rots[..., np.newaxis]], axis=1)
        loc = np.concatenate([a["location"] for a in dt_annos_part], 0)
        dims = np.concatenate([a["dimensions"] for a in dt_annos_part], 0)
        rots = np.concatenate([a["rotation_y"] for a in dt_annos_part], 0)
        dt_boxes = np.concatenate(
            [loc, dims, rots[..., np.newaxis]], axis=1)
        overlap_part = d3_box_overlap(gt_boxes, dt_boxes).astype(
            np.float64)
    else:
        raise ValueError("unknown metric")

    parted_overlaps[i] = overlap_part

“pcdet/datasets/kitti/kitti_object_eval_python/ rotate_iou.py”脚本中新增rotate_iou_cpu_eval函数:

def rotate_iou_cpu_eval(dev_boxes, dev_query_boxes, criterion=-1):
    num_boxes = dev_boxes.shape[0]
    num_qboxes = dev_query_boxes.shape[0]
    dev_iou = np.zeros((num_boxes, num_qboxes))

    for box_i in range(num_boxes):
        for qbox_i in range(num_qboxes):
            dev_iou[box_i, qbox_i] = devRotateIoUEval(dev_query_boxes[qbox_i], dev_boxes[box_i], criterion)

    return dev_iou

修改NMS算子

nms_cuda算子在昇腾NPU上无法使用,需要迁移到CPU上计算。

修改路径:“pcdet/ops/iou3d_nms/src/iou3d_cpu.cpp”

修改(新增)内容如下所示:

int nms_cpu(at::Tensor boxes, at::Tensor keep, float nms_overlap_thresh) {
    int boxes_num = boxes.size(0);
    const float * boxes_data = boxes.data<float>();
    long * keep_data = keep.data<long>();

    int num_to_keep = 0;

    std::vector<int> boxIndex;
    for (int i = 0; i < boxes_num; i++) {
        boxIndex.push_back(i);
    }

    while (boxIndex.size() > 0) {
        int keep_box_index = boxIndex[0];
        keep[num_to_keep++] = keep_box_index;

        boxIndex.erase(boxIndex.begin());

        for (auto it = boxIndex.begin(); it != boxIndex.end(); ) {
            float iou_bev_v = iou_bev(boxes_data + keep_box_index * 7, boxes_data + (*it) * 7);
            if (iou_bev_v > nms_overlap_thresh) {
                it = boxIndex.erase(it);
            } else {
                it++;
            }
        }
    }
    return num_to_keep;
}