반응형
Data Flow
Structures
Models
Datasets
Data Transforms
- 데이터 변환 파이프라인 설계하기
- 예시
# 학습 파이프라인
train_pipeline = [
dict(type='LoadImageFromFile', backend_args=backend_args), # 파일에서 이미지 불러오기
dict(
type='LoadAnnotations', # 현재 이미지에 맞는 annotation 불러오기
with_bbox=True),
dict(
type='Resize', # 이미지와 annotation 사이즈 변경
scale=(1333, 800),
keep_ratio=True
),
dict(
type='RandomFlip', # 이미지와 annotation 랜덤으로 뒤집기
prob=0.5),
dict(type='PackDetInputs') # annotation 데이터와 데이터의 키 값을 data_sample로 묶음
]
# 테스트 파이프라인
test_pipeline = [
dict(type='LoadImageFromFile', backend_args=backend_args),
dict(type='Resize', scale=(1333, 800), keep_ratio=True),
dict(
type='PackDetInputs',
meta_keys=('img_id', 'img_path', 'ori_shape', 'img_shape',
'scale_factor'))
]
Evaluation
Engine
Conventions
- OpenMMLab2.0은 OpenCV의 입력인자와 함께 구성되어 (width, height) 순서.
- 반대로 데이터 파이프라인과 모델을 거치는 경우 (height, width)
- img_shape: (height, width)
- ori_shape: (height, width)
- pad_shape: (height, width)
- batch_input_shape: (height, width)
- 예시
@TRANSFORMS.register_module()
class Mosaic(BaseTransform):
def __init__(self,
img_scale: Tuple[int, int] = (640, 640),
center_ratio_range: Tuple[float, float] = (0.5, 1.5),
bbox_clip_border: bool = True,
pad_val: float = 114.0,
prob: float = 1.0) -> None:
...
# img_scale 순서는 (width, height)이여야 함
self.img_scale = img_scale
def transform(self, results: dict) -> dict:
...
results['img'] = mosaic_img
# 이곳에서 순서는 (height, width)
results['img_shape'] = mosaic_img.shape[:2]
- Loss의 경우 model과정을 거쳐 loss와 metric을 dict형태로 반환
- 예시: bbox_head.loss()는 'loss_bbox', 'loss_cls', 'acc'를 포함한 경과를 반환
- loss를 포함함 값만 역전파에 사용됨. BaseDetector.train_step()수정으로 변경 가능
class BBoxHead(nn.Module):
...
def loss(self, ...):
losses = dict()
# classification loss
losses['loss_cls'] = self.loss_cls(...)
# classification accuracy
losses['acc'] = accuracy(...)
# bbox regression loss
losses['loss_bbox'] = self.loss_bbox(...)
return losses
- empty proposals: 2-stage에서 empty proposal에 대한 처리를 추가, 전체 배치와 단일 이미지의 empty proposal에 대해 동시에 처리 필요
- 예시: CascadeRoIHead
# simple_test method
...
# There is no proposal in the whole batch
if rois.shape[0] == 0:
bbox_results = [[
np.zeros((0, 5), dtype=np.float32)
for _ in range(self.bbox_head[-1].num_classes)
]] * num_imgs
if self.with_mask:
mask_classes = self.mask_head[-1].num_classes
segm_results = [[[] for _ in range(mask_classes)]
for _ in range(num_imgs)]
results = list(zip(bbox_results, segm_results))
else:
results = bbox_results
return results
...
# There is no proposal in the single image
for i in range(self.num_stages):
...
if i < self.num_stages - 1:
for j in range(num_imgs):
# Handle empty proposal
if rois[j].shape[0] > 0:
bbox_label = cls_score[j][:, :-1].argmax(dim=1)
refine_roi = self.bbox_head[i].regress_by_class(
rois[j], bbox_label, bbox_pred[j], img_metas[j])
refine_roi_list.append(refine_roi)
- Coco Panoptic Dataset: foreground와 backbround 레이블의 범위 확인 필요
반응형
'OpenMMLab(미공개) > MMDetection' 카테고리의 다른 글
[MMDetection] Train & Test - Configs (0) | 2024.01.13 |
---|---|
[MMDetection] Customization - Models (0) | 2024.01.13 |
[MMDetection] 환경설정 (0) | 2024.01.13 |
[MMDetection] 개요 (0) | 2024.01.13 |