Korea Health Datathon 2020 참가 후기

‘Korea Health Datahon 2020’에 대회에 대해 간략한 후기를 남겨보려 한다.

0. 대회 요약

의료영상을 직접 다뤄본 적은 없지만, 실제 데이터에 딥러닝 모델이 어떻게 쓰이는지 궁금하여 이번 대회에 참가하게 되었다.

대회에 관한 자세한 정보는 대회 GitHub Page에서 확인할 수 있다.

우선 부비동 이미지 학습 알고리즘 성능 평가 (A Track)와
유방암 병리 이미지 분류 모델 개발 (B Track) 중 한 가지를 골라
대회에 참가할 수 있었는데 우리 팀은 B Track을 골라 이번 대회에 참가하게 되었다.

두 Track 모두 Classification 문제로 암 진단을 하는 딥러닝 모델을 만들어 내는 것이 핵심이였다.

B Track에서 사용한 BaseLine 코드나 DataSet에 관한 정보는
KHD 2020 Github Page에서 확인을 할 수 있다.

1. 입력 이미지에 대한 조사

우선 유방 조직 세포 이미지를 처음 다뤄보는 것이기 때문에
Breast cancer classification challenge나 Kaggle에 있는 비슷한
Competition Solution 그리고 관련 논문을 찾아보며
어떻게 딥러닝 모델을 설계하는지 조사해 보았다.

논문에 나와있는 입력 영상의 경우 입력 이미지가 매우 커서 Patch 단위로 끊어서
이미지를 조사하는 경우가 있었는데, 이번 대회의 경우 입력 이미지가 크지 않아
(3 * 512 * 512) 이러한 전처리 과정은 거치지 않고 모델을 설계하게 되었다.

세포 이미지를 다루는 전처리 과정 중
Stain Normalization이라는 과정이 조금 특이해 보였다.

이번 대회에 적용을 해보려 했으나 라이브러리 충돌 문제와
Test 이미지에 target 이미지를 적용하지 못한다는 이유로
Stain Normalization이라는 기법은 사용하지 못했다.

이번 대회는 1주일 동안 모델을 만들어내는 것이 목표였기 때문에
자료 조사를 하는데 충분한 시간을 할애하지는 못했다.

다음은 이번 대회를 하면서 찾아보고 도움을 받은 논문 List이다.

2. 대회 솔루션

우리 팀 같은 경우 딥러닝 프레임워크 Pytorch를 이용하여 모델을 설계하였다.

이번 대회를 하면서 어떻게 최적의 모델을 찾게 되었는지 단계별로 적어보겠다.

0. Random Seed 고정

모델의 통제변인, 조작변인을 확실히 구분해주기 위해서
난수 생성도 고정된 Seed를 사용하여 통제를 해 주었다.

추후 최적의 모델을 찾고 나서 Random 값도 Hyper Parameter의 일종으로
적용할 수 있다는 이야기를 듣고, 모델을 선정하기 전 필수적으로 Random Seed를 고정하였다.

1. Baseline 코드 수정

모델을 선정하는 것보다 중요한 것은 주어진 데이터에 대한 처리이다.

우선 baseline 코드가 training set을 불러오는 것만 되어 있기 때문에 training set과 validation set으로 나누어 주는 작업을 했다.

데이터를 Validation set을 먼저 만들어주는 작업은 필히 해야한다!

Cross validation 작업을 통해 10개의 fold로 나누어 주었고,
그 중 validiation score가 가장 높은 것을 test에 돌려볼 수 있도록 모델을 채택했다.

2. Epoch 증가

Baseline 코드에서 epoch만 늘려 Test set에 제출을 했다.

Epoch는 대부분의 경우 늘리면 늘릴 수록 모델의 성능이 좋아지지만,
Epoch말고도 여러 변수들을 실험을 해보아야 했기 때문에
20 epoch를 기준으로 잡고 여러 실험을 진행했다.

3. Input Image Min-Max Normalization

Input image가 0~256 사이에 있는 RGB 이미지 였는데, 이를 0~1로 normalize 작업을 거쳤다.

이미 Pretrained 된 Weight들이 이 값에 맞추어 학습을 한것 이기도 하고, Backpropagation을 통해 Weight값을 초기화 할 때,
0 ~ 255 값을 쓰면 값이 너무 커지게 된다.

따라서 이런 Normalization 기법은 필히 해주는 것이 좋다.

4. Input Image Mean-Std Normalization

Input image를 training set에서 얻은 이미지들의 평균과 표준편차를 구하여
정규화를 시키는 작업을 했다.

RGB 채널별로 각각 이미지별로 평균과 표준 편차를 구한 후,
다시 Training Set 전체에 대한 평균과 표준편차를 구해 그 값을 이용하여
정규화 작업을 거쳐서 CNN 모델의 Input으로 넣어주게 되었다.

5. 모델 선정하기 & 모델 Fitting

모델을 선정해주는 작업을 거쳤다. 대회에서 사용을 해본 모델의 종류는 다음과 같다.

  • ResNet18
  • EfficientNet b3
  • RexNet 2.0
  • VGG16
  • MobileNetV2
  • ResNeSt

각각 모델을 모델의 마지막 layer만 학습을 시키는 방법
모델의 마지막 layer와 Backbone layer의 마지막 layer를 학습 시키는 방법을 이용하여
가장 성능이 좋은 모델을 찾으려고 노력했다.

모델을 바꾸고 실험을 돌리는데 약 1시간 정도 소요되고,
Submit을 한 번 하면 1시간을 기다려야 하기 때문에 생각보다 많은 모델을
Test해볼 시간은 없었다.

6. Data Augmentation

Data Augmentation에는 hflip, vflip, rotation 90을 random하게 적용
할 수 있도록 했다.

Crop도 시도를 했지만, 오히려 Crop을 했을 때에는 성능이 떨어졌다.

성능이 떨어진 이유를 추측해보자면,

  1. Test DataSet이 적어 Underfitting이 된 경우
  2. Crop 이후 Resize를 해줄 때 Interpolation 작업을 거치는데, 이 때 만들어진 data들이 test 하는데 영향을 미침.
  3. Input image와 Test image의 Scale이 같아, Crop이 의미가 없었다.
  4. Crop을 해줄 때 중요한 정보들이 날라갔다.

여러 이유들을 예상해볼 수 있었는데, 이런 것 들을 세세하게 짚고 넘어갈 시간은 없었다..

7. Under Sampling & Over Sampling

Under 샘플링과 Over 샘플링이라는 기법도 사용했다.
데이터가 불균형하게 존재할 때, 불균형함을 없애주기 위해 사용하는 기법이다.

이번 대회에서는 정상 세포 이미지와 암세포 이미지의 비율이 2:1로 주어졌는데,
데이터의 imbalace에 의한 문제는 없었다.

오히려 Under 샘플링을 적용해주었더니 성능이 떨어졌다.

8. Label Smooting

Label Smooting도 적용했다. 이번 대회는classification 문제이므로,
Loss function을 cross entropy를 사용했는데 training set에
너무 overfitting하지 않도록 label smooting을 0.1을 주어 training을 했다.

Label Smooting은 일종의 Regularization 기법인데
정답에 대한 Labeling을 확률적으로 표현하는 방법으로 생각하면 된다.

9. Model Ensamble

최종적으로 모델 앙상블 작업을 거쳤다.
3~5개 정도의 모델을 가지고 최고의 score를 뽑는 앙상블 모델을 찾으려고 노력했다.

앙상블에도 여러 종류가 있는데 이번 대회에서는 각각 모델들의 Classifier에
들어가기 전 Feature 들을 모두 합쳐서 Fully Connected Layer를 만드는 방법을 썼다.

이번 앙상블을 통해 알게 된 것은 단일 모델에서 최고 성능을 내는 모델들을 이용하여 앙상블을 하더라도 무조건 좋은 성능을 뽑아내는 모델을 만들 수 있다는 것은 아니라는 것이다.

즉, 모델들 간의 조화가 굉장히 중요하다.

단일 모델에서는 조금 안 좋은 성능을 내더라도 앙상블을 썻을 때
좋은 결과를 낼 수 있으니 차근차근 다 해보면 좋다.

10. 적용을 하지 못했지만 생각해 낸 기법들

이번 대회가 1주일밖에 주어지지 않아 생각해 냈지만 해보지 못한 방법들도 많다.

추후 비슷한 대회에 나가게 될 경우 이러한 방법을 적용해 볼 수 있으니 참고해보면 좋을 것 같다.

  • TTA(Test Time Augmentation)

    Test Image를 이용하여 vflop, hflop rotation을 적용하여 Test Image를 여러개 만들고 이를 모두 Test에 적용해보고 정확도를 올릴 수 있는 기법이다.
    하지만 실제 Test Set을 조작을 할 수 없으므로 현업에서는 이러한 방법을 잘 사용하지 않는다고 한다.

  • Model Ensamble (Voting)

    모델 앙상블을 하는 여러 가지 방법 중 이번 대회에서는 Feature들을 합치는 방법을 이용하여 앙상블을 진행했는데, Voting하는 방법도 앙상블 기법 중 많이 사용하는 기법이다. 다음에 기회가 된다면 사용해 보고 싶다.

  • 여러 Hyper Parameter 값들 튜닝 작업

    1주일이라는 시간이 결코 긴 시간이 아니였다. 시도를 해볼 수 있는 튜닝 작업은 많았지만 시간이 부족하여 결국 다 진행하지는 못했다. 대표적으로 Optimizer 바꾸기, Learning rate 바꾸기, K fold의 숫자 바꾸기 등등..
    선택과 집중이 정말 중요하다는 것을 느끼게 해준 대회였다.

3. 대회 결과

비록 상금은 타지 못했지만, 이번 대회를 하면서 수 많은 튜닝하는 기법들에 대해 알아가는 시간이 되었다.

이미 너무 좋은 딥러닝 모델들이 존재하고 또 계속해서 좋은 모델들이 발표되고 있다. ImageNet DataSet을 이용하여 만든 pretrained 모델을 조금만 튜닝해주면
세포 이미지에도 높은 정확도를 보이는 딥러닝 모델을 만들 수 있다는 것이 신기했다.

대회 마지막 순위이다. 그래도 5위라는 쾌거(?)를 달성했다.

대회 Score를 보면 알겠지만 정말 소수점 싸움이다.

조금만 더 튜닝을 잘했더라면 좋은 순위를 받을 수 있었을 것 같은데 조금 아쉽다.

마지막으로 딥러닝 모델을 만들 때 중요한 점을 정리해보자면

1. 항상 메모하는 습관을 들이자.

이번 대회에서 여러 실험을 돌릴 때마다 어떻게 바꾸었고,
결과가 어땠는지 Trello라는 사이트를 통해 기록을 하였다.
웹 기반의 프로젝트 관리 툴인데 온라인 상으로 Update를 바로바로 해주니
편하고 협업을 하기 굉장히 유용했다.

2. 차근차근 하나씩 해보자.

당연한 말이지만, 차근차근 하나씩 해보면서 결과를 확인하고 바꾸는 작업을 해야지
한 번에 많이 바꾸고 실험을 돌려놓면 어떤 원인 때문에 결과가 좋게 나왔는지
알 수가 없다. 조금 느리더라도 차근차근 하나씩 바꾸면서 모델을 바꾸어 나간다면
후반부에는 분명 좋은 결과를 얻을 수 있다.

3. 기본 모델도 무시하지 말자.

이미 좋은 딥러닝 모델이 넘쳐나고 있지만, 그래도 딥러닝을 처음 배울 때 배우는
모델인 VGG16, ResNet같은 모델들도 실험을 돌려봐야 한다는 것이다.
오히려 이런 모델들이 어떤 Task에서 성능이 높게 나올 수도 있다!

4. 통계 지표들을 잘 활용하자.

최종적으로는 Score를 가지고 점수를 측정하지만
우리가 사용할 수 있는 통계지표는 너무나도 많다.

예를 들면 Precision, Recall, Accuracy, Recall, Specificity 등등
하나하나 의미를 따지다 보면 현재 딥러닝 모델이 어떤 것을 측정을 잘못하고 있는지
알 수 있다. 이런 의미들을 곱씹어본다면 좀 더 좋은 모델을 찾을 수 있다.


이상 대회 후기 포스팅을 마치려고 한다.
추후 비슷한 Task의 대회를 나가는 분들에게 조금이나마 도움이 되었으면 한다.

마지막으로 같이 대회에 참가하여 많은 것을 배울 수 있게 해준
developer0hye에게도 정말 고맙다고 이야기 하고 싶다.

댓글남기기