ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 01. MMDetection(object detection) 시작하기
    Object-Detection 2024. 5. 13. 16:49
    반응형

    mmdetection은 오픈소스 객체 감지 툴박스로, 주로 컴퓨터 비전 연구와 응용 프로그램 개발에 사용됩니다.

    이 툴박스는 PyTorch 기반으로 구축되었으며, 다양한 객체 감지 모델과 알고리즘을 쉽게 구현할 수 있도록 설계되었습니다.

    mmdetection은 모듈화가 잘 되어 있어서 사용자가 다양한 구성요소를 쉽게 교체하거나 업그레이드할 수 있습니다.

    mmdetection에서는 주로 네 가지 주요 구성 요소를 사용합니다: Backbone, Neck, Head, Loss. 각각의 구성 요소는 다음과 같은 역할을 합니다:

    1. Backbone:
      • 이는 모델의 기본적인 구조로, 입력 이미지에서 고수준의 특징을 추출하는 역할을 합니다. 일반적으로 사용되는 backbone에는 ResNet, VGG, MobileNet 등이 있습니다.
      • 예: ResNet-50은 깊이가 50층인 Residual Networks로, 각 층에서의 학습을 용이하게 하기 위해 skip connection을 사용합니다.
    2. Neck:
      • Neck은 backbone에서 추출된 특징을 다듬고, 다양한 스케일의 특징들을 조합하여 더 유용한 특징 정보를 생성하는 역할을 합니다. 예를 들어, FPN(Feature Pyramid Network)은 다양한 해상도에서 특징을 통합하여 각각의 해상도에서 객체를 효과적으로 감지할 수 있게 돕습니다.
      • 예: FPN은 여러 스케일의 특징 맵을 상하로 연결하여 객체의 크기가 다양할 때도 효과적인 감지가 가능하게 합니다.
    3. Head:
      • Head는 최종적인 감지 목표를 달성하기 위해 특징 맵을 사용합니다. 이는 분류(classification), 회귀(regression), 객체 경계 상자 예측 등을 수행할 수 있습니다. 예를 들어, Faster R-CNN에서는 RPN(Region Proposal Network)과 RoI(Region of Interest) head를 사용합니다.
      • 예: RPN은 객체가 있을 법한 위치의 경계 상자를 제안하고, RoI head는 이 상자들을 기반으로 객체의 클래스와 정확한 위치를 예측합니다.
    4. Loss:
      • Loss 함수는 모델의 예측이 실제 값과 얼마나 잘 일치하는지를 측정합니다. 이를 통해 모델 학습 중에 가중치를 조정하게 됩니다. 각각의 태스크(예: 분류, 경계 상자 회귀 등)에 맞는 손실 함수가 사용됩니다.
      • 예: 분류에는 Cross-Entropy Loss를 사용하고, 경계 상자의 위치 조정에는 Smooth L1 Loss를 사용합니다.

    크게 4개의 모듈로 정의가 가능하고, 구성 요소별로 테스트가 가능한 점이 접근성이 매우 뛰어나 보입니다.

     

    테스트 예제는 RTMDet-l(large)로 진행하게끔 되어 있습니다.

    성능은 YOLO model과 비슷해보이네요.

     

    아키텍쳐는 다음과 같습니다.

     

    4개의 모듈로 구성되어 있습니다.

    이걸 보니깐 정말 vision을 전공하지 않는 이상 모듈을 갈아 끼우는 건 쉬워보이진 않네요.

    아마 다른 누군가가 잘 조합한 구조를 그대로 차용해서, fine-tune을 진행하는게 가장 쉬워보이는 작업이 되겠네요.

     

    전체 튜토리얼 코드는 다음과 같습니다.

    https://github.com/open-mmlab/mmdetection/blob/main/demo/MMDet_Tutorial.ipynb

     

    mmdetection/demo/MMDet_Tutorial.ipynb at main · open-mmlab/mmdetection

    OpenMMLab Detection Toolbox and Benchmark. Contribute to open-mmlab/mmdetection development by creating an account on GitHub.

    github.com

     

     

    모델을 다운받는 코드는 다음과 같습니다.

    # We download the pre-trained checkpoints for inference and finetuning.
    !mkdir ./checkpoints
    !mim download mmdet --config rtmdet_tiny_8xb32-300e_coco --dest ./checkpoints

    mim은 OpenMMLab 프로젝트의 Python 도구입니다.

    pip와 같은 프로그램 같네요.

    rtmdet_tiny_8xb32-300e_coco 이라는 config를 다운받아서 model을 실행시키는 구조입니다.

     

    모델의 크기가 55메가밖에 안되다니... 놀랍네요.

    LLM은 못해도 8B짜리 모델을 4비트로 줄여도 5~6GB인데...

     

    파일 구조를 보면 일반적인 python 실행 방식과 조금 다른 점을 발견할 수 있습니다.

    모든 실행 코드를 python script에 config 방식으로 넣어서 실행한다는 점이 특이하네요.

     

    파일을 열어보면 config의 형태를 python의 Dictionary로 설정해주고 있네요.

    model 예시

    model = dict(
        backbone=dict(
            act_cfg=dict(inplace=True, type='SiLU'),
            arch='P5',
            channel_attention=True,
            deepen_factor=0.167,
            expand_ratio=0.5,
            init_cfg=dict(
                checkpoint=
                'https://download.openmmlab.com/mmdetection/v3.0/rtmdet/cspnext_rsb_pretrain/cspnext-tiny_imagenet_600e.pth',
                prefix='backbone.',
                type='Pretrained'),
            norm_cfg=dict(type='SyncBN'),
            type='CSPNeXt',
            widen_factor=0.375),
        neck=dict(
            act_cfg=dict(inplace=True, type='SiLU'),
            expand_ratio=0.5,
            in_channels=[
                96,
                192,
                384,
            ],
            norm_cfg=dict(type='SyncBN'),
            num_csp_blocks=1,
            out_channels=96,
            type='CSPNeXtPAFPN'),
        bbox_head=dict(
            act_cfg=dict(inplace=True, type='SiLU'),
            anchor_generator=dict(
                offset=0, strides=[
                    8,
                    16,
                    32,
                ], type='MlvlPointGenerator'),
            bbox_coder=dict(type='DistancePointBBoxCoder'),
            exp_on_reg=False,
            feat_channels=96,
            in_channels=96,
            loss_bbox=dict(loss_weight=2.0, type='GIoULoss'),
            loss_cls=dict(
                beta=2.0,
                loss_weight=1.0,
                type='QualityFocalLoss',
                use_sigmoid=True),
            norm_cfg=dict(type='SyncBN'),
            num_classes=80,
            pred_kernel_size=1,
            share_conv=True,
            stacked_convs=2,
            type='RTMDetSepBNHead',
            with_objectness=False),
        type='RTMDet')

     

    이해가 되기 쉽게 조금 수정한 코드입니다.

     

    위에 설명한 아키텍쳐와 완전한 동일한 형태로 설정을 진행합니다.

    Backbone, Neck, Head 정확하게 3개의 모듈을 넣어서 하나의 모델링을 하는 방식이네요.

    우리가 주의 깊게 봐야할 점은 type key에 들어가는 value 같습니다.

    나머지 하이퍼 파라미터들은 대부분 설정하란대로 하면 될 것이고,

    type은 사실상 python의 Class Name으로 진행합니다.

     

    이렇게 설정을 해놓고서 다음과 같은 API에 담아서 실행하는 구조입니다.

    from mmdet.apis import DetInferencer
    
    # Choose to use a config
    model_name = 'rtmdet_tiny_8xb32-300e_coco'
    # Setup a checkpoint file to load
    checkpoint = './checkpoints/rtmdet_tiny_8xb32-300e_coco_20220902_112414-78e30dcc.pth'
    
    # Set the device to be used for evaluation
    device = 'cuda:0'
    
    # Initialize the DetInferencer
    inferencer = DetInferencer(model_name, checkpoint, device)
    
    # Use the detector to do inference
    img = './demo/demo.jpg'
    result = inferencer(img, out_dir='./output')

     

    model_name은 위에서 다운로드 받은 모델이고, checkpoints는 가중치, device 번호만 설정 후

    DetInferencer를 인스턴스 받아서 calling하면서 저장하는 방식입니다.

     

    Vision은 Yolo v3 이후엔 해본 적이 없었는데, 다시 해보니 너무 재밌네요!

    다음엔 COCO Dataset에 대해서 알아보고, Fine-tuning까지 진행하면 되겠네요.

    반응형
Designed by Tistory.