"git@developer.sourcefind.cn:OpenDAS/ollama.git" did not exist on "2a21363bb756a7341d3d577f098583865bd7603f"
Commit e3b5253b authored by ZCMax's avatar ZCMax Committed by ChaimZhu
Browse files

Update all registries and fix some ut problems

parent 8dd8da12
...@@ -4,16 +4,16 @@ ...@@ -4,16 +4,16 @@
## 配置 ## 配置
- 硬件:8 NVIDIA Tesla V100 (32G) GPUs, Intel(R) Xeon(R) Gold 6148 CPU @ 2.40GHz * 硬件:8 NVIDIA Tesla V100 (32G) GPUs, Intel(R) Xeon(R) Gold 6148 CPU @ 2.40GHz
- 软件:Python 3.7, CUDA 10.1, cuDNN 7.6.5, PyTorch 1.3, numba 0.48.0. * 软件:Python 3.7, CUDA 10.1, cuDNN 7.6.5, PyTorch 1.3, numba 0.48.0.
- 模型:由于不同代码库所实现的模型种类有所不同,在基准测试中我们选择了 SECOND、PointPillars、Part-A2 和 VoteNet 几种模型,分别与其他代码库中的相应模型实现进行了对比。 * 模型:由于不同代码库所实现的模型种类有所不同,在基准测试中我们选择了 SECOND、PointPillars、Part-A2 和 VoteNet 几种模型,分别与其他代码库中的相应模型实现进行了对比。
- 度量方法:我们使用整个训练过程中的平均吞吐量作为度量方法,并跳过每个 epoch 的前 50 次迭代以消除训练预热的影响。 * 度量方法:我们使用整个训练过程中的平均吞吐量作为度量方法,并跳过每个 epoch 的前 50 次迭代以消除训练预热的影响。
## 主要结果 ## 主要结果
对于模型的训练速度(样本/秒),我们将 MMDetection3D 与其他实现了相同模型的代码库进行了对比。结果如下所示,表格内的数字越大,代表模型的训练速度越快。代码库中不支持的模型使用 `×` 进行标识。 对于模型的训练速度(样本/秒),我们将 MMDetection3D 与其他实现了相同模型的代码库进行了对比。结果如下所示,表格内的数字越大,代表模型的训练速度越快。代码库中不支持的模型使用 `×` 进行标识。
| 模型 | MMDetection3D | OpenPCDet | votenet | Det3D | | 模型 | MMDetection3D | OpenPCDet | votenet | Det3D |
| :-----------------: | :-----------: | :-------: | :-----: | :---: | | :-----------------: | :-----------: | :-------: | :-----: | :---: |
| VoteNet | 358 | × | 77 | × | | VoteNet | 358 | × | 77 | × |
| PointPillars-car | 141 | × | × | 140 | | PointPillars-car | 141 | × | × | 140 |
...@@ -25,104 +25,103 @@ ...@@ -25,104 +25,103 @@
### 为了计算速度所做的修改 ### 为了计算速度所做的修改
- __MMDetection3D__:我们尝试使用与其他代码库中尽可能相同的配置,具体配置细节见 [基准测试配置](https://github.com/open-mmlab/MMDetection3D/blob/master/configs/benchmark) * __MMDetection3D__:我们尝试使用与其他代码库中尽可能相同的配置,具体配置细节见 [基准测试配置](https://github.com/open-mmlab/MMDetection3D/blob/master/configs/benchmark)
- __Det3D__:为了与 Det3D 进行比较,我们使用了 commit [519251e](https://github.com/poodarchu/Det3D/tree/519251e72a5c1fdd58972eabeac67808676b9bb7) 所对应的代码版本。 * __Det3D__:为了与 Det3D 进行比较,我们使用了 commit [519251e](https://github.com/poodarchu/Det3D/tree/519251e72a5c1fdd58972eabeac67808676b9bb7) 所对应的代码版本。
- __OpenPCDet__:为了与 OpenPCDet 进行比较,我们使用了 commit [b32fbddb](https://github.com/open-mmlab/OpenPCDet/tree/b32fbddbe06183507bad433ed99b407cbc2175c2) 所对应的代码版本。 * __OpenPCDet__:为了与 OpenPCDet 进行比较,我们使用了 commit [b32fbddb](https://github.com/open-mmlab/OpenPCDet/tree/b32fbddbe06183507bad433ed99b407cbc2175c2) 所对应的代码版本。
为了计算训练速度,我们在 `./tools/train_utils/train_utils.py` 文件中添加了用于记录运行时间的代码。我们对每个 epoch 的训练速度进行计算,并报告所有 epoch 的平均速度。 为了计算训练速度,我们在 `./tools/train_utils/train_utils.py` 文件中添加了用于记录运行时间的代码。我们对每个 epoch 的训练速度进行计算,并报告所有 epoch 的平均速度。
<details>
<details>
<summary> <summary>
(为了使用相同方法进行测试所做的具体修改 - 点击展开) (为了使用相同方法进行测试所做的具体修改 - 点击展开)
</summary> </summary>
```diff ```diff
diff --git a/tools/train_utils/train_utils.py b/tools/train_utils/train_utils.py diff --git a/tools/train_utils/train_utils.py b/tools/train_utils/train_utils.py
index 91f21dd..021359d 100644 index 91f21dd..021359d 100644
--- a/tools/train_utils/train_utils.py --- a/tools/train_utils/train_utils.py
+++ b/tools/train_utils/train_utils.py +++ b/tools/train_utils/train_utils.py
@@ -2,6 +2,7 @@ import torch @@ -2,6 +2,7 @@ import torch
import os import os
import glob import glob
import tqdm import tqdm
+import datetime +import datetime
from torch.nn.utils import clip_grad_norm_ from torch.nn.utils import clip_grad_norm_
@@ -13,7 +14,10 @@ def train_one_epoch(model, optimizer, train_loader, model_func, lr_scheduler, ac @@ -13,7 +14,10 @@ def train_one_epoch(model, optimizer, train_loader, model_func, lr_scheduler, ac
if rank == 0: if rank == 0:
pbar = tqdm.tqdm(total=total_it_each_epoch, leave=leave_pbar, desc='train', dynamic_ncols=True) pbar = tqdm.tqdm(total=total_it_each_epoch, leave=leave_pbar, desc='train', dynamic_ncols=True)
+ start_time = None + start_time = None
for cur_it in range(total_it_each_epoch): for cur_it in range(total_it_each_epoch):
+ if cur_it > 49 and start_time is None: + if cur_it > 49 and start_time is None:
+ start_time = datetime.datetime.now() + start_time = datetime.datetime.now()
try: try:
batch = next(dataloader_iter) batch = next(dataloader_iter)
except StopIteration: except StopIteration:
@@ -55,9 +59,11 @@ def train_one_epoch(model, optimizer, train_loader, model_func, lr_scheduler, ac @@ -55,9 +59,11 @@ def train_one_epoch(model, optimizer, train_loader, model_func, lr_scheduler, ac
tb_log.add_scalar('learning_rate', cur_lr, accumulated_iter) tb_log.add_scalar('learning_rate', cur_lr, accumulated_iter)
for key, val in tb_dict.items(): for key, val in tb_dict.items():
tb_log.add_scalar('train_' + key, val, accumulated_iter) tb_log.add_scalar('train_' + key, val, accumulated_iter)
+ endtime = datetime.datetime.now() + endtime = datetime.datetime.now()
+ speed = (endtime - start_time).seconds / (total_it_each_epoch - 50) + speed = (endtime - start_time).seconds / (total_it_each_epoch - 50)
if rank == 0: if rank == 0:
pbar.close() pbar.close()
- return accumulated_iter - return accumulated_iter
+ return accumulated_iter, speed + return accumulated_iter, speed
def train_model(model, optimizer, train_loader, model_func, lr_scheduler, optim_cfg, def train_model(model, optimizer, train_loader, model_func, lr_scheduler, optim_cfg,
@@ -65,6 +71,7 @@ def train_model(model, optimizer, train_loader, model_func, lr_scheduler, optim_ @@ -65,6 +71,7 @@ def train_model(model, optimizer, train_loader, model_func, lr_scheduler, optim_
lr_warmup_scheduler=None, ckpt_save_interval=1, max_ckpt_save_num=50, lr_warmup_scheduler=None, ckpt_save_interval=1, max_ckpt_save_num=50,
merge_all_iters_to_one_epoch=False): merge_all_iters_to_one_epoch=False):
accumulated_iter = start_iter accumulated_iter = start_iter
+ speeds = [] + speeds = []
with tqdm.trange(start_epoch, total_epochs, desc='epochs', dynamic_ncols=True, leave=(rank == 0)) as tbar: with tqdm.trange(start_epoch, total_epochs, desc='epochs', dynamic_ncols=True, leave=(rank == 0)) as tbar:
total_it_each_epoch = len(train_loader) total_it_each_epoch = len(train_loader)
if merge_all_iters_to_one_epoch: if merge_all_iters_to_one_epoch:
@@ -82,7 +89,7 @@ def train_model(model, optimizer, train_loader, model_func, lr_scheduler, optim_ @@ -82,7 +89,7 @@ def train_model(model, optimizer, train_loader, model_func, lr_scheduler, optim_
cur_scheduler = lr_warmup_scheduler cur_scheduler = lr_warmup_scheduler
else: else:
cur_scheduler = lr_scheduler cur_scheduler = lr_scheduler
- accumulated_iter = train_one_epoch( - accumulated_iter = train_one_epoch(
+ accumulated_iter, speed = train_one_epoch( + accumulated_iter, speed = train_one_epoch(
model, optimizer, train_loader, model_func, model, optimizer, train_loader, model_func,
lr_scheduler=cur_scheduler, lr_scheduler=cur_scheduler,
accumulated_iter=accumulated_iter, optim_cfg=optim_cfg, accumulated_iter=accumulated_iter, optim_cfg=optim_cfg,
@@ -91,7 +98,7 @@ def train_model(model, optimizer, train_loader, model_func, lr_scheduler, optim_ @@ -91,7 +98,7 @@ def train_model(model, optimizer, train_loader, model_func, lr_scheduler, optim_
total_it_each_epoch=total_it_each_epoch, total_it_each_epoch=total_it_each_epoch,
dataloader_iter=dataloader_iter dataloader_iter=dataloader_iter
) )
- -
+ speeds.append(speed) + speeds.append(speed)
# save trained model # save trained model
trained_epoch = cur_epoch + 1 trained_epoch = cur_epoch + 1
if trained_epoch % ckpt_save_interval == 0 and rank == 0: if trained_epoch % ckpt_save_interval == 0 and rank == 0:
@@ -107,6 +114,8 @@ def train_model(model, optimizer, train_loader, model_func, lr_scheduler, optim_ @@ -107,6 +114,8 @@ def train_model(model, optimizer, train_loader, model_func, lr_scheduler, optim_
save_checkpoint( save_checkpoint(
checkpoint_state(model, optimizer, trained_epoch, accumulated_iter), filename=ckpt_name, checkpoint_state(model, optimizer, trained_epoch, accumulated_iter), filename=ckpt_name,
) )
+ print(speed) + print(speed)
+ print(f'*******{sum(speeds) / len(speeds)}******') + print(f'*******{sum(speeds) / len(speeds)}******')
def model_state_to_cpu(model_state): def model_state_to_cpu(model_state):
``` ```
</details> </details>
### VoteNet ### VoteNet
- __MMDetection3D__:在 v0.1.0 版本下, 执行如下命令: * __MMDetection3D__:在 v0.1.0 版本下, 执行如下命令:
```bash ```bash
./tools/dist_train.sh configs/votenet/votenet_16x8_sunrgbd-3d-10class.py 8 --no-validate ./tools/dist_train.sh configs/votenet/votenet_16x8_sunrgbd-3d-10class.py 8 --no-validate
``` ```
- __votenet__:在 commit [2f6d6d3](https://github.com/facebookresearch/votenet/tree/2f6d6d36ff98d96901182e935afe48ccee82d566) 版本下,执行如下命令: * __votenet__:在 commit [2f6d6d3](https://github.com/facebookresearch/votenet/tree/2f6d6d36ff98d96901182e935afe48ccee82d566) 版本下,执行如下命令:
```bash ```bash
python train.py --dataset sunrgbd --batch_size 16 python train.py --dataset sunrgbd --batch_size 16
...@@ -197,13 +196,13 @@ ...@@ -197,13 +196,13 @@
### PointPillars-car ### PointPillars-car
- __MMDetection3D__:在 v0.1.0 版本下, 执行如下命令: * __MMDetection3D__:在 v0.1.0 版本下, 执行如下命令:
```bash ```bash
./tools/dist_train.sh configs/benchmark/hv_pointpillars_secfpn_3x8_100e_det3d_kitti-3d-car.py 8 --no-validate ./tools/dist_train.sh configs/benchmark/hv_pointpillars_secfpn_3x8_100e_det3d_kitti-3d-car.py 8 --no-validate
``` ```
- __Det3D__:在 commit [519251e](https://github.com/poodarchu/Det3D/tree/519251e72a5c1fdd58972eabeac67808676b9bb7) 版本下,使用 `kitti_point_pillars_mghead_syncbn.py` 并执行如下命令: * __Det3D__:在 commit [519251e](https://github.com/poodarchu/Det3D/tree/519251e72a5c1fdd58972eabeac67808676b9bb7) 版本下,使用 `kitti_point_pillars_mghead_syncbn.py` 并执行如下命令:
```bash ```bash
./tools/scripts/train.sh --launcher=slurm --gpus=8 ./tools/scripts/train.sh --launcher=slurm --gpus=8
...@@ -239,13 +238,13 @@ ...@@ -239,13 +238,13 @@
### PointPillars-3class ### PointPillars-3class
- __MMDetection3D__:在 v0.1.0 版本下, 执行如下命令: * __MMDetection3D__:在 v0.1.0 版本下, 执行如下命令:
```bash ```bash
./tools/dist_train.sh configs/benchmark/hv_pointpillars_secfpn_4x8_80e_pcdet_kitti-3d-3class.py 8 --no-validate ./tools/dist_train.sh configs/benchmark/hv_pointpillars_secfpn_4x8_80e_pcdet_kitti-3d-3class.py 8 --no-validate
``` ```
- __OpenPCDet__:在 commit [b32fbddb](https://github.com/open-mmlab/OpenPCDet/tree/b32fbddbe06183507bad433ed99b407cbc2175c2) 版本下,执行如下命令: * __OpenPCDet__:在 commit [b32fbddb](https://github.com/open-mmlab/OpenPCDet/tree/b32fbddbe06183507bad433ed99b407cbc2175c2) 版本下,执行如下命令:
```bash ```bash
cd tools cd tools
...@@ -256,13 +255,13 @@ ...@@ -256,13 +255,13 @@
基准测试中的 SECOND 指在 [second.Pytorch](https://github.com/traveller59/second.pytorch) 首次被实现的 [SECONDv1.5](https://github.com/traveller59/second.pytorch/blob/master/second/configs/all.fhd.config)。Det3D 实现的 SECOND 中,使用了自己实现的 Multi-Group Head,因此无法将它的速度与其他代码库进行对比。 基准测试中的 SECOND 指在 [second.Pytorch](https://github.com/traveller59/second.pytorch) 首次被实现的 [SECONDv1.5](https://github.com/traveller59/second.pytorch/blob/master/second/configs/all.fhd.config)。Det3D 实现的 SECOND 中,使用了自己实现的 Multi-Group Head,因此无法将它的速度与其他代码库进行对比。
- __MMDetection3D__:在 v0.1.0 版本下, 执行如下命令: * __MMDetection3D__:在 v0.1.0 版本下, 执行如下命令:
```bash ```bash
./tools/dist_train.sh configs/benchmark/hv_second_secfpn_4x8_80e_pcdet_kitti-3d-3class.py 8 --no-validate ./tools/dist_train.sh configs/benchmark/hv_second_secfpn_4x8_80e_pcdet_kitti-3d-3class.py 8 --no-validate
``` ```
- __OpenPCDet__:在 commit [b32fbddb](https://github.com/open-mmlab/OpenPCDet/tree/b32fbddbe06183507bad433ed99b407cbc2175c2) 版本下,执行如下命令: * __OpenPCDet__:在 commit [b32fbddb](https://github.com/open-mmlab/OpenPCDet/tree/b32fbddbe06183507bad433ed99b407cbc2175c2) 版本下,执行如下命令:
```bash ```bash
cd tools cd tools
...@@ -271,13 +270,13 @@ ...@@ -271,13 +270,13 @@
### Part-A2 ### Part-A2
- __MMDetection3D__:在 v0.1.0 版本下, 执行如下命令: * __MMDetection3D__:在 v0.1.0 版本下, 执行如下命令:
```bash ```bash
./tools/dist_train.sh configs/benchmark/hv_PartA2_secfpn_4x8_cyclic_80e_pcdet_kitti-3d-3class.py 8 --no-validate ./tools/dist_train.sh configs/benchmark/hv_PartA2_secfpn_4x8_cyclic_80e_pcdet_kitti-3d-3class.py 8 --no-validate
``` ```
- __OpenPCDet__:在 commit [b32fbddb](https://github.com/open-mmlab/OpenPCDet/tree/b32fbddbe06183507bad433ed99b407cbc2175c2) 版本下,执行如下命令以进行模型训练: * __OpenPCDet__:在 commit [b32fbddb](https://github.com/open-mmlab/OpenPCDet/tree/b32fbddbe06183507bad433ed99b407cbc2175c2) 版本下,执行如下命令以进行模型训练:
```bash ```bash
cd tools cd tools
......
...@@ -3,12 +3,13 @@ from .inference import (convert_SyncBN, inference_detector, ...@@ -3,12 +3,13 @@ from .inference import (convert_SyncBN, inference_detector,
inference_mono_3d_detector, inference_mono_3d_detector,
inference_multi_modality_detector, inference_segmentor, inference_multi_modality_detector, inference_segmentor,
init_model, show_result_meshlab) init_model, show_result_meshlab)
from .test import single_gpu_test
from .train import init_random_seed, train_model
__all__ = [ __all__ = [
'inference_detector', 'init_model', 'single_gpu_test', 'inference_detector',
'inference_mono_3d_detector', 'show_result_meshlab', 'convert_SyncBN', 'init_model',
'train_model', 'inference_multi_modality_detector', 'inference_segmentor', 'inference_mono_3d_detector',
'init_random_seed' 'show_result_meshlab',
'convert_SyncBN',
'inference_multi_modality_detector',
'inference_segmentor',
] ]
# Copyright (c) OpenMMLab. All rights reserved.
from os import path as osp
import mmcv
import torch
from mmcv.image import tensor2imgs
from mmdet3d.models import (Base3DDetector, Base3DSegmentor,
SingleStageMono3DDetector)
def single_gpu_test(model,
data_loader,
show=False,
out_dir=None,
show_score_thr=0.3):
"""Test model with single gpu.
This method tests model with single gpu and gives the 'show' option.
By setting ``show=True``, it saves the visualization results under
``out_dir``.
Args:
model (nn.Module): Model to be tested.
data_loader (nn.Dataloader): Pytorch data loader.
show (bool, optional): Whether to save viualization results.
Default: True.
out_dir (str, optional): The path to save visualization results.
Default: None.
Returns:
list[dict]: The prediction results.
"""
model.eval()
results = []
dataset = data_loader.dataset
prog_bar = mmcv.ProgressBar(len(dataset))
for i, data in enumerate(data_loader):
with torch.no_grad():
result = model(return_loss=False, rescale=True, **data)
if show:
# Visualize the results of MMDetection3D model
# 'show_results' is MMdetection3D visualization API
models_3d = (Base3DDetector, Base3DSegmentor,
SingleStageMono3DDetector)
if isinstance(model.module, models_3d):
model.module.show_results(
data,
result,
out_dir=out_dir,
show=show,
score_thr=show_score_thr)
# Visualize the results of MMDetection model
# 'show_result' is MMdetection visualization API
else:
batch_size = len(result)
if batch_size == 1 and isinstance(data['img'][0],
torch.Tensor):
img_tensor = data['img'][0]
else:
img_tensor = data['img'][0].data[0]
img_metas = data['img_metas'][0].data[0]
imgs = tensor2imgs(img_tensor, **img_metas[0]['img_norm_cfg'])
assert len(imgs) == len(img_metas)
for i, (img, img_meta) in enumerate(zip(imgs, img_metas)):
h, w, _ = img_meta['img_shape']
img_show = img[:h, :w, :]
ori_h, ori_w = img_meta['ori_shape'][:-1]
img_show = mmcv.imresize(img_show, (ori_w, ori_h))
if out_dir:
out_file = osp.join(out_dir, img_meta['ori_filename'])
else:
out_file = None
model.module.show_result(
img_show,
result[i],
show=show,
out_file=out_file,
score_thr=show_score_thr)
results.extend(result)
batch_size = len(result)
for _ in range(batch_size):
prog_bar.update()
return results
# Copyright (c) OpenMMLab. All rights reserved.
import random
import warnings
import numpy as np
import torch
from mmcv.parallel import MMDataParallel, MMDistributedDataParallel
from mmcv.runner import (HOOKS, DistSamplerSeedHook, EpochBasedRunner,
Fp16OptimizerHook, OptimizerHook, build_optimizer,
build_runner, get_dist_info)
from mmcv.utils import build_from_cfg
from torch import distributed as dist
from mmdet3d.datasets import build_dataset
from mmdet3d.utils import find_latest_checkpoint
from mmdet.core import DistEvalHook as MMDET_DistEvalHook
from mmdet.core import EvalHook as MMDET_EvalHook
from mmdet.datasets import build_dataloader as build_mmdet_dataloader
from mmdet.datasets import replace_ImageToTensor
from mmdet.utils import get_root_logger as get_mmdet_root_logger
from mmseg.core import DistEvalHook as MMSEG_DistEvalHook
from mmseg.core import EvalHook as MMSEG_EvalHook
from mmseg.datasets import build_dataloader as build_mmseg_dataloader
from mmseg.utils import get_root_logger as get_mmseg_root_logger
def init_random_seed(seed=None, device='cuda'):
"""Initialize random seed.
If the seed is not set, the seed will be automatically randomized,
and then broadcast to all processes to prevent some potential bugs.
Args:
seed (int, optional): The seed. Default to None.
device (str, optional): The device where the seed will be put on.
Default to 'cuda'.
Returns:
int: Seed to be used.
"""
if seed is not None:
return seed
# Make sure all ranks share the same random seed to prevent
# some potential bugs. Please refer to
# https://github.com/open-mmlab/mmdetection/issues/6339
rank, world_size = get_dist_info()
seed = np.random.randint(2**31)
if world_size == 1:
return seed
if rank == 0:
random_num = torch.tensor(seed, dtype=torch.int32, device=device)
else:
random_num = torch.tensor(0, dtype=torch.int32, device=device)
dist.broadcast(random_num, src=0)
return random_num.item()
def set_random_seed(seed, deterministic=False):
"""Set random seed.
Args:
seed (int): Seed to be used.
deterministic (bool): Whether to set the deterministic option for
CUDNN backend, i.e., set `torch.backends.cudnn.deterministic`
to True and `torch.backends.cudnn.benchmark` to False.
Default: False.
"""
random.seed(seed)
np.random.seed(seed)
torch.manual_seed(seed)
torch.cuda.manual_seed_all(seed)
if deterministic:
torch.backends.cudnn.deterministic = True
torch.backends.cudnn.benchmark = False
def train_segmentor(model,
dataset,
cfg,
distributed=False,
validate=False,
timestamp=None,
meta=None):
"""Launch segmentor training."""
logger = get_mmseg_root_logger(cfg.log_level)
# prepare data loaders
dataset = dataset if isinstance(dataset, (list, tuple)) else [dataset]
data_loaders = [
build_mmseg_dataloader(
ds,
cfg.data.samples_per_gpu,
cfg.data.workers_per_gpu,
# cfg.gpus will be ignored if distributed
len(cfg.gpu_ids),
dist=distributed,
seed=cfg.seed,
drop_last=True) for ds in dataset
]
# put model on gpus
if distributed:
find_unused_parameters = cfg.get('find_unused_parameters', False)
# Sets the `find_unused_parameters` parameter in
# torch.nn.parallel.DistributedDataParallel
model = MMDistributedDataParallel(
model.cuda(),
device_ids=[torch.cuda.current_device()],
broadcast_buffers=False,
find_unused_parameters=find_unused_parameters)
else:
model = MMDataParallel(
model.cuda(cfg.gpu_ids[0]), device_ids=cfg.gpu_ids)
# build runner
optimizer = build_optimizer(model, cfg.optimizer)
if cfg.get('runner') is None:
cfg.runner = {'type': 'IterBasedRunner', 'max_iters': cfg.total_iters}
warnings.warn(
'config is now expected to have a `runner` section, '
'please set `runner` in your config.', UserWarning)
runner = build_runner(
cfg.runner,
default_args=dict(
model=model,
batch_processor=None,
optimizer=optimizer,
work_dir=cfg.work_dir,
logger=logger,
meta=meta))
# register hooks
runner.register_training_hooks(cfg.lr_config, cfg.optimizer_config,
cfg.checkpoint_config, cfg.log_config,
cfg.get('momentum_config', None))
# an ugly walkaround to make the .log and .log.json filenames the same
runner.timestamp = timestamp
# register eval hooks
if validate:
val_dataset = build_dataset(cfg.data.val, dict(test_mode=True))
val_dataloader = build_mmseg_dataloader(
val_dataset,
samples_per_gpu=1,
workers_per_gpu=cfg.data.workers_per_gpu,
dist=distributed,
shuffle=False)
eval_cfg = cfg.get('evaluation', {})
eval_cfg['by_epoch'] = cfg.runner['type'] != 'IterBasedRunner'
eval_hook = MMSEG_DistEvalHook if distributed else MMSEG_EvalHook
# In this PR (https://github.com/open-mmlab/mmcv/pull/1193), the
# priority of IterTimerHook has been modified from 'NORMAL' to 'LOW'.
runner.register_hook(
eval_hook(val_dataloader, **eval_cfg), priority='LOW')
# user-defined hooks
if cfg.get('custom_hooks', None):
custom_hooks = cfg.custom_hooks
assert isinstance(custom_hooks, list), \
f'custom_hooks expect list type, but got {type(custom_hooks)}'
for hook_cfg in cfg.custom_hooks:
assert isinstance(hook_cfg, dict), \
'Each item in custom_hooks expects dict type, but got ' \
f'{type(hook_cfg)}'
hook_cfg = hook_cfg.copy()
priority = hook_cfg.pop('priority', 'NORMAL')
hook = build_from_cfg(hook_cfg, HOOKS)
runner.register_hook(hook, priority=priority)
if cfg.resume_from:
runner.resume(cfg.resume_from)
elif cfg.load_from:
runner.load_checkpoint(cfg.load_from)
runner.run(data_loaders, cfg.workflow)
def train_detector(model,
dataset,
cfg,
distributed=False,
validate=False,
timestamp=None,
meta=None):
logger = get_mmdet_root_logger(log_level=cfg.log_level)
# prepare data loaders
dataset = dataset if isinstance(dataset, (list, tuple)) else [dataset]
if 'imgs_per_gpu' in cfg.data:
logger.warning('"imgs_per_gpu" is deprecated in MMDet V2.0. '
'Please use "samples_per_gpu" instead')
if 'samples_per_gpu' in cfg.data:
logger.warning(
f'Got "imgs_per_gpu"={cfg.data.imgs_per_gpu} and '
f'"samples_per_gpu"={cfg.data.samples_per_gpu}, "imgs_per_gpu"'
f'={cfg.data.imgs_per_gpu} is used in this experiments')
else:
logger.warning(
'Automatically set "samples_per_gpu"="imgs_per_gpu"='
f'{cfg.data.imgs_per_gpu} in this experiments')
cfg.data.samples_per_gpu = cfg.data.imgs_per_gpu
runner_type = 'EpochBasedRunner' if 'runner' not in cfg else cfg.runner[
'type']
data_loaders = [
build_mmdet_dataloader(
ds,
cfg.data.samples_per_gpu,
cfg.data.workers_per_gpu,
# `num_gpus` will be ignored if distributed
num_gpus=len(cfg.gpu_ids),
dist=distributed,
seed=cfg.seed,
runner_type=runner_type,
persistent_workers=cfg.data.get('persistent_workers', False))
for ds in dataset
]
# put model on gpus
if distributed:
find_unused_parameters = cfg.get('find_unused_parameters', False)
# Sets the `find_unused_parameters` parameter in
# torch.nn.parallel.DistributedDataParallel
model = MMDistributedDataParallel(
model.cuda(),
device_ids=[torch.cuda.current_device()],
broadcast_buffers=False,
find_unused_parameters=find_unused_parameters)
else:
model = MMDataParallel(
model.cuda(cfg.gpu_ids[0]), device_ids=cfg.gpu_ids)
# build runner
optimizer = build_optimizer(model, cfg.optimizer)
if 'runner' not in cfg:
cfg.runner = {
'type': 'EpochBasedRunner',
'max_epochs': cfg.total_epochs
}
warnings.warn(
'config is now expected to have a `runner` section, '
'please set `runner` in your config.', UserWarning)
else:
if 'total_epochs' in cfg:
assert cfg.total_epochs == cfg.runner.max_epochs
runner = build_runner(
cfg.runner,
default_args=dict(
model=model,
optimizer=optimizer,
work_dir=cfg.work_dir,
logger=logger,
meta=meta))
# an ugly workaround to make .log and .log.json filenames the same
runner.timestamp = timestamp
# fp16 setting
fp16_cfg = cfg.get('fp16', None)
if fp16_cfg is not None:
optimizer_config = Fp16OptimizerHook(
**cfg.optimizer_config, **fp16_cfg, distributed=distributed)
elif distributed and 'type' not in cfg.optimizer_config:
optimizer_config = OptimizerHook(**cfg.optimizer_config)
else:
optimizer_config = cfg.optimizer_config
# register hooks
runner.register_training_hooks(
cfg.lr_config,
optimizer_config,
cfg.checkpoint_config,
cfg.log_config,
cfg.get('momentum_config', None),
custom_hooks_config=cfg.get('custom_hooks', None))
if distributed:
if isinstance(runner, EpochBasedRunner):
runner.register_hook(DistSamplerSeedHook())
# register eval hooks
if validate:
# Support batch_size > 1 in validation
val_samples_per_gpu = cfg.data.val.pop('samples_per_gpu', 1)
if val_samples_per_gpu > 1:
# Replace 'ImageToTensor' to 'DefaultFormatBundle'
cfg.data.val.pipeline = replace_ImageToTensor(
cfg.data.val.pipeline)
val_dataset = build_dataset(cfg.data.val, dict(test_mode=True))
val_dataloader = build_mmdet_dataloader(
val_dataset,
samples_per_gpu=val_samples_per_gpu,
workers_per_gpu=cfg.data.workers_per_gpu,
dist=distributed,
shuffle=False)
eval_cfg = cfg.get('evaluation', {})
eval_cfg['by_epoch'] = cfg.runner['type'] != 'IterBasedRunner'
eval_hook = MMDET_DistEvalHook if distributed else MMDET_EvalHook
# In this PR (https://github.com/open-mmlab/mmcv/pull/1193), the
# priority of IterTimerHook has been modified from 'NORMAL' to 'LOW'.
runner.register_hook(
eval_hook(val_dataloader, **eval_cfg), priority='LOW')
resume_from = None
if cfg.resume_from is None and cfg.get('auto_resume'):
resume_from = find_latest_checkpoint(cfg.work_dir)
if resume_from is not None:
cfg.resume_from = resume_from
if cfg.resume_from:
runner.resume(cfg.resume_from)
elif cfg.load_from:
runner.load_checkpoint(cfg.load_from)
runner.run(data_loaders, cfg.workflow)
def train_model(model,
dataset,
cfg,
distributed=False,
validate=False,
timestamp=None,
meta=None):
"""A function wrapper for launching model training according to cfg.
Because we need different eval_hook in runner. Should be deprecated in the
future.
"""
if cfg.model.type in ['EncoderDecoder3D']:
train_segmentor(
model,
dataset,
cfg,
distributed=distributed,
validate=validate,
timestamp=timestamp,
meta=meta)
else:
train_detector(
model,
dataset,
cfg,
distributed=distributed,
validate=validate,
timestamp=timestamp,
meta=meta)
# Copyright (c) OpenMMLab. All rights reserved. # Copyright (c) OpenMMLab. All rights reserved.
from mmdet.core.anchor import build_prior_generator
from .anchor_3d_generator import (AlignedAnchor3DRangeGenerator, from .anchor_3d_generator import (AlignedAnchor3DRangeGenerator,
AlignedAnchor3DRangeGeneratorPerCls, AlignedAnchor3DRangeGeneratorPerCls,
Anchor3DRangeGenerator) Anchor3DRangeGenerator)
from .builder import (ANCHOR_GENERATORS, PRIOR_GENERATORS,
build_anchor_generator, build_prior_generator)
__all__ = [ __all__ = [
'AlignedAnchor3DRangeGenerator', 'Anchor3DRangeGenerator', 'AlignedAnchor3DRangeGenerator', 'Anchor3DRangeGenerator',
'build_prior_generator', 'AlignedAnchor3DRangeGeneratorPerCls' 'build_prior_generator', 'AlignedAnchor3DRangeGeneratorPerCls',
'build_anchor_generator', 'ANCHOR_GENERATORS', 'PRIOR_GENERATORS'
] ]
...@@ -2,10 +2,10 @@ ...@@ -2,10 +2,10 @@
import mmcv import mmcv
import torch import torch
from mmdet.core.anchor import ANCHOR_GENERATORS from mmdet3d.registry import TASK_UTILS
@ANCHOR_GENERATORS.register_module() @TASK_UTILS.register_module()
class Anchor3DRangeGenerator(object): class Anchor3DRangeGenerator(object):
"""3D Anchor Generator by range. """3D Anchor Generator by range.
...@@ -221,7 +221,7 @@ class Anchor3DRangeGenerator(object): ...@@ -221,7 +221,7 @@ class Anchor3DRangeGenerator(object):
return ret return ret
@ANCHOR_GENERATORS.register_module() @TASK_UTILS.register_module()
class AlignedAnchor3DRangeGenerator(Anchor3DRangeGenerator): class AlignedAnchor3DRangeGenerator(Anchor3DRangeGenerator):
"""Aligned 3D Anchor Generator by range. """Aligned 3D Anchor Generator by range.
...@@ -340,7 +340,7 @@ class AlignedAnchor3DRangeGenerator(Anchor3DRangeGenerator): ...@@ -340,7 +340,7 @@ class AlignedAnchor3DRangeGenerator(Anchor3DRangeGenerator):
return ret return ret
@ANCHOR_GENERATORS.register_module() @TASK_UTILS.register_module()
class AlignedAnchor3DRangeGeneratorPerCls(AlignedAnchor3DRangeGenerator): class AlignedAnchor3DRangeGeneratorPerCls(AlignedAnchor3DRangeGenerator):
"""3D Anchor Generator by range for per class. """3D Anchor Generator by range for per class.
......
# Copyright (c) OpenMMLab. All rights reserved.
import warnings
from mmdet3d.registry import TASK_UTILS
PRIOR_GENERATORS = TASK_UTILS
ANCHOR_GENERATORS = TASK_UTILS
def build_prior_generator(cfg, default_args=None):
warnings.warn(
'``build_prior_generator`` would be deprecated soon, please use '
'``mmdet3d.registry.TASK_UTILS.build()`` ')
return TASK_UTILS.build(cfg, default_args=default_args)
def build_anchor_generator(cfg, default_args=None):
warnings.warn(
'``build_anchor_generator`` would be deprecated soon, please use '
'``mmdet3d.registry.TASK_UTILS.build()`` ')
return TASK_UTILS.build(cfg, default_args=default_args)
# Copyright (c) OpenMMLab. All rights reserved. # Copyright (c) OpenMMLab. All rights reserved.
from .assigners import AssignResult, BaseAssigner, MaxIoUAssigner from .assigners import AssignResult, BaseAssigner, MaxIoUAssigner
from .coders import DeltaXYZWLHRBBoxCoder
# from .bbox_target import bbox_target # from .bbox_target import bbox_target
from .builder import build_assigner, build_bbox_coder, build_sampler
from .coders import DeltaXYZWLHRBBoxCoder
from .iou_calculators import (AxisAlignedBboxOverlaps3D, BboxOverlaps3D, from .iou_calculators import (AxisAlignedBboxOverlaps3D, BboxOverlaps3D,
BboxOverlapsNearest3D, BboxOverlapsNearest3D,
axis_aligned_bbox_overlaps_3d, bbox_overlaps_3d, axis_aligned_bbox_overlaps_3d, bbox_overlaps_3d,
...@@ -26,5 +27,6 @@ __all__ = [ ...@@ -26,5 +27,6 @@ __all__ = [
'LiDARInstance3DBoxes', 'CameraInstance3DBoxes', 'bbox3d2roi', 'LiDARInstance3DBoxes', 'CameraInstance3DBoxes', 'bbox3d2roi',
'bbox3d2result', 'DepthInstance3DBoxes', 'BaseInstance3DBoxes', 'bbox3d2result', 'DepthInstance3DBoxes', 'BaseInstance3DBoxes',
'bbox3d_mapping_back', 'xywhr2xyxyr', 'limit_period', 'points_cam2img', 'bbox3d_mapping_back', 'xywhr2xyxyr', 'limit_period', 'points_cam2img',
'points_img2cam', 'get_box_type', 'Coord3DMode', 'mono_cam_box2vis' 'points_img2cam', 'get_box_type', 'Coord3DMode', 'mono_cam_box2vis',
'build_assigner', 'build_bbox_coder', 'build_sampler'
] ]
# Copyright (c) OpenMMLab. All rights reserved.
import warnings
from mmdet3d.registry import TASK_UTILS
BBOX_ASSIGNERS = TASK_UTILS
BBOX_SAMPLERS = TASK_UTILS
BBOX_CODERS = TASK_UTILS
def build_assigner(cfg, **default_args):
"""Builder of box assigner."""
warnings.warn('``build_assigner`` would be deprecated soon, please use '
'``mmdet3d.registry.TASK_UTILS.build()`` ')
return TASK_UTILS.build(cfg, default_args=default_args)
def build_sampler(cfg, **default_args):
"""Builder of box sampler."""
warnings.warn('``build_sampler`` would be deprecated soon, please use '
'``mmdet3d.registry.TASK_UTILS.build()`` ')
return TASK_UTILS.build(cfg, default_args=default_args)
def build_bbox_coder(cfg, **default_args):
"""Builder of box coder."""
warnings.warn('``build_bbox_coder`` would be deprecated soon, please use '
'``mmdet3d.registry.TASK_UTILS.build()`` ')
return TASK_UTILS.build(cfg, default_args=default_args)
# Copyright (c) OpenMMLab. All rights reserved. # Copyright (c) OpenMMLab. All rights reserved.
from mmdet.core.bbox import build_bbox_coder
from .anchor_free_bbox_coder import AnchorFreeBBoxCoder from .anchor_free_bbox_coder import AnchorFreeBBoxCoder
from .centerpoint_bbox_coders import CenterPointBBoxCoder from .centerpoint_bbox_coders import CenterPointBBoxCoder
from .delta_xyzwhlr_bbox_coder import DeltaXYZWLHRBBoxCoder from .delta_xyzwhlr_bbox_coder import DeltaXYZWLHRBBoxCoder
...@@ -12,7 +11,7 @@ from .point_xyzwhlr_bbox_coder import PointXYZWHLRBBoxCoder ...@@ -12,7 +11,7 @@ from .point_xyzwhlr_bbox_coder import PointXYZWHLRBBoxCoder
from .smoke_bbox_coder import SMOKECoder from .smoke_bbox_coder import SMOKECoder
__all__ = [ __all__ = [
'build_bbox_coder', 'DeltaXYZWLHRBBoxCoder', 'PartialBinBasedBBoxCoder', 'DeltaXYZWLHRBBoxCoder', 'PartialBinBasedBBoxCoder',
'CenterPointBBoxCoder', 'AnchorFreeBBoxCoder', 'GroupFree3DBBoxCoder', 'CenterPointBBoxCoder', 'AnchorFreeBBoxCoder', 'GroupFree3DBBoxCoder',
'PointXYZWHLRBBoxCoder', 'FCOS3DBBoxCoder', 'PGDBBoxCoder', 'SMOKECoder', 'PointXYZWHLRBBoxCoder', 'FCOS3DBBoxCoder', 'PGDBBoxCoder', 'SMOKECoder',
'MonoFlexCoder' 'MonoFlexCoder'
......
...@@ -2,11 +2,11 @@ ...@@ -2,11 +2,11 @@
import numpy as np import numpy as np
import torch import torch
from mmdet.core.bbox.builder import BBOX_CODERS from mmdet3d.registry import TASK_UTILS
from .partial_bin_based_bbox_coder import PartialBinBasedBBoxCoder from .partial_bin_based_bbox_coder import PartialBinBasedBBoxCoder
@BBOX_CODERS.register_module() @TASK_UTILS.register_module()
class AnchorFreeBBoxCoder(PartialBinBasedBBoxCoder): class AnchorFreeBBoxCoder(PartialBinBasedBBoxCoder):
"""Anchor free bbox coder for 3D boxes. """Anchor free bbox coder for 3D boxes.
......
# Copyright (c) OpenMMLab. All rights reserved. # Copyright (c) OpenMMLab. All rights reserved.
import torch import torch
from mmdet3d.registry import TASK_UTILS
from mmdet.core.bbox import BaseBBoxCoder from mmdet.core.bbox import BaseBBoxCoder
from mmdet.core.bbox.builder import BBOX_CODERS
@BBOX_CODERS.register_module() @TASK_UTILS.register_module()
class CenterPointBBoxCoder(BaseBBoxCoder): class CenterPointBBoxCoder(BaseBBoxCoder):
"""Bbox coder for CenterPoint. """Bbox coder for CenterPoint.
......
# Copyright (c) OpenMMLab. All rights reserved. # Copyright (c) OpenMMLab. All rights reserved.
import torch import torch
from mmdet3d.registry import TASK_UTILS
from mmdet.core.bbox import BaseBBoxCoder from mmdet.core.bbox import BaseBBoxCoder
from mmdet.core.bbox.builder import BBOX_CODERS
@BBOX_CODERS.register_module() @TASK_UTILS.register_module()
class DeltaXYZWLHRBBoxCoder(BaseBBoxCoder): class DeltaXYZWLHRBBoxCoder(BaseBBoxCoder):
"""Bbox Coder for 3D boxes. """Bbox Coder for 3D boxes.
......
...@@ -2,12 +2,12 @@ ...@@ -2,12 +2,12 @@
import numpy as np import numpy as np
import torch import torch
from mmdet3d.registry import TASK_UTILS
from mmdet.core.bbox import BaseBBoxCoder from mmdet.core.bbox import BaseBBoxCoder
from mmdet.core.bbox.builder import BBOX_CODERS
from ..structures import limit_period from ..structures import limit_period
@BBOX_CODERS.register_module() @TASK_UTILS.register_module()
class FCOS3DBBoxCoder(BaseBBoxCoder): class FCOS3DBBoxCoder(BaseBBoxCoder):
"""Bounding box coder for FCOS3D. """Bounding box coder for FCOS3D.
......
...@@ -2,11 +2,11 @@ ...@@ -2,11 +2,11 @@
import numpy as np import numpy as np
import torch import torch
from mmdet.core.bbox.builder import BBOX_CODERS from mmdet3d.registry import TASK_UTILS
from .partial_bin_based_bbox_coder import PartialBinBasedBBoxCoder from .partial_bin_based_bbox_coder import PartialBinBasedBBoxCoder
@BBOX_CODERS.register_module() @TASK_UTILS.register_module()
class GroupFree3DBBoxCoder(PartialBinBasedBBoxCoder): class GroupFree3DBBoxCoder(PartialBinBasedBBoxCoder):
"""Modified partial bin based bbox coder for GroupFree3D. """Modified partial bin based bbox coder for GroupFree3D.
......
...@@ -3,11 +3,11 @@ import numpy as np ...@@ -3,11 +3,11 @@ import numpy as np
import torch import torch
from torch.nn import functional as F from torch.nn import functional as F
from mmdet3d.registry import TASK_UTILS
from mmdet.core.bbox import BaseBBoxCoder from mmdet.core.bbox import BaseBBoxCoder
from mmdet.core.bbox.builder import BBOX_CODERS
@BBOX_CODERS.register_module() @TASK_UTILS.register_module()
class MonoFlexCoder(BaseBBoxCoder): class MonoFlexCoder(BaseBBoxCoder):
"""Bbox Coder for MonoFlex. """Bbox Coder for MonoFlex.
......
...@@ -2,11 +2,11 @@ ...@@ -2,11 +2,11 @@
import numpy as np import numpy as np
import torch import torch
from mmdet3d.registry import TASK_UTILS
from mmdet.core.bbox import BaseBBoxCoder from mmdet.core.bbox import BaseBBoxCoder
from mmdet.core.bbox.builder import BBOX_CODERS
@BBOX_CODERS.register_module() @TASK_UTILS.register_module()
class PartialBinBasedBBoxCoder(BaseBBoxCoder): class PartialBinBasedBBoxCoder(BaseBBoxCoder):
"""Partial bin based bbox coder. """Partial bin based bbox coder.
......
...@@ -3,11 +3,11 @@ import numpy as np ...@@ -3,11 +3,11 @@ import numpy as np
import torch import torch
from torch.nn import functional as F from torch.nn import functional as F
from mmdet.core.bbox.builder import BBOX_CODERS from mmdet3d.registry import TASK_UTILS
from .fcos3d_bbox_coder import FCOS3DBBoxCoder from .fcos3d_bbox_coder import FCOS3DBBoxCoder
@BBOX_CODERS.register_module() @TASK_UTILS.register_module()
class PGDBBoxCoder(FCOS3DBBoxCoder): class PGDBBoxCoder(FCOS3DBBoxCoder):
"""Bounding box coder for PGD.""" """Bounding box coder for PGD."""
......
...@@ -2,11 +2,11 @@ ...@@ -2,11 +2,11 @@
import numpy as np import numpy as np
import torch import torch
from mmdet3d.registry import TASK_UTILS
from mmdet.core.bbox import BaseBBoxCoder from mmdet.core.bbox import BaseBBoxCoder
from mmdet.core.bbox.builder import BBOX_CODERS
@BBOX_CODERS.register_module() @TASK_UTILS.register_module()
class PointXYZWHLRBBoxCoder(BaseBBoxCoder): class PointXYZWHLRBBoxCoder(BaseBBoxCoder):
"""Point based bbox coder for 3D boxes. """Point based bbox coder for 3D boxes.
......
...@@ -2,11 +2,11 @@ ...@@ -2,11 +2,11 @@
import numpy as np import numpy as np
import torch import torch
from mmdet3d.registry import TASK_UTILS
from mmdet.core.bbox import BaseBBoxCoder from mmdet.core.bbox import BaseBBoxCoder
from mmdet.core.bbox.builder import BBOX_CODERS
@BBOX_CODERS.register_module() @TASK_UTILS.register_module()
class SMOKECoder(BaseBBoxCoder): class SMOKECoder(BaseBBoxCoder):
"""Bbox Coder for SMOKE. """Bbox Coder for SMOKE.
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment