AI프렌즈 위성관측 데이터 활용 강수량 산출 AI 경진대회

Public 1등 솔루션 공유

2020.05.25 19:46 7,168 Views

재밌는 대회 개최해주셔서 정말 감사합니다.

혼자했으면 힘들었을텐데 팀으로 진행해서 좋은 결과가 있었던 것 같습니다.

대회 마감 3일전까지 점수가 오르지 않아 정말 힘들었는데, 좋은 Feature를 찾아내서 많은 향상이 있었습니다.


Feature

  •  Temp 0~8
  •  Type
  •  GMI와 DPR의 Latitude Diff
  •  GMI와 DPR의 Longitude Diff

Latitude와 Longitude Diff를 추가한 이유는 대회 막바지에 외부 데이터를 추가하다가 보니 GMI 데이터와 DPR 데이터의 좌표 맵핑이 가장 힘들었습니다.

데이터 설명 자료에서도 GMI와 DPR의 가장 가까운 좌표를 계산하여 Mapping하였다고 했는데 직접 해보니 가장자리 부분이 정확하게 Mapping하지 못하였습니다.

그래서 이런 Diff 정보를 추가하면 상대적으로 Model이 이 값이 컸을 때 데이터를 신뢰할 수 없다고 판단하지 않을까 생각해서 추가하였습니다.

이 피쳐만 추가해서 기존 1.55정도의 Public Learderboad Score에서 1.42까지 한번에 올라갈 수 있었습니다.


  • -9999가 1개라도 있으면 제거
  • 데이터는 전체 다 사용
  • StandardScale 적용



Data Augmetation

  • Roatation 90, 180, 270, HFlip, VFlip, Transpose
  • Augmentation 비율 0.5


외부 데이터

  • 데이터 설명 ppt에서 data받은 곳이 나와있었고 이번 대회에서 제공된 2016~ 뿐만 아니라 2014, 2015 정보도 있었습니다.2014, 2015 데이터를 받아 최대한 이번 대회 Format에 맞는 변환에 성공하였고 대회 막바지에 시간이 많지 않아 대략적으로 8300개 정도 추가하여 학습하였습니다. 외부 데이터를 추가한 Model이 생각보다 큰 효과는 없었지만 약간의 성능 향상이 있었습니다. 기존 Data로 학습한 모델과 외부 데이터를 추가하여 학습한 모델로 Ensemble 시 다양성을 추가하기 위한 목적도 있습니다.



Model

GoldBar님이 올려주신 코드가 아니었다면 정말 힘들었을 것 같습니다. 다시 한번 감사드립니다.


처음에는 LGBM으로 접근하다가 도저히 안될 것 같아서 Unet기반 Segmentation Model로 진행하였습니다.

그 후 GoldBar님이 올려주신 코드와 댓글을 보고 모델을 다시 생각하게 되었고 이 코드 기반으로 모델을 변경하면서 좋은 Model을 찾았습니다.


CNN 기반 Custom Model KFold

  • Data: Original Data, -9999 제거
  • Cross Validation: 5 Fold
  • Loss: MOFLoss
  • Optimizer: RAdam + LARS + LookAHead (https://github.com/mgrankin/over9000)
  • Scheduler: CosineAnnealingWarmRestarts(optimizer, 10, 2,eta_min=1e-6)
  • Model: CNN 기반 Custom Model
  • Batch: 128
  • Epoch: 150


CNN 기반 Custom Model Single

  • Data: Original Data, -9999 제거, 추가 데이터 사용 약 8300개 (-9999제거, 위 경도가 심하게 일치하지 않은 것 제외)
  • Cross Validation: train_test_split(sorted(glob.glob(train_path + '/*')), test_size=0.1, random_state=31014)
  • Loss: MOFLoss
  • Optimizer: RAdam + LARS + LookAHead (https://github.com/mgrankin/over9000)
  • Scheduler: CosineAnnealingWarmRestarts(optimizer, 10, 2,eta_min=1e-6)
  • Model: CNN 기반 Custom Model
  • Batch: 128
  • Epoch: 150


Goldbar님 Model Single

  • Data: Original Data, -9999 제거, 추가 데이터 사용 약 8300개 (-9999제거, 위 경도가 심하게 일치하지 않은 것 제외)
  • Cross Validation: train_test_split(sorted(glob.glob(train_path + '/*')), test_size=0.1, random_state=31014)
  • Loss: MOFLoss
  • Optimizer: RAdam + LARS + LookAHead (https://github.com/mgrankin/over9000)
  • Scheduler: CosineAnnealingWarmRestarts(optimizer, 10, 2,eta_min=1e-6)
  • Model: Goldbar님 Single Model
  • Batch: 128
  • Epoch: 150



Ensemble

CV와 대략적인 LB기준으로 Ensemble을 진행하였습니다. 

위에서 말한 3가지 모델에 가중치를 주어 결합하였고 최종적으로 1.37868을 기록하였습니다.

최종결과: 1번 * 0.6 + 2번*0.2 +3번*0.2



시도한 것

  • 다양한 Custom Model 실험
  • 다양한 Loss(SmoothL1Loss, L1Loss, DiceLoss 등), Optimizer(AdamW, Adam, SGD 등), Scheduler 실험
  • Unet기반 Segmentation Model 실험(Encoder Model을 바꾸거나 Fpn, DeepLab 사용 등)
  • LGBM기반 Model (정말 다양하게 해봤는데, 1.8 초반 정도가 한계였습니다.)
  • Augmentation 중 Random Box Cut 후 그 부분만 회전, Flip 하는 CutFlip을 구현했는데 성능향상이 아주 조금 있는 것 같아 사용하지 않았습니다.
  • Augmentation 중 Random Box Cut 후 그 지역을 0 Target의 Median의 Noise를 준 Random값으로 채워주는 것도 해봤는데 잘 안되었습니다.
  • 오차 분석 후 299가 넘는 점들을 잘 예측하지 못한다는 점에서 아주 큰 값은 인접셀의 평균 값으로 Smoothing해주었는데 잘 안되었습니다.
  • 299가 넘는 값들을 가지는 것 제외해보았는데 잘 안되었습니다.
  • Temp Diff Feature ( tem0 - temp1, temp0-temp2 ...)
  • -9999 데이터도 채워서 사용하였는데 큰 향상이 없어 사용하지 않았습니다.


감사합니다.


로그인이 필요합니다
0 / 1000
Kimgoing
2020.05.25 20:41

대단하시네요.. 1등 축하드립니다. 올리신 내용 바탕으로 다시 공부하도록 해야 겠습니다. 

처음해봐요
2020.05.25 23:30

삭제된 댓글입니다

처음해봐요
2020.05.25 23:30

감사합니다~ 

이성민0403
2020.05.25 20:54

공유해주셔서 감사합니다.

처음해봐요
2020.05.25 23:50

감사합니다!!

2020.05.25 22:33

와 정말 다양한 시도를 하셨네요 축하드립니다

처음해봐요
2020.05.25 23:50

감사합니다! 적지 못한 것도 많은데ㅠ 많은 시도를 하고 많이 실패해서 좋은 결과가 있었던 것 같습니다!

GoldBar
2020.05.25 22:36

솔루션 공유 감사합니다.

혼자 진행하다가 더이상 진행하기 어려운 상황이라 코드를 공개하였는데 누군가에게 도움이 되었다니 기분이 좋네요.

처음해봐요
2020.05.25 23:31

공유해주셔서 감사합니다. 덕분에 모델을 다시 생각해 볼 수 있었습니다!

1Gb
2020.05.25 23:38

솔루션 감사합니다 TTA 안하시고도 엄청 높은 점수가 나오셨네요 대단하십니다. 혹시 MOFLoss 에 대해서 조금 더 알 수 있을 까요??

처음해봐요
2020.05.25 23:47

TTA도 해보긴 했는데 큰 성능 차이가 없어서 기본 모델로 했습니다. MOFLoss는 그냥 mae_over_fscore의 줄인말이고 계산 결과는 Dacon에서 만든 것과 같습니다.

1Gb
2020.05.25 23:53

아 그렇군요 감사합니다

뭉뭉
2020.05.26 01:04

아 위치 정보가 엄청 크게 작용하는군요 .. 저도 시도해 보려다 정말 귀찮다는 이유로 안했는데 점수 상승이 엄청 크네요 .. ㅎㅎ 저 Feature를 썼으면 어땠을까하는 후회가 남네요 ..ㅋㅋㅋㅋ

뭉뭉
2020.05.26 01:04

그런데 regression model에서 혹시 MOFloss는 어떻게 정의하셨나요 ? 
저 같은 경우는 외부데이터 없이 efficientnetb4을 백본으로한 Unet에서
cls model과 0.1이상의 값에 대한 regression model을 따로 학습하니 1.489 정도의 score를 낼 수 있었습니다. 

뭉뭉
2020.05.26 01:04

그런데 이렇게 cls와 reg모델을 따로 학습한 이유가 저도 엄청 많은 실험을 해보았는데, 단일 regression model에서는 fscore를 loss로 변환하는 과정에서 binary하게 값을 assign하다보니 역전파가 되지 않더라고요...
어떻게 하신건지 궁금합니다.

처음해봐요
2020.05.26 01:06

latitude와 longitude 자체를 사용한 것 보다 GMI와 DPR의 차를 사용하니 거의 0.1 정도 향상이 있었습니다. 저희도 초반에 Unet기반으로 다양한 백본을 실험했었고 점수 올리기 힘들던 차에 GoldBar님 솔루션이 있어서 도움이 되었습니다. 

처음해봐요
2020.05.26 01:12

Classification Model과 Regression Model로 나눠서도 해봤었는데  L1 Loss로 먼저 학습 후 따로 Binary Classification으로 학습하여 score보고 강제로 0으로 바꾸는 작업을 했었습니다. 점수가 조금 좋아졌는데 큰 성능 변화가 없어서 일단 문제를 분리해서 생각하는 것은 더이상 하지 않았습니다. Classification 문제는 0.1보다 크면 1 작으면 0으로 두어서 Pixel별로 classification도 해보고 전체 target이 0이면 1 아니면 0으로 두고도 해보았습니다.

처음해봐요
2020.05.26 01:48

아마 대회가 더 길어졌다면 Classification 부분을 강화했을 것 같습니다ㅠ
계속 하다보면서 loss를 문제와 일치시키면 좋을 것 같다는 생각을 했고 저희도 unet 기반으로 했을 때는 계속 학습이 잘 안되었고 batch를 늘리면 좀 괜찮았던 것 같은데 그래도 안될 때가 있었습니다. 딱히 구현에 특이한 점은 없는 것 같은데 f_score 구현은 아래와 같습니다.

처음해봐요
2020.05.26 01:50

beta (float): positive constant , 1
eps (float): epsilon to avoid zero division, 1e-7
threshold: threshold for outputs binarization, 0.5
tp = torch.sum(gt * pr)
fp = torch.sum(pr) - tp
fn = torch.sum(gt) - tp
score = ((1 + beta ** 2) * tp + eps) / ((1 + beta ** 2) * tp + beta ** 2 * fn + fp + eps)

endgame
2020.05.26 01:40

삭제된 댓글입니다

endgame
2020.05.26 01:43

 Diff 아이디어 정말 감사합니다!! 고생 많으셨습니다!~~

처음해봐요
2020.05.26 01:52

감사합니다! endgame님도 축하드립니다. 고생하셨습니다!

최정명
2020.05.26 04:13

1위 축하드립니다!
솔루션을  깔끔하게 잘 정리하셨네요 !
저도 LGBM으로 접근해보았다가 답이 없음을 느꼈습니다. ㅠㅠ
LGBM 으로 한 픽셀씩 regression으로 시도해 보았는데 답이 없더군요.
결국 Unet 모델로 여러 과정을 거치면서  앙상블을 시도 했습니다...

정말 고생 많으셨습니다!

처음해봐요
2020.05.26 18:29

정명님도 축하드립니다!
저희는 Unet으로 잘 안되었는데 솔루션이 궁금하네요! 나중에 보고 배우도록 하겠습니다

고생하셨습니다!

바위게
2020.05.26 09:26

일반적으로 lat/lon 자료를 직접 입력자료에 넣는 것은 조심스럽기 때문에 아예 배제하고 생각했는데, 두 개의 latitude 차이에 대해서는 생각해보지 못했네요. 앙상블이 답일거라고는 생각했는데 역시나였구요. 이전 연도의 외부 데이터를 추가로 넣으신 것도 좋은 발상이네요. 나중에 코드 공개되면 꼼꼼이 보고 배워가야겠습니다. 축하드려요~!

처음해봐요
2020.05.26 18:31

운 좋게 차이 값 Feature를 발견하게 된 것 같습니다. 감사합니다!

당쇠
2020.05.27 15:56

감사합니다.

처음해봐요
2020.05.27 21:10

감사합니다!

Kimgoing
2020.06.20 14:31

저 혹시 소스를 공개해 주시다면 공부를 더 해보고 싶은데 언제쯤 공개되는지 여쭤봐도 될까요?

처음해봐요
2020.06.20 23:30

코드 공유하는 건 어렵지 않은데 공유 해도 되는지 모르겠어요ㅠ 데이콘에서 답변해주면 좋을 것 같습니다!

Kimgoing
2020.06.21 09:18

답변 감사합니다. 저도 데이콘 쪽에 문의를 넣어봐야겠네요~ 

🇰🇷🇹🇼🇳🇮🇬🇺🇳🇫
2021.09.15 15:14

감사합니다!

레오레오
2021.09.29 10:49

감사합니다!