[딥러닝 프로젝트] Medical Imaging 모델 Fine-tuning 고난기: 2주차 차차 정리
Projects/Projects

[딥러닝 프로젝트] Medical Imaging 모델 Fine-tuning 고난기: 2주차 차차 정리

이 글은 필자가 학교 수업 수강중 딥러닝 프로젝트 과제를 하면서 혼자서 파인튜닝을 한 고난기를 적은 여정입니다. 모델 튜닝을 하여 제출하는 과제이기에 제 자신이 한 머릿속 고민들과 아이디어들을 적어보고 싶어 만든 글이라 개념 설명은 따로 하지 않았습니다. 편하게 봐주세요!

완성된 모델 링크입니다.(완벽한 모델은 아니니 개발은 이렇게 진행된다고 감을 잡으시는 용도로 좋을 것 같습니다.)

매일 성능을 작성하였습니다.(Colab PRO를 구매해서 제대로 써보고자 매일 모델을 학습시키고 있습니다.) epoch마다의 학습 중 가장 성능이 뛰어날때/일반화가 잘 되었을 때를 뽑았으며 현재 2주차 진행중입니다.

  • 5/30일 73~84% 과적합
  • 5/31일 68~71%

2주차. 앞서 실험 정리하고 하나로 묶기

  • Data Preprocessing
    • K-fold Cross Validation
    • (R+G+B) 하나의 채널+ HorizontalFlip 그래도
    • CentralCrop 제거 및 모델 구조 조금 수정
    • train_test_split 구현
    • Data Preprocessing: RGB채널 각각이 아닌 한 채널로 처리
    • Data Augmentation: HorizontalFlip
  • 모델 구조 뜯어고치기. 가능하면 FPN을 구현하여 괜찮게 구현하고 싶다.
    • Encoder/Decoder 구조 -> 굳이?라는 생각이 든다. -> Classification task이므로 Encoder 구조만 가능/Decoder 필요 없음
    • Mini-Batch Gradient Descent
    • (더 수정 필요) ResNet 구조
  • Generalization / Regularization
    • L2-Norm 파라미터 추가
    • 추가 옵션) DropOut
    • Epoch 추가
  • Hyper-Parameter(항상 진행중)
    • Learning Rate 조정
    • Batch size 조정
  • 추가 필요!
    • Edge Enhancement -> High-pass filtering
    • Dropout은 Fully Connected Layer으로만 구성

2주차 1. Data Preprocessing

데이터 처리는 앞서 고민했던 내용에서 조금 더 정리해서 다음과 같이 구현해보려고 한다.

  1. (R+G+B) 하나의 채널
  2. HorizontalFlip은 그대로 + CentralCrop 제거
  3. Train_test_split 함수 구현
  4. K-fold Cross Validation

다음과 같은데 각각의 이유를 설명하려 한다. 일단 1번은 그림 자체가 다 흑백이라 굳이 3개의 채널을 할 필요도 없었고 정확도도 현저히 낮았다. 그래서 다시 1개의 채널로 회귀하였다. 2번은 데이터셋 늘리는 거니까 당연히 가만히 냅두었다. 하지만 이번에는 Colab PRO 유저로 CentralCrop을 제거하여 약 44%의 데이터 손실을 줄이려 한다.

epoch=120 환경에서 돌려본 결과 다음과 같다.

# Epoch : 64 / 120 72.0 66.04

epoch=120, 전으로 돌아와서 학습

일단은 전으로 돌아와서 다행이었다. 66~72 정도면 선방했다고 생각한다. 그래서 Train/Validation set 데이터셋을 바꾸고 어느정도 정상화하였다.

몇가지 수정점(Batch size, train_test_split)을 거치고 만들어진 완전한 학습은 다음과 같다.

# Epoch : 100 / 120 71.0 67.92

생각보다 괜찮게 나왔다! validation 셋이 보완이 되지 않는 부분이 learning rate와 연관이 있겠다고 생각이 되어서 learning rate을 0.0005로 수정했다. Batch Size 학습이 이정도면 k-fold cross validation이 정말 도움이 많이 될 것 같다는 생각이 들었다.

# Epoch : 38 / 120 75.5 69.81
# Epoch : 44 / 120 80.67 67.92

앞의 0.0001때를 5배 압축된 시리즈처럼 보인다! 최고치를 경신했지만 0.0001과의 협의점이 필요해보여 0.0002로 설정하였다. weight_decay = 1e-5*5

# Epoch : 88 / 120 84.67 73.58

최고치 달성!

이제 나올대로 나왔으니 K-fold Cross Validation 수행할 일만 남았다. 내일부터는 다른 과제에 매달려야 하니 오늘 간단한 코드라도 준비해놓자.

-> 5/30 오후 4시: 원래 github에서 비슷한 코드를 적용하려고 했는데 너무 적용하기 귀찮을 것 같아서 그냥 코드로 구현해보았다. 함수로 구현하여서 epoch에 따라 학습할 때 train_dataset, valid_dataset을 수정할 수 있도록 코드를 구현하였다. epoch=120으로 학습하였다.

코드에 문제가 있나보다 폴더에 따라 0.0이 나오는거 보면 함수 수정이 필요해보인다.(아마도 인덱스가 밀려서 틀리게 나오는 것으로 추정된다.) 일단 수정이 더 필요해보이지만 오늘은 시간이 없는관계로 수정되지 않는 상황에서의 성능만 보이겠다.

최후의 K-fold Cross Validation 적용후

k-fold cross validation 코드를 수정한 후에 바뀐 모습이 기대된다. 확실한건 이게 먹힌다는 생각이 든다. 코드 수정 + 데이터 shuffle 처리가 필요해보인다. 데이터 shuffle 을 시키지 않아 일어나는 문제였다. (shuffle 안하면 한쪽으로만 데이터가 학습되어 괜찮은 성능이 나오지 않는 이유다.)수정을 하고 학습을 해보니 괜찮게 모형이 만들어졌다. 뭔가 Batch mode 양상이 보이지 않아 Gradient-Descent도 Mini-Batch Gradient Descent로 수정하였다.

이제 HyperParameter 조정을 해보려고 한다. learning rate는 어느정도 정리되었으니, weight_decay를 조정하여 완전한 값을 정의하고자 한다. 실험 방법은 weight_decay = 1e-1, 1e-2, 1e-3, 1e-4, 1e-5로 나누어 실험해본다.

weight_decay = 1e-1 일 때, 생각보다 학습이 잘되어서 epoch=120이던 환경을 200까지 늘려보았다.

# Epoch : 109 / 200 71.86 68.97

epoch =200, weight_decay =1e-1, k-fold = 6

다 괜찮은데 k_fold=5로 설정하여 데이터셋을 충분히 학습될 수 있도록 수정할 필요가 있어보인다. weight_decay = 1e-2로 설정할때

# Epoch : 83 / 120 70.41 62.71

weight_decay = 1e-2, epoch=120, k_fold=6

흠 생각보다 weight_decay = 1e-2이 생각보다 별로 인것같다. 다음 weight_decay = 1e-3

# Epoch : 115 / 120 73.64 67.85

weight_decay=1e-3, epoch 120, k_fold=6

이 결과도 좋지만 weight_decay = 1e-1 일 때가 제일 만족스럽다. weight_decay=1e-4를 마지막으로 보자.

# Epoch : 108 / 120 72.11 66.1

weight_decay=1e-4, epoch 120, k_fold=6

되게 흥미로운 결과이다. 더 학습시키고 싶은 마음이 생겼다.그래서 1e-4, 1e-1로 후보를 간추려보고, k_fold=5로 다시 실험해보았다.

# Epoch : 117 / 120 77.84 67.61

weight_decay=1e-4, epoch 120, k_fold=5

생각보다 마의 70% 벽을 깨기는 어려운 것 같다.