Unverified Commit e4857216 authored by Yuefeng Wu's avatar Yuefeng Wu Committed by GitHub
Browse files

[Fix]: fix multi-batch test problem (#95)

* update bbox_results to support multi-batches test and fix ci problem in test_part_aggregation_ROI_head

* compress test samples in test_parta2_roi_head

* compress test samples

* fix multi-batch bug

* fix multi-batch bug

* fix multi-batch bug

* fix mvxnet test

* fix mvxnet test

* multi batch test

* multi batch test

* multi batch test
parent cccbaf7a
...@@ -31,7 +31,7 @@ def single_gpu_test(model, data_loader, show=False, out_dir=None): ...@@ -31,7 +31,7 @@ def single_gpu_test(model, data_loader, show=False, out_dir=None):
if show: if show:
model.module.show_results(data, result, out_dir) model.module.show_results(data, result, out_dir)
results.append(result) results.extend(result)
batch_size = len(data['img_metas'][0].data) batch_size = len(data['img_metas'][0].data)
for _ in range(batch_size): for _ in range(batch_size):
......
...@@ -35,9 +35,6 @@ class Base3DDetector(BaseDetector): ...@@ -35,9 +35,6 @@ class Base3DDetector(BaseDetector):
raise ValueError( raise ValueError(
'num of augmentations ({}) != num of image meta ({})'.format( 'num of augmentations ({}) != num of image meta ({})'.format(
len(points), len(img_metas))) len(points), len(img_metas)))
# TODO: remove the restriction of imgs_per_gpu == 1 when prepared
samples_per_gpu = len(points[0])
assert samples_per_gpu == 1
if num_augs == 1: if num_augs == 1:
img = [img] if img is None else img img = [img] if img is None else img
......
...@@ -163,7 +163,7 @@ class H3DNet(TwoStage3DDetector): ...@@ -163,7 +163,7 @@ class H3DNet(TwoStage3DDetector):
merged_bboxes = merge_aug_bboxes_3d(aug_bboxes, img_metas, merged_bboxes = merge_aug_bboxes_3d(aug_bboxes, img_metas,
self.bbox_head.test_cfg) self.bbox_head.test_cfg)
return merged_bboxes return [merged_bboxes]
def extract_feats(self, points, img_metas): def extract_feats(self, points, img_metas):
"""Extract features of multiple samples.""" """Extract features of multiple samples."""
......
...@@ -389,22 +389,24 @@ class MVXTwoStageDetector(Base3DDetector): ...@@ -389,22 +389,24 @@ class MVXTwoStageDetector(Base3DDetector):
bbox3d2result(bboxes, scores, labels) bbox3d2result(bboxes, scores, labels)
for bboxes, scores, labels in bbox_list for bboxes, scores, labels in bbox_list
] ]
return bbox_results[0] return bbox_results
def simple_test(self, points, img_metas, img=None, rescale=False): def simple_test(self, points, img_metas, img=None, rescale=False):
"""Test function without augmentaiton.""" """Test function without augmentaiton."""
img_feats, pts_feats = self.extract_feat( img_feats, pts_feats = self.extract_feat(
points, img=img, img_metas=img_metas) points, img=img, img_metas=img_metas)
bbox_list = dict() bbox_list = [dict() for i in range(len(img_metas))]
if pts_feats and self.with_pts_bbox: if pts_feats and self.with_pts_bbox:
bbox_pts = self.simple_test_pts( bbox_pts = self.simple_test_pts(
pts_feats, img_metas, rescale=rescale) pts_feats, img_metas, rescale=rescale)
bbox_list.update(pts_bbox=bbox_pts) for result_dict, pts_bbox in zip(bbox_list, bbox_pts):
result_dict['pts_bbox'] = pts_bbox
if img_feats and self.with_img_bbox: if img_feats and self.with_img_bbox:
bbox_img = self.simple_test_img( bbox_img = self.simple_test_img(
img_feats, img_metas, rescale=rescale) img_feats, img_metas, rescale=rescale)
bbox_list.update(img_bbox=bbox_img) for result_dict, img_bbox in zip(bbox_list, bbox_img):
result_dict['img_bbox'] = img_bbox
return bbox_list return bbox_list
def aug_test(self, points, img_metas, imgs=None, rescale=False): def aug_test(self, points, img_metas, imgs=None, rescale=False):
...@@ -415,7 +417,7 @@ class MVXTwoStageDetector(Base3DDetector): ...@@ -415,7 +417,7 @@ class MVXTwoStageDetector(Base3DDetector):
if pts_feats and self.with_pts_bbox: if pts_feats and self.with_pts_bbox:
bbox_pts = self.aug_test_pts(pts_feats, img_metas, rescale) bbox_pts = self.aug_test_pts(pts_feats, img_metas, rescale)
bbox_list.update(pts_bbox=bbox_pts) bbox_list.update(pts_bbox=bbox_pts)
return bbox_list return [bbox_list]
def extract_feats(self, points, img_metas, imgs=None): def extract_feats(self, points, img_metas, imgs=None):
"""Extract point and image features of multiple samples.""" """Extract point and image features of multiple samples."""
......
...@@ -81,7 +81,7 @@ class VoteNet(SingleStage3DDetector): ...@@ -81,7 +81,7 @@ class VoteNet(SingleStage3DDetector):
bbox3d2result(bboxes, scores, labels) bbox3d2result(bboxes, scores, labels)
for bboxes, scores, labels in bbox_list for bboxes, scores, labels in bbox_list
] ]
return bbox_results[0] return bbox_results
def aug_test(self, points, img_metas, imgs=None, rescale=False): def aug_test(self, points, img_metas, imgs=None, rescale=False):
"""Test with augmentation.""" """Test with augmentation."""
...@@ -104,4 +104,4 @@ class VoteNet(SingleStage3DDetector): ...@@ -104,4 +104,4 @@ class VoteNet(SingleStage3DDetector):
merged_bboxes = merge_aug_bboxes_3d(aug_bboxes, img_metas, merged_bboxes = merge_aug_bboxes_3d(aug_bboxes, img_metas,
self.bbox_head.test_cfg) self.bbox_head.test_cfg)
return merged_bboxes return [merged_bboxes]
...@@ -101,7 +101,7 @@ class VoxelNet(SingleStage3DDetector): ...@@ -101,7 +101,7 @@ class VoxelNet(SingleStage3DDetector):
bbox3d2result(bboxes, scores, labels) bbox3d2result(bboxes, scores, labels)
for bboxes, scores, labels in bbox_list for bboxes, scores, labels in bbox_list
] ]
return bbox_results[0] return bbox_results
def aug_test(self, points, img_metas, imgs=None, rescale=False): def aug_test(self, points, img_metas, imgs=None, rescale=False):
"""Test function with augmentaiton.""" """Test function with augmentaiton."""
...@@ -123,4 +123,4 @@ class VoxelNet(SingleStage3DDetector): ...@@ -123,4 +123,4 @@ class VoxelNet(SingleStage3DDetector):
merged_bboxes = merge_aug_bboxes_3d(aug_bboxes, img_metas, merged_bboxes = merge_aug_bboxes_3d(aug_bboxes, img_metas,
self.bbox_head.test_cfg) self.bbox_head.test_cfg)
return merged_bboxes return [merged_bboxes]
...@@ -155,4 +155,4 @@ class H3DRoIHead(Base3DRoIHead): ...@@ -155,4 +155,4 @@ class H3DRoIHead(Base3DRoIHead):
bbox3d2result(bboxes, scores, labels) bbox3d2result(bboxes, scores, labels)
for bboxes, scores, labels in bbox_list for bboxes, scores, labels in bbox_list
] ]
return bbox_results[0] return bbox_results
...@@ -159,7 +159,7 @@ class PartAggregationROIHead(Base3DRoIHead): ...@@ -159,7 +159,7 @@ class PartAggregationROIHead(Base3DRoIHead):
bbox3d2result(bboxes, scores, labels) bbox3d2result(bboxes, scores, labels)
for bboxes, scores, labels in bbox_list for bboxes, scores, labels in bbox_list
] ]
return bbox_results[0] return bbox_results
def _bbox_forward_train(self, seg_feats, part_feats, voxels_dict, def _bbox_forward_train(self, seg_feats, part_feats, voxels_dict,
sampling_results): sampling_results):
......
...@@ -38,9 +38,9 @@ def test_inference_detector(): ...@@ -38,9 +38,9 @@ def test_inference_detector():
'6x8_160e_kitti-3d-3class.py' '6x8_160e_kitti-3d-3class.py'
detector = init_detector(detector_cfg, device='cpu') detector = init_detector(detector_cfg, device='cpu')
results = inference_detector(detector, pcd) results = inference_detector(detector, pcd)
bboxes_3d = results[0]['boxes_3d'] bboxes_3d = results[0][0]['boxes_3d']
scores_3d = results[0]['scores_3d'] scores_3d = results[0][0]['scores_3d']
labels_3d = results[0]['labels_3d'] labels_3d = results[0][0]['labels_3d']
assert bboxes_3d.tensor.shape[0] >= 0 assert bboxes_3d.tensor.shape[0] >= 0
assert bboxes_3d.tensor.shape[1] == 7 assert bboxes_3d.tensor.shape[1] == 7
assert scores_3d.shape[0] >= 0 assert scores_3d.shape[0] >= 0
......
...@@ -113,9 +113,9 @@ def test_voxel_net(): ...@@ -113,9 +113,9 @@ def test_voxel_net():
# test simple_test # test simple_test
results = self.simple_test(points, img_metas) results = self.simple_test(points, img_metas)
boxes_3d = results['boxes_3d'] boxes_3d = results[0]['boxes_3d']
scores_3d = results['scores_3d'] scores_3d = results[0]['scores_3d']
labels_3d = results['labels_3d'] labels_3d = results[0]['labels_3d']
assert boxes_3d.tensor.shape == (50, 7) assert boxes_3d.tensor.shape == (50, 7)
assert scores_3d.shape == torch.Size([50]) assert scores_3d.shape == torch.Size([50])
assert labels_3d.shape == torch.Size([50]) assert labels_3d.shape == torch.Size([50])
...@@ -155,9 +155,9 @@ def test_vote_net(): ...@@ -155,9 +155,9 @@ def test_vote_net():
# test simple_test # test simple_test
results = self.simple_test(points, img_metas) results = self.simple_test(points, img_metas)
boxes_3d = results['boxes_3d'] boxes_3d = results[0]['boxes_3d']
scores_3d = results['scores_3d'] scores_3d = results[0]['scores_3d']
labels_3d = results['labels_3d'] labels_3d = results[0]['labels_3d']
assert boxes_3d.tensor.shape[0] >= 0 assert boxes_3d.tensor.shape[0] >= 0
assert boxes_3d.tensor.shape[1] == 7 assert boxes_3d.tensor.shape[1] == 7
assert scores_3d.shape[0] >= 0 assert scores_3d.shape[0] >= 0
...@@ -171,8 +171,8 @@ def test_parta2(): ...@@ -171,8 +171,8 @@ def test_parta2():
parta2 = _get_detector_cfg( parta2 = _get_detector_cfg(
'parta2/hv_PartA2_secfpn_2x8_cyclic_80e_kitti-3d-3class.py') 'parta2/hv_PartA2_secfpn_2x8_cyclic_80e_kitti-3d-3class.py')
self = build_detector(parta2).cuda() self = build_detector(parta2).cuda()
points_0 = torch.rand([2000, 4], device='cuda') points_0 = torch.rand([1000, 4], device='cuda')
points_1 = torch.rand([2000, 4], device='cuda') points_1 = torch.rand([1000, 4], device='cuda')
points = [points_0, points_1] points = [points_0, points_1]
img_meta_0 = dict(box_type_3d=LiDARInstance3DBoxes) img_meta_0 = dict(box_type_3d=LiDARInstance3DBoxes)
img_meta_1 = dict(box_type_3d=LiDARInstance3DBoxes) img_meta_1 = dict(box_type_3d=LiDARInstance3DBoxes)
...@@ -197,9 +197,9 @@ def test_parta2(): ...@@ -197,9 +197,9 @@ def test_parta2():
# test_simple_test # test_simple_test
results = self.simple_test(points, img_metas) results = self.simple_test(points, img_metas)
boxes_3d = results['boxes_3d'] boxes_3d = results[0]['boxes_3d']
scores_3d = results['scores_3d'] scores_3d = results[0]['scores_3d']
labels_3d = results['labels_3d'] labels_3d = results[0]['labels_3d']
assert boxes_3d.tensor.shape[0] >= 0 assert boxes_3d.tensor.shape[0] >= 0
assert boxes_3d.tensor.shape[1] == 7 assert boxes_3d.tensor.shape[1] == 7
assert scores_3d.shape[0] >= 0 assert scores_3d.shape[0] >= 0
......
...@@ -372,22 +372,20 @@ def test_part_aggregation_ROI_head(): ...@@ -372,22 +372,20 @@ def test_part_aggregation_ROI_head():
if not torch.cuda.is_available(): if not torch.cuda.is_available():
pytest.skip('test requires GPU and torch+cuda') pytest.skip('test requires GPU and torch+cuda')
_setup_seed(0)
roi_head_cfg = _get_roi_head_cfg( roi_head_cfg = _get_roi_head_cfg(
'parta2/hv_PartA2_secfpn_2x8_cyclic_80e_kitti-3d-3class.py') 'parta2/hv_PartA2_secfpn_2x8_cyclic_80e_kitti-3d-3class.py')
self = build_head(roi_head_cfg).cuda() self = build_head(roi_head_cfg).cuda()
spatial_features = torch.rand([1, 256, 200, 176], device='cuda')
seg_features = torch.rand([32000, 16], device='cuda') features = np.load('./tests/test_samples/parta2_roihead_inputs.npz')
neck_features = [torch.rand([1, 512, 200, 176], device='cuda')] seg_features = torch.tensor(
feats_dict = dict( features['seg_features'], dtype=torch.float32, device='cuda')
spatial_features=spatial_features, feats_dict = dict(seg_features=seg_features)
seg_features=seg_features,
neck_features=neck_features) voxels = torch.tensor(
features['voxels'], dtype=torch.float32, device='cuda')
voxels = torch.rand([32000, 5, 4], device='cuda') num_points = torch.ones([500], device='cuda')
num_points = torch.ones([32000], device='cuda') coors = torch.zeros([500, 4], device='cuda')
coors = torch.zeros([32000, 4], device='cuda') voxel_centers = torch.zeros([500, 3], device='cuda')
voxel_centers = torch.zeros([32000, 3], device='cuda')
box_type_3d = LiDARInstance3DBoxes box_type_3d = LiDARInstance3DBoxes
img_metas = [dict(box_type_3d=box_type_3d)] img_metas = [dict(box_type_3d=box_type_3d)]
voxels_dict = dict( voxels_dict = dict(
...@@ -396,10 +394,27 @@ def test_part_aggregation_ROI_head(): ...@@ -396,10 +394,27 @@ def test_part_aggregation_ROI_head():
coors=coors, coors=coors,
voxel_centers=voxel_centers) voxel_centers=voxel_centers)
pred_bboxes = LiDARInstance3DBoxes(torch.rand([5, 7], device='cuda')) pred_bboxes = LiDARInstance3DBoxes(
pred_scores = torch.rand([5], device='cuda') torch.tensor(
pred_labels = torch.randint(0, 3, [5], device='cuda') [[0.3990, 0.5167, 0.0249, 0.9401, 0.9459, 0.7967, 0.4150],
pred_clses = torch.rand([5, 3], device='cuda') [0.8203, 0.2290, 0.9096, 0.1183, 0.0752, 0.4092, 0.9601],
[0.2093, 0.1940, 0.8909, 0.4387, 0.3570, 0.5454, 0.8299],
[0.2099, 0.7684, 0.4290, 0.2117, 0.6606, 0.1654, 0.4250],
[0.9927, 0.6964, 0.2472, 0.7028, 0.7494, 0.9303, 0.0494]],
dtype=torch.float32,
device='cuda'))
pred_scores = torch.tensor([0.9722, 0.7910, 0.4690, 0.3300, 0.3345],
dtype=torch.float32,
device='cuda')
pred_labels = torch.tensor([0, 1, 0, 2, 1],
dtype=torch.int64,
device='cuda')
pred_clses = torch.tensor(
[[0.7874, 0.1344, 0.2190], [0.8193, 0.6969, 0.7304],
[0.2328, 0.9028, 0.3900], [0.6177, 0.5012, 0.2330],
[0.8985, 0.4894, 0.7152]],
dtype=torch.float32,
device='cuda')
proposal = dict( proposal = dict(
boxes_3d=pred_bboxes, boxes_3d=pred_bboxes,
scores_3d=pred_scores, scores_3d=pred_scores,
...@@ -419,12 +434,12 @@ def test_part_aggregation_ROI_head(): ...@@ -419,12 +434,12 @@ def test_part_aggregation_ROI_head():
bbox_results = self.simple_test(feats_dict, voxels_dict, img_metas, bbox_results = self.simple_test(feats_dict, voxels_dict, img_metas,
proposal_list) proposal_list)
boxes_3d = bbox_results['boxes_3d'] boxes_3d = bbox_results[0]['boxes_3d']
scores_3d = bbox_results['scores_3d'] scores_3d = bbox_results[0]['scores_3d']
labels_3d = bbox_results['labels_3d'] labels_3d = bbox_results[0]['labels_3d']
assert boxes_3d.tensor.shape == (6, 7) assert boxes_3d.tensor.shape == (12, 7)
assert scores_3d.shape == (6, ) assert scores_3d.shape == (12, )
assert labels_3d.shape == (6, ) assert labels_3d.shape == (12, )
def test_free_anchor_3D_head(): def test_free_anchor_3D_head():
......
...@@ -101,11 +101,11 @@ def main(): ...@@ -101,11 +101,11 @@ def main():
set_random_seed(args.seed, deterministic=args.deterministic) set_random_seed(args.seed, deterministic=args.deterministic)
# build the dataloader # build the dataloader
# TODO: support multiple images per gpu (only minor changes are needed) samples_per_gpu = cfg.data.test.pop('samples_per_gpu', 1)
dataset = build_dataset(cfg.data.test) dataset = build_dataset(cfg.data.test)
data_loader = build_dataloader( data_loader = build_dataloader(
dataset, dataset,
samples_per_gpu=1, samples_per_gpu=samples_per_gpu,
workers_per_gpu=cfg.data.workers_per_gpu, workers_per_gpu=cfg.data.workers_per_gpu,
dist=distributed, dist=distributed,
shuffle=False) shuffle=False)
......
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