Skip to content

mmsegmentation 사용법 #4

@ed-kyu

Description

@ed-kyu

일단 해보는 중인데, 해본 데까지 적어놓겠습니다.

그냥 다운로드해서 돌리게 되면, 버전 오류같은 게 발생합니다. (mmcv관련) mmcv 버전을 조정하면, 다른 곳에서 다시 버전 오류가 납니다. 따라서, 신규범님이 올려주신 글(생생정보tip 글)을 참고해서, cudatoolkit 버전을 바꾸고, 바꾼 cuda 버전으로 pytorch, mmcv를 다운받았습니다.

<참고 글>

mmseg 공식 github https://github.com/open-mmlab/mmsegmentation/blob/master/docs/en/get_started.md#installation

신규범님 글 https://kyubumshin.github.io/2022/04/23/tip/conda-cuda-설치/

  1. conda 환경 설정 가상환경 사용 안하면 실수로 cuda 날릴 수도 있다고 합니다.

    conda create -n open-mmlab python=3.10 -y
    conda activate open-mmlab
  2. 신규범님 글 참고, cuda 버전 변경

저는 11.3으로 했습니다.

conda config --append channels conda-forge
conda install cudatoolkit=11.3 -c conda-forge
conda install cudatoolkit-dev=11.3 -c conda-forge
  1. cudatoolkit 버전에 맞는 pytorch, mmcv 설치
conda install pytorch=1.11.0 torchvision cudatoolkit=11.3 -c pytorch
pip install mmcv-full -f https://download.openmmlab.com/mmcv/dist/cu113/torch1.11/index.html
  1. mmsegmentation 설치

    git clone https://github.com/open-mmlab/mmsegmentation.git
    cd mmsegmentation
    pip install -e .

학습은 mmdetection과 마찬가지로,

mmseg 디렉토리 안에서 다음과 같이 실행하면 됩니다.

python tools/train.py [학습 모델 path]

Coco format 활용하는 법

(현재 잘 모르겠는 것들)

palette?

해야할 것들이 조금 있습니다. 디렉토리를 새로 분류해줘야 합니다. (파일 복사해서 새로운 디렉토리 구조로 만듬)

디렉토리 구조는 다음과 같습니다.

data_dir - annotations - train/valid

data_dir - images - train/valid/test

추후 들어갈 학습 이미지, annotation 구조, 디렉토리명은 수정해서 쓰셔도 됩니다.

  1. 새로운 폴더에 파일을 복사

    baseline 코드 내에서 실행했습니다. 코드에서, dataloader 부분

    batch_size = 1
    train_loader = torch.utils.data.DataLoader(dataset=train_dataset, 
                                               batch_size=batch_size,
                                               shuffle=True,
                                               num_workers=4,
                                               collate_fn=collate_fn)
    
    val_loader = torch.utils.data.DataLoader(dataset=val_dataset, 
                                             batch_size=batch_size,
                                             shuffle=False,
                                             num_workers=4,
                                             collate_fn=collate_fn)
    
    test_loader = torch.utils.data.DataLoader(dataset=test_dataset,
                                              batch_size=batch_size,
                                              num_workers=4,
                                              collate_fn=collate_fn)

    이 코드 이후에 실행했습니다.

    a. annotations 폴더에 파일 만들기

    # annotation 폴더 만들기
    # data_dir 편한대로 수정
    data_dir = '/opt/ml/input/mmseg'
    annotation_dir = os.path.join(data_dir, 'annotations')
    for path in ['train', 'valid']:
        os.makedirs(os.path.join(annotation_dir, path), exist_ok=True)
    for idx, (imgs, masks, image_infos) in enumerate(train_loader):
        image_infos = image_infos[0]
        # annotation을 image_id로 저장합니다.
        file_dir = f"{annotation_dir}/train/{image_infos['id']:04}.png"
    
        masks = masks[0].numpy()
        
        cv2.imwrite(file_dir, masks)
    for idx, (imgs, masks, image_infos) in enumerate(val_loader):
        image_infos = image_infos[0]
        # annotation을 image_id로 저장합니다.
        file_dir = f"{annotation_dir}/valid/{image_infos['id']:04}.png"
    
        masks = masks[0].numpy()
        
        cv2.imwrite(file_dir, masks)

    b. images 폴더에 파일 복사하기

    import os
    import json
    import shutil
    
    # kfold, json 위치는 적절하게 수정해서 사용
    DATA_ROOT = "/opt/ml/input/data"
    TRAIN_JSON = os.path.join(DATA_ROOT, "stratified_kfold/cv_train_1.json")
    VALID_JSON = os.path.join(DATA_ROOT, "stratified_kfold/cv_val_1.json")
    TEST_JSON = os.path.join(DATA_ROOT, "test.json")
    def make(json, path):
        imagePath = f'{data_dir}/images/' + path
    
        os.makedirs(imagePath, exist_ok=True)
        rename_images(json, imagePath)
    
    def rename_images(json_dir, image_dir):
        with open(json_dir, "r", encoding="utf8") as outfile:
            json_data = json.load(outfile)
        image_datas = json_data["images"]
    
    		# 이미지를 image_id 기준으로 새로 저장
        for image_data in image_datas:
            shutil.copyfile(os.path.join(DATA_ROOT, image_data['file_name']), os.path.join(image_dir,f"{image_data['id']:04}.jpg"))
    make(TRAIN_JSON, 'train')
    make(VALID_JSON, 'valid')
    make(TEST_JSON, 'test')
  2. configs 폴더 안에 base 폴더 구조처럼 datasets, models, schedules 폴더를 만들고,

    default_runtime.py도 복사합니다.

    • datasets

      • 새로운 파일 하나 생성 (3번 설명으로 이어짐)
    • models

      • 사용할 모델 복사파일에서 필요한 모델이 들어있어야 합니다.
    • schedules

      • 저는 새로 하나 만들어줬습니다. mmdetection에서 사용한 값을 그냥 가져왔습니다.
      lr = 1e-4 / 2 
      optimizer = dict(type='AdamW', lr=lr, weight_decay=0.01)
      optimizer_config = dict(grad_clip=dict(max_norm=10, norm_type=2))
      # lr_config = dict(
      #     policy='CosineAnnealing',
      #     warmup='linear',
      #     warmup_iters=300,
      #     warmup_ratio=1.0 / 10,
      #     min_lr_ratio=7e-6)
      lr_config = dict(
          policy='step',
          warmup='linear',
          warmup_iters=500,
          warmup_ratio=0.001,
          step=[8, 11])
      # runtime settings
      runner = dict(type='EpochBasedRunner', max_epochs=100)
      checkpoint_config = dict(interval=10)
      # best mIoU로 저장
      evaluation = dict(interval=1, metric='mIoU', save_best='mIoU', classwise=True)
    • default_runtime.py

    • 사용할 모델 복사파일

  3. datasets 폴더안에 새로운 파일을 하나 만듭니다. 파일이름은 편하신대로 지으시면 됩니다.

    • data_root 는 새로 저장할 데이터들의 상위 디렉토리로 설정하시면 됩니다. 현재 코드에서는 mmseg 폴더 안에 annotations와 images 폴더가 있고, 각각 annotations 폴더에는 train, valid 폴더가, images 폴더에는 train, valid, test 폴더가 있습니다.
    # dataset settings
    dataset_type = 'CustomDataset'
    data_root = '/opt/ml/input/mmseg/'
    
    # class settings
    classes = ['Background', 'General trash', 'Paper', 'Paper pack', 'Metal', 'Glass', 'Plastic','Styrofoam', 'Plastic bag', 'Battery', 'Clothing']
    palette = [
        [0, 0, 0],
        [192, 0, 128], [0, 128, 192], [0, 128, 64],
        [128, 0, 0], [64, 0, 128], [64, 0, 192],
        [192, 128, 64], [192, 192, 128], [64, 64, 128], [128, 0, 192]
        ]
    
    # set normalize value
    img_norm_cfg = dict(
        mean=[123.675, 116.28, 103.53], std=[58.395, 57.12, 57.375], to_rgb=True)
    crop_size = (512, 512)
    train_pipeline = [
        dict(type='LoadImageFromFile'),
        dict(type='LoadAnnotations'),
        dict(type='Resize', img_scale=(512, 512), ratio_range=(0.5, 2.0)),
        dict(type='RandomCrop', crop_size=crop_size, cat_max_ratio=0.75),
        dict(type='RandomFlip', prob=0.5),
        dict(type='PhotoMetricDistortion'),
        dict(type='Normalize', **img_norm_cfg),
        dict(type='Pad', size=crop_size, pad_val=0, seg_pad_val=255),
        dict(type='DefaultFormatBundle'),
        dict(type='Collect', keys=['img', 'gt_semantic_seg']),
    ]
    valid_pipeline = [
        dict(type='LoadImageFromFile'),
        dict(
            type='MultiScaleFlipAug',
            img_scale=(512, 512),
            flip=False,
            transforms=[
                dict(type='Resize', keep_ratio=True),
                dict(type='RandomFlip'),
                dict(type='Normalize', **img_norm_cfg),
                dict(type='ImageToTensor', keys=['img']),
                dict(type='Collect', keys=['img']),
            ])
    ]
    test_pipeline = [
        dict(type='LoadImageFromFile'),
        dict(
            type='MultiScaleFlipAug',
            img_scale=(512, 512),
            flip=False,
            flip_direction=['horizontal', 'vertical'],
            transforms=[
                dict(type='Resize', keep_ratio=True),
                dict(type='RandomFlip'),
                dict(type='Normalize', **img_norm_cfg),
                dict(type='ImageToTensor', keys=['img']),
                dict(type='Collect', keys=['img']),
            ])
    ]
    data = dict(
        samples_per_gpu=16,
        workers_per_gpu=8,
        train=dict(
            classes=classes,
            palette=palette,
            type=dataset_type,
            reduce_zero_label=False, 
            img_dir=data_root + "images/train",
            ann_dir=data_root + "annotations/train",
            pipeline=train_pipeline),
        val=dict(
            classes=classes,
            palette=palette,
            type=dataset_type,
            reduce_zero_label=False, 
            img_dir=data_root + "images/valid",
            ann_dir=data_root + "annotations/valid",
            pipeline=valid_pipeline),
        test=dict(
            classes=classes,
            palette=palette,
            type=dataset_type,
            reduce_zero_label=False, 
            img_dir=data_root + "images/test",
            pipeline=test_pipeline))
  4. mmsegmentation 디렉토리 안에서

    python tools/train.py [학습 모델 path]

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions