コード例 #1
0
    def test_compute_ewc_weights_v1(self):
        return
        from incdet3.models.ewc_func import (
            _init_ewc_weights, _cycle_next, _update_ewc_term,
            _compute_accum_grad_v1, _compute_FIM_cls2term_v1,
            _compute_FIM_reg2term_v1, _compute_FIM_clsregterm_v1,
            _update_ewc_weights_v1)
        from incdet3.builders.dataloader_builder import example_convert_to_torch
        from tqdm import tqdm
        from det3.ops import write_pkl
        state = np.random.get_state()
        torch_state_cpu = torch.Generator().get_state()
        torch_state_gpu = torch.Generator(device="cuda:0").get_state()
        network = build_network().cuda()
        dataloader = build_dataloader()
        num_of_datasamples = len(dataloader)
        debug_mode = False
        reg2_coef = 0.1
        clsreg_coef = 0.1
        est_ewc_weights = network.compute_ewc_weights_v1(
            dataloader,
            num_of_datasamples,
            reg2_coef=reg2_coef,
            clsreg_coef=clsreg_coef,
            debug_mode=debug_mode)

        # compute gt
        gt_ewc_weights = _init_ewc_weights(network._model)
        network.eval()
        for i, data in tqdm(enumerate(dataloader)):
            data = example_convert_to_torch(data,
                                            dtype=torch.float32,
                                            device=torch.device("cuda:0"))
            voxels = data["voxels"]
            num_points = data["num_points"]
            coors = data["coordinates"]
            batch_anchors = data["anchors"]
            preds_dict = network._network_forward(network._model, voxels,
                                                  num_points, coors, 1)
            box_preds = preds_dict["box_preds"]
            cls_preds = preds_dict["cls_preds"]
            labels = data['labels']
            reg_targets = data['reg_targets']
            importance = data['importance']
            weights = Network._prepare_loss_weights(
                labels,
                pos_cls_weight=network._pos_cls_weight,
                neg_cls_weight=network._neg_cls_weight,
                loss_norm_type=network._loss_norm_type,
                importance=importance,
                use_direction_classifier=True,
                dtype=box_preds.dtype)
            cls_targets = labels * weights["cared"].type_as(labels)
            cls_targets = cls_targets.unsqueeze(-1)
            loss_cls = network._compute_classification_loss(
                est=cls_preds,
                gt=cls_targets,
                weights=weights["cls_weights"] *
                importance) * network._cls_loss_weight
            loss_reg = network._compute_location_loss(
                est=box_preds,
                gt=reg_targets,
                weights=weights["reg_weights"] *
                importance) * network._loc_loss_weight
            accum_grad_dict = _compute_accum_grad_v1(loss_cls, loss_reg,
                                                     network._model)
            cls2_term = _compute_FIM_cls2term_v1(accum_grad_dict["cls_grad"])
            reg2_term = _compute_FIM_reg2term_v1(accum_grad_dict["reg_grad"])
            clsreg_term = _compute_FIM_clsregterm_v1(
                accum_grad_dict["cls_grad"], accum_grad_dict["reg_grad"])
            gt_ewc_weights = _update_ewc_weights_v1(gt_ewc_weights, cls2_term,
                                                    reg2_term, clsreg_term,
                                                    reg2_coef, clsreg_coef, i)
        for name, param in gt_ewc_weights.items():
            self.assertTrue(torch.allclose(param, est_ewc_weights[name]))
        np.random.set_state(state)
        torch.Generator().set_state(torch_state_cpu)
        torch.Generator(device="cuda:0").set_state(torch_state_gpu)
コード例 #2
0
def build_network():
    network_cfg_template = {
        "VoxelEncoder": {
            "name": "SimpleVoxel",
            "@num_input_features": 4,
        },
        "MiddleLayer": {
            "name": "SpMiddleFHD",
            "@use_norm": True,
            "@num_input_features": 4,
            "@output_shape": [1, 41, 1600, 1408, 16],  #TBD
            "downsample_factor": 8
        },
        "RPN": {
            "name": "ResNetRPN",
            "@use_norm": True,
            "@num_class": None,  # TBD
            "@layer_nums": [5],
            "@layer_strides": [1],
            "@num_filters": [128],
            "@upsample_strides": [1],
            "@num_upsample_filters": [128],
            "@num_input_features": 128,
            "@num_anchor_per_loc": None,  # TBD
            "@encode_background_as_zeros": True,
            "@use_direction_classifier": True,
            "@use_groupnorm": False,
            "@num_groups": 0,
            "@box_code_size": 7,  # TBD
            "@num_direction_bins": 2,
        },
    }
    name_template = "IncDetTest"
    rpn_name = "ResNetRPN"
    network_cfg = deepcopy(network_cfg_template)
    network_cfg["RPN"]["name"] = rpn_name
    network_cfg["RPN"]["@num_class"] = 3
    network_cfg["RPN"]["@num_anchor_per_loc"] = 6
    params = {
        "classes_target": ["class1", "class2", "class3"],
        "classes_source": ["class1", "class2"],
        "model_resume_dict": {
            "ckpt_path":
            "unit_tests/data/train_class2-23200.tckpt",
            "num_classes":
            2,
            "num_anchor_per_loc":
            4,
            "partially_load_params": [
                "rpn.conv_cls.weight",
                "rpn.conv_cls.bias",
                "rpn.conv_box.weight",
                "rpn.conv_box.bias",
                "rpn.conv_dir_cls.weight",
                "rpn.conv_dir_cls.bias",
            ]
        },
        "sub_model_resume_dict": {
            "ckpt_path": "unit_tests/data/train_class2-23200.tckpt",
            "num_classes": 2,
            "num_anchor_per_loc": 4,
            "partially_load_params": []
        },
        "voxel_encoder_dict": network_cfg["VoxelEncoder"],
        "middle_layer_dict": network_cfg["MiddleLayer"],
        "rpn_dict": network_cfg["RPN"],
        "training_mode": "lwf",
        "is_training": True,
        "pos_cls_weight": 1.0,
        "neg_cls_weight": 1.0,
        "l2sp_alpha_coef": 2.0,
        "weight_decay_coef": 0.01,
        "delta_coef": 4.0,
        "ewc_coef": 2.0,
        "ewc_weights_path":
        "unit_tests/data/test_model-ewc-ewc_weights_v1.pkl",
        "distillation_loss_cls_coef": 1.0,
        "distillation_loss_reg_coef": 1.0,
        "num_biased_select": 2,
        "loss_dict": {
            "ClassificationLoss": {
                "name": "SigmoidFocalClassificationLoss",
                "@alpha": 0.25,
                "@gamma": 2.0,
            },
            "LocalizationLoss": {
                "name": "WeightedSmoothL1LocalizationLoss",
                "@sigma": 3.0,
                "@code_weights": [2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0],
                "@codewise": True,
            },
            "DirectionLoss": {
                "name": "WeightedSoftmaxClassificationLoss",
            },
            "DistillationClassificationLoss": {
                "name": "WeightedSmoothL1LocalizationLoss",
                "@sigma": 1.3,
                "@code_weights": [4.0] * 2,
                "@codewise": True,
            },
            "DistillationRegressionLoss": {
                "name": "WeightedSmoothL1LocalizationLoss",
                "@sigma": 3.0,
                "@code_weights": [3.0] * 7,
                "@codewise": True,
            },
        },
        "hook_layers": [],
        "distillation_mode": ["ewc"],
        "bool_reuse_anchor_for_cls": False,
        "bool_biased_select_with_submodel": False
    }
    network = Network(**params).cuda()
    return network
コード例 #3
0
def train(cfg):
    global g_log_dir, g_save_dir
    cores = setup_cores(cfg, mode="train")
    model = cores["model"]
    dataloader_train = cores["dataloader_train"]
    dataloader_val = cores["dataloader_val"]
    optimizer = cores["optimizer"]
    lr_scheduler = cores["lr_scheduler"]

    max_iter = cfg.TRAIN["train_iter"]
    num_log_iter = cfg.TRAIN["num_log_iter"]
    num_val_iter = cfg.TRAIN["num_val_iter"]
    num_save_iter = cfg.TRAIN["num_save_iter"]
    dataitr_train = dataloader_train.__iter__()
    iter_elapsed = 0
    while model.get_global_step() < max_iter:
        iter_elapsed += 1
        model.update_global_step()
        data_dict = get_data(dataloader_train,
                             mode="train",
                             dataloader_itr=dataitr_train)
        data = data_dict["data"]
        dataitr_train = data_dict["dataloader_itr"]
        train_info = train_one_iter(model, data, optimizer, lr_scheduler,
                                    model.get_global_step())
        if model.get_global_step(
        ) % num_save_iter == 0 or model.get_global_step() >= max_iter:
            Network.save_weight(model._model, g_save_dir,
                                model.get_global_step())
            if model._sub_model is not None:
                Network.save_weight(model._sub_model, g_save_dir,
                                    model.get_global_step())
        if model.get_global_step(
        ) % num_log_iter == 0 or model.get_global_step() >= max_iter:
            log_train_info(train_info, model.get_global_step())
            time_elapsed = time.time() - g_since
            ert = (time_elapsed / iter_elapsed *
                   (max_iter - model.get_global_step()))
            print(
                f"Estimated time remaining: {int(ert / 60):d} min {int(ert % 60):d} s"
            )
        if model.get_global_step(
        ) % num_val_iter == 0 or model.get_global_step() >= max_iter:
            val_info = val_one_epoch(model,
                                     dataloader_val,
                                     x_range=(cfg.TASK["valid_range"][0],
                                              cfg.TASK["valid_range"][3]),
                                     y_range=(cfg.TASK["valid_range"][1],
                                              cfg.TASK["valid_range"][4]))
            log_val_info(val_info,
                         model.get_global_step(),
                         vis_param_dict={
                             "data_dir":
                             cfg.VALDATA["@root_path"],
                             "x_range": (cfg.TASK["valid_range"][0],
                                         cfg.TASK["valid_range"][3]),
                             "y_range": (cfg.TASK["valid_range"][1],
                                         cfg.TASK["valid_range"][4]),
                             "grid_size": (0.1, 0.1),
                             "dataset":
                             dataloader_val.dataset
                         })
    Logger.log_txt("Training DONE!")
コード例 #4
0
def generate_pseudo_annotation(cfg):
    if "pseudo_annotation" not in cfg.TRAINDATA.keys():
        return
    Logger.log_txt("==========Generate Pseudo Annotations START=========")
    # build voxelizer and target_assigner
    voxelizer = build_voxelizer(cfg.VOXELIZER)
    param = deepcopy(cfg.TARGETASSIGNER)
    param["@classes"] = cfg.NETWORK["@classes_source"]
    target_assigner = build_target_assigner(param)
    # create pseudo dataset
    ## build network with evaluation mode
    ## do not change cfg.NETWORK
    param = deepcopy(cfg.NETWORK)
    ## modify network._model config and make it same to network._sub_model
    param["@classes_target"] = param["@classes_source"]
    param["@model_resume_dict"] = param["@sub_model_resume_dict"]
    param["@is_training"] = False
    param["@box_coder"] = target_assigner.box_coder
    param["@middle_layer_dict"]["@output_shape"] = [
        1
    ] + voxelizer.grid_size[::-1].tolist() + [16]
    param = {proc_param(k): v for k, v in param.items() if is_param(k)}
    network = Network(**param).cuda()
    ## build dataloader without data augmentation, without shuffle, batch_size 1
    param = deepcopy(cfg.TRAINDATA)
    param["prep"]["@augment_dict"] = None
    param["training"] = False
    param["prep"]["@training"] = False
    param["batch_size"] = 1
    param["num_of_workers"] = 1
    param["@class_names"] = cfg.NETWORK["@classes_source"]
    # The following line does not affect actually.
    param["prep"]["@filter_label_dict"]["keep_classes"] = cfg.NETWORK[
        "@classes_source"]
    dataloader_train = build_dataloader(data_cfg=param,
                                        ext_dict={
                                            "voxelizer":
                                            voxelizer,
                                            "target_assigner":
                                            target_assigner,
                                            "feature_map_size":
                                            param["feature_map_size"]
                                        })
    ## create new labels
    ### setup tmp dirs: tmp_root
    data_root_path = cfg.TRAINDATA["@root_path"]
    data_pc_path = os.path.join(data_root_path, "velodyne")
    data_calib_path = os.path.join(data_root_path, "calib")
    data_label_path = os.path.join(data_root_path, "label_2")
    tmp_root_path = f"/tmp/incdet3-{time.time()}/training"
    tmp_pc_path = os.path.join(tmp_root_path, "velodyne")
    tmp_calib_path = os.path.join(tmp_root_path, "calib")
    tmp_det_path = os.path.join(tmp_root_path, "detections")
    tmp_label_path = os.path.join(tmp_root_path, "label_2")
    tmp_splitidx_path = os.path.join(os.path.dirname(tmp_root_path),
                                     "split_index")
    os.makedirs(tmp_root_path, exist_ok=False)
    os.makedirs(tmp_label_path, exist_ok=False)
    os.makedirs(tmp_splitidx_path, exist_ok=False)
    ### soft link lidar dir, calib dir to tmp_root dir
    os.symlink(data_pc_path, tmp_pc_path)
    os.symlink(data_calib_path, tmp_calib_path)
    ### forward model on dataloader and save detections in tmp_root dir
    network.eval()
    detections = []
    tags = [itm["tag"] for itm in dataloader_train.dataset._kitti_infos]
    calibs = [itm["calib"] for itm in dataloader_train.dataset._kitti_infos]
    write_txt(sorted(tags), os.path.join(tmp_splitidx_path, "train.txt"))
    for data in tqdm(dataloader_train):
        data = example_convert_to_torch(data)
        detection = network(data)
        detections.append(detection[0])
    dataset_type = str(type(dataloader_train.dataset))
    dataloader_train.dataset.save_detections(detections, tags, calibs,
                                             tmp_det_path)
    ### ensemble the detections and gt labels
    ensemble_pseudo_anno_and_gt(gt_label_dir=data_label_path,
                                detection_dir=tmp_det_path,
                                old_classes=cfg.NETWORK["@classes_source"],
                                pseudo_anno_dir=tmp_label_path)
    ## create new info pkls
    ### create info pkl by system call
    assert (
        cfg.TRAINDATA["dataset"] == "kitti",
        "We currently only support the kitti dataset for pseudo annotation.")
    cmd = "python3 tools/create_data_pseudo_anno.py "
    cmd += "--dataset kitti "
    cmd += f"--data-dir {os.path.dirname(tmp_root_path)}"
    os.system(cmd)
    # update cfg.TRAINDATA
    ### update @root_path, @info_path
    cfg.TRAINDATA["@root_path"] = tmp_root_path
    cfg.TRAINDATA["@info_path"] = os.path.join(os.path.dirname(tmp_root_path),
                                               "KITTI_infos_train.pkl")
    ### update classes_to_exclude
    cfg.TRAINDATA["prep"]["@classes_to_exclude"] = []
    Logger.log_txt("==========Generate Pseudo Annotations END=========")
コード例 #5
0
def setup_cores(cfg, mode):
    global g_use_fp16
    if mode == "train":
        # build dataloader_train
        generate_pseudo_annotation(cfg)
        Logger.log_txt(
            "After generating the pseudo annotation, the cfg.TRAINDATA is ")
        Logger.log_txt(cfg.TRAINDATA)
        Logger.log_txt(
            "After generating the pseudo annotation, the cfg.NETWORK is ")
        Logger.log_txt(cfg.NETWORK)
        voxelizer = build_voxelizer(cfg.VOXELIZER)
        target_assigner = build_target_assigner(cfg.TARGETASSIGNER)
        dataloader_train = build_dataloader(
            data_cfg=cfg.TRAINDATA,
            ext_dict={
                "voxelizer": voxelizer,
                "target_assigner": target_assigner,
                "feature_map_size": cfg.TRAINDATA["feature_map_size"]
            })
        # build dataloader_val
        dataloader_val = build_dataloader(data_cfg=cfg.VALDATA,
                                          ext_dict={
                                              "voxelizer":
                                              voxelizer,
                                              "target_assigner":
                                              target_assigner,
                                              "feature_map_size":
                                              cfg.VALDATA["feature_map_size"]
                                          })
        # build dataloader_test
        dataloader_test = None
        # build model
        param = cfg.NETWORK
        param["@middle_layer_dict"]["@output_shape"] = [
            1
        ] + voxelizer.grid_size[::-1].tolist() + [16]
        param["@is_training"] = True
        param["@box_coder"] = target_assigner.box_coder
        param = {proc_param(k): v for k, v in param.items() if is_param(k)}
        network = Network(**param).cuda()
        # build optimizer & lr_scheduler
        optimizer, lr_scheduler = build_optimizer_and_lr_scheduler(
            net=network,
            optimizer_cfg=cfg.TRAIN["optimizer_dict"],
            lr_scheduler_cfg=cfg.TRAIN["lr_scheduler_dict"],
            start_iter=network.get_global_step())
        # handle fp16 training
        use_fp16 = cfg.TASK["use_fp16"] if "use_fp16" in cfg.TASK.keys(
        ) else False
        if use_fp16:
            network, optimizer = amp.initialize(network,
                                                optimizer,
                                                opt_level="O2")
        g_use_fp16 = use_fp16
    elif mode == "test":
        # build dataloader_train
        voxelizer = build_voxelizer(cfg.VOXELIZER)
        target_assigner = build_target_assigner(cfg.TARGETASSIGNER)
        dataloader_train = None
        # build dataloader_val
        dataloader_val = None
        # build dataloader_test
        dataloader_test = build_dataloader(data_cfg=cfg.TESTDATA,
                                           ext_dict={
                                               "voxelizer":
                                               voxelizer,
                                               "target_assigner":
                                               target_assigner,
                                               "feature_map_size":
                                               cfg.TESTDATA["feature_map_size"]
                                           })
        # build model
        param = cfg.NETWORK
        param["@is_training"] = False
        param["@box_coder"] = target_assigner.box_coder
        param["@middle_layer_dict"]["@output_shape"] = [
            1
        ] + voxelizer.grid_size[::-1].tolist() + [16]
        param = {proc_param(k): v for k, v in param.items() if is_param(k)}
        network = Network(**param).cuda()
        # build optimizer & lr_scheduler
        optimizer, lr_scheduler = None, None
    elif mode in ["compute_ewc_weights", "compute_mas_weights"]:
        voxelizer = build_voxelizer(cfg.VOXELIZER)
        target_assigner = build_target_assigner(cfg.TARGETASSIGNER)
        dataloader_train = build_dataloader(
            data_cfg=cfg.TRAINDATA,
            ext_dict={
                "voxelizer": voxelizer,
                "target_assigner": target_assigner,
                "feature_map_size": cfg.TRAINDATA["feature_map_size"]
            })
        dataloader_val, dataloader_test = None, None
        # build model
        param = cfg.NETWORK
        param["@middle_layer_dict"]["@output_shape"] = [
            1
        ] + voxelizer.grid_size[::-1].tolist() + [16]
        param["@is_training"] = True
        param["@box_coder"] = target_assigner.box_coder
        param = {proc_param(k): v for k, v in param.items() if is_param(k)}
        network = Network(**param).cuda()
        # build optimizer & lr_scheduler
        optimizer, lr_scheduler = None, None
    else:
        raise NotImplementedError
    cores = {
        "dataloader_train": dataloader_train,
        "dataloader_val": dataloader_val,
        "dataloader_test": dataloader_test,
        "model": network,
        "optimizer": optimizer,
        "lr_scheduler": lr_scheduler
    }
    return cores