본문 바로가기
Boostcamp

[부스트캠프] Semantic Segmentation competition 회고

by Yonghip 2023. 6. 29.

Segmentation 대회 이후 바로 최종 프로젝트이므로 사실상 부캠에서 참여하는 마지막 대회였으며 마지막이라 그런지 모든 팀들이 상위권을 목표로 삼았고 저희 팀도 입상 욕심이 컸습니다.

 

최종 대회는 손뼈에서 총 29개의 class를 segmentation하는 multi label segmentation이었으며 segmentation연구가 활발히 진행되는 의료 도메인에 관한 문제라 기존 연구도 많았고 시도할 수 있는 방법론 역시 많았습니다.

 

추가로 이번 대회의 데이터는 공개가 불가능하여 예시를 직접 보여드리지 못하는 점 참고 바랍니다!

 

문제 정의

팀원 모두 경진대회에 익숙해져서 GPU를 최대로 사용할 수 있게 일정을 짰습니다.

 

아래와 같이 일정을 구성하여 실험은 계속 돌리고 GPU를 사용하지 않는 일을 병행하며 대회를 진행하였습니다. 베이스라인 코드 구성 -> 아키텍처 및 모델 실험 + 리서칭 + EDA -> 추가 실험 +  에러 분석-> 앙상블

 

EDA를 하며 다음과 같은 insight를 얻었습니다.

  1. 대게 정상각도이나 30~45도 손을 회전하고 찍은 사진이 존재함
  2. 붕대, 반지, 네일아트 등 손의 뼈와는 확연히 대비되는 이상 부분이 존재함
  3. 팔목 부분에서 팔부분까지 철심이 있는 데이터가 존재하며 이 역시 손뼈와는 확연히 대비됨
  4. 골절로 인해 손뼈가 정상과는 확연히 다른 데이터가 존재함

 

대회가 절반쯤 진행되고 대다수 팀이 일정 성능에 도달한 뒤 성능 향상이 더디어질 때 추가 EDA와 val set 시각화를 통해 모델 에러를 분석하였고 얻은 insight는 다음과 같습니다.

  1. 눈으로 확인할 때는 GT보다 TP가 더 경계면을 잘 예측하는 것 같음
  2. 경계면에서 FN과 FP모두 일정한 에러가 존재함
  3. 겹쳐진 클래스에 대한 예측 정확도가 낮음
  4. 예측이 뼈 부위가 아닌 아예 외부 범위에 존재함

저희 팀은 이때 상위에 위치하고 있으므로 fine-tuning에 집중하기 보다는 문제해결을 위해 여러 실험을 진행했습니다. 이후에는 성능 향상을 이룬 방법들에 대해 원인->방법->결과 분석 순으로 하나씩 설명해 보겠습니다.

 

Data Cleaning & Augmentation

Data Cleaning

초기 EDA시 골절, 철심, 붕대, 반지 등등 보통 X-ray데이터와 시각적으로 확연히 다른 데이터가 있었는데 이를 제거하고 리더보드에서 성능을 비교하였습니다.

 

성능에 큰 영향은 주지 못했었는데 아마 원본 데이터 양이 적어 cleaning 시 더욱 적어지기 때문이기도 하고 (300장 중 20장) 최근 모델의 성능이 올라 이러한 확연한 이상치는 전부 감지 가능할 것이라고도 생각했습니다.

 

Augmentation

증강은 이전처럼 여러 조합을 기본 모델에 하나씩 실험해 보며 성능을 비교하며 판단했습니다.

최종적으로 3개의 증강을 선택했으며 각각의 증강과 선택이유는 아래와 같습니다

 

 

One class method & Loss

에러 분석 insight

  1. 눈으로 확인할 때는 GT보다 TP가 더 경계면을 잘 예측하는 것 같음
  2. 경계면에서 FN과 FP모두 일정한 에러가 존재함
  3. 겹쳐진 클래스에 대한 예측 정확도가 낮음
  4. 예측이 뼈 부위가 아닌 아예 외부 범위에 존재함

위에 작성했던 에러 분석 부분을 제가 맡았었는데 저는 특히 2번 문제에 집중했습니다.

 

1번 문제는 Segmentation task의 사소한 라벨링 오류에서 비롯된것 같으며 이로 인해 학습 시 실제 경계면과 라벨값의 차이가 발생해 모델의 예측이 정교해지지 못하고 2번 문제가 발생했다 생각했습니다.

 

이때는 이미 대다수 팀의 dice가 0.95를 넘었기 때문에 약간의 라벨링 에러와 이를 판별하지 못한 약간의 모델 에러로 인해 성능 향상이 더뎌지고 있다고 판단했습니다.

 

One class method

따라서 모델에러를 줄이고 경계를 정교하게 만들기 위하여 29개 클래스를 하나의 클래스 변환해 뼈와 경계를 중점적으로 학습하는 모델을 사용하였습니다. 가중치가 줄어 더 큰 size의 image를 학습시킬 수 있었으며 class에 대한 정보가 사라져 경계면을 더 잘 학습할 수 있을 것이라 판단했기 때문입니다.

 

29개의 클래스를 inference 할 시 one-class 모델이 True로 inference한 경우의 예측만 남기고 나머지는 False으로 치환해 배경으로 인식하도록 하였습니다.

 

 

한 클래스만 학습시켰을때 dice는 0.99를 넘었으며 이를 통해 기존 모델의 결과를 후처리 하는 솔루션으로 당시 dice:0.9514 -> 0.9578의 향상을 이루었으며 앙상블 이후에 적용할 때에도 약간의 성능 향상을 보여주었습니다

성능향상에는 언급한 대로 모델의 FP를 줄일 수 있고 후처리를 통해 배경에 예측이 생기는 경우도 방지할 수 있기 때문이라 판단했습니다.

 

Loss

loss는 여러 loss로 실험해 보았을 때 평가지표와 동일한 dice loss의 val set과 public의 차이가 가장 작았습니다. 따라서 기존에 최고 성능인 Jaccard loss와 dice loss 그리고 픽셀별로 loss를 계산하는 BCE loss 총 3개를 [Jaccard, Dice, BCE] -> [0.3: 0.6: 0.1]의 비로 combine 하여 사용했습니다.

 

Ensemble & TTA

앙상블 방식으로는 소프트 보팅 방식을 사용하였으며 각 모델의 예측값을 전부 더한 뒤 thershold를 그에 맞게 스케일링 해주었습니다.

 

최종적으로는 저희가 선택한 3개의 모델의 예측에 Horizontal flip과 Multi resize TTA를 적용한 예측 총 6개를 소프트 보팅한 예측을 사용하였습니다.

 

 

여러 시도 끝에 Public : 0.9743(2nd) / Private : 0.9749(2nd)의 점수로 2위를 달성할 수 있었습니다.

 


이번대회는 시간도 길었고 실험 계획 역시 체계적이라 초중반부터 상위권을 계속 유지했었습니다. 심리적으로도 부담이 덜했고 팀원 간의 신뢰도 생겨 각자 리서칭, EDA, 기능 추가 등을 병렬적으로 수행했습니다.

 

경진대회가 끝나면 극한의 파인튜닝과 앙상블 말고는 해낸 것이 없는 것 같아 현타가 오곤 했는데 이번에는 자연스럽게 EDA → 인사이트 → 구현 및 실험 → 왜? 순서로 실험 진행이 가능해 많은 인사이트를 얻을 수 있었습니다.

 

그리고 이게 부캠에서 진행하는 마지막 대회인데 여러 대회를 거치면서 돌아보면 컴페티션에 대한 흥미도 다시 살아나고 협업, 방법론, 라이브러리 사용등 여러 면에서 성장한 만족스러운 과정이었습니다.

 

 

이미지 및 대회 출처: 네이버 부스트캠프 AI Tech

깃허브: https://github.com/boostcampaitech5/level2_cv_semanticsegmentation-cv-11/tree/master