Category: Python

  • Mask R-CNN 시작하기

    Image classification을 했으니 object detection으로 넘어가야 한다. 가르침을 받을만한 책이 없기 때문에 맨 땅에 헤딩하면서 배우기로 한다. 다행히 PyTorch에서 제공하는 한글 메뉴얼이 있다.

    https://tutorials.pytorch.kr/intermediate/torchvision_tutorial.html

    PennFudan 이라는 데이터셋을 이용한 설명이 있다. Custom 데이터를 이용해야 하므로 mask를 어떻게 구성해야 하는지 파악해 보기로 한다. Colab 코드에서 정보를 좀 얻어보기로 한다.

    https://colab.research.google.com/github/pytorch/vision/blob/temp-tutorial/tutorials/torchvision_finetuning_instance_segmentation.ipynb

    from PIL import Image
    Image.open('PennFudanPed/PNGImages/FudanPed00001.png')

    Jupyter Notebook에서 이 코드를 실행하면 다음의 그림 파일인 것을 알 수 있다.

    그리고 같은 형식의 이름 파일이 mask 인 것 같다.

    mask = Image.open('PennFudanPed/PedMasks/FudanPed00001_mask.png')

    검은색이다. 분명히 정보가 있을 것 같지만 검은색으로 보인다. 익숙한 R을 이용하여 그림 파일을 분석해 보았다.

    library('png')
    a=readPNG('FudanPed00001_mask.png')

    Matrix 형식으로 불러오면 분석이 어려우니까 numeric 으로 변환하여 확인해 본다. 즉, 이 그림 파일은 3개의 값으로만 구성되어 있다.

    unique(as.numeric(a))
    [1] 0.000000000 0.003921569 0.007843137

    좀 더 이해하기 쉽도록 자료를 변경하여 보자.

    unique(as.numeric(a)) * 255
    [1] 0 1 2

    즉, 배경인 0과 1(1/255), 2(2/255)로 표시된 정보임을 알 수 있다. 프로그램의 관점에서는 분명하게 구분되지만 그림 파일 뷰어에서는 그렇게 보이지 않는 그런 것임을 알 수 있다.

    답답해 하지 말고 다음 단계로 넘어가면 될 것 같다.

  • 모델을 학습시킨 후에 평가할 때의 이야기.

    나의 경우에는 데이터를 넣고 그 결과를 받아서 결과 종류에 따라서 이미지 처리하는 것이 달라진다. 이미지 처리하는 과정이 있어, 1개씩 입력하면 편하다. 그래서 그 동안 테스트 자료들을 그렇게 처리했다. 그런데 한 번에 여러개를 처리할 수 없을까 고민을 하다가 결국 해보았다.

    결과 형식이 list(?)로 나오기 때문에 결과 해석에 따른 이미지 처리 과정도 순차적으로 확인하는 과정으로 하였다. 즉, for 문을 이용했다는 이야기이다.

    속도의 차이는 없는 것 같고, GPU 메모리를 좀 더 사용하며, CPU 사용량이 줄어들었다. CPU 사용량이 줄기는 했는데, 패턴(?)이 달라진 것 같다. 전에 방식으로는 0.6 * 6이라는 느낌으로 사용했다면, 이번에는 0.9 + 0.1*5 정도의 느낌으로 사용한다.

  • Scriptable Transforms

    Scriptable Transforms 이 torchvision 0.8에서부터 지원이 된다고 한다. 무엇인지는 모르겠으나 속도가 빨라질 수도 있다기에 내 연구 과제에 적용시켜 보았는데, 오히려 느리다. 사용 방법에 따라서 차이가 존재하는 것 같다.

  • Early Stopping

    PyTorch에서는 별도의 함수로 지정되어 있는 것 같지 않지만, 기본 개념을 알고 있다면 어렵지 않게 직접 구현할 수 있다. R과 마찬가지로 Python에서는 for 반복문에서 중단하는 명령어는 break이다. 기본 제공되는 스크립트에서 best accuracy를 평가하는 부분에 현재 epoch 번호도 저장하도록 변수를 하나 더 지정한다. 그리고 epoch와 관련된 반복문 마지막 부분에 현재 epoch과 best accuracy 때에 epoch 차이를 확인하여 일정 범위를 넘어서면 break가 동작하도록 조건문을 설정한다.

    def train_model(model, criterion, optimizer, epochs):
        ...
        for epoch in range(epochs):
            ...
            if phase == 'val' and epoch_acc > best_acc:
                ...
                best_epoch = epoch
            if (epoch - best_epoch >= 10):
                break