본문 바로가기

공부방/Upstage AI Lab 4기

패스트캠퍼스 Upstage AI Lab 부트캠프 4기, "Upstage 경진대회 CV편"

새로운 공부를 하니 시간이 정말 천천히 가는 것 같으면서도 또 순삭이네요. 첫 경진대회인 아파트 실거래가 예측하는 머신러닝 경진대회가 지나고, 바로 MLOps를 지나, CV 경진대회까지 쉴틈없이 달리는 중인데요. 이번 포스팅에서는 지난 주에 마무리했던 CV 경진대회에 대한 이야기를 해볼까 합니다. 

 

이번 대회는 CV, Computer vision domain에서 중요한 이미지를 분류하는 태스크가 주제였습니다. CV의 아주 클래식한 예시처럼, 강아지 사진을 넣고 모델이 강아지인지 고양이인지 맞추게 하는 것처럼 말이지요. 대회에서 주어진 이미지들은 총 17가지 클래스로 구분되어 있었는데요. 1570장의 학습 이미지가 주어지고, 각 이미지는 클래스1(자동차 번호판), 클래스2(이력서), 클래스3(진료확인서) ... 와 같이 클래스가 라벨링된 csv 파일이 함께 제공됐습니다. 이 이미지를 학습하고 3140장의 평가 이미지를 예측하는 것이고요, 점수는 F1 score로 매겼습니다. 

가장 먼저 학습 데이터와 테스트 데이터르를 눈으로 직접 확인해봤습니다. 

학습 데이터는 올바르게 정면에서 잘 찍은 듯한 이미지들이었고, 테스트 데이터는 노이즈가 심하거나 삐뚤어지고 다른 이미지와 겹쳐있는 것들도 있었습니다. 랜덤하게 회전되어 있었고, 뒤집히거나 훼손된 이미지도 있었죠. 클린한 이미지만 공부해서는 더러운 이미지까지 잘 맞추기는 어렵겠죠? 그래서 어그멘테이션이 중요할 것이라는 생각을 처음부터 했습니다. 다만, 어느 강도로 얼마나 많이, 데이터셋 크기는 어느 정도로 늘려야 할 것인가에 대해서는 감이 없었죠. 

 

1. 매일 팀원들과 회의

저희 팀의 경우에는 매일 아침 10시부터 10시 반까지는 각자 공부한 내용을 공유하기도 하고, 시도해 본 방법들이나 아이디어를 얘기하는 시간을 가졌습니다. 

처음부터 저희 팀장을 맡아주셨던 분이 데이터 어그멘테이션을 14만장 수준으로 높이고, 베이스라인 코드에서 크게(?) 벗어나지 않은 수준에서 모델을 돌려서 결과를 제출했는데 0.9 대의 점수가 나왔습니다. 테스트용으로 올린거라 이후에 이것저것 작업하면서 코드를 잃어버리셨다고 했는데, 어쨌든 저희 팀 입장에서는 처음부터 굉장히 든든한 성과가 나와서 마음놓고 다양한 실험을 해볼 수 있는 배경이 됐어요. 

 

2. 데이터 전처리 파트

저는 데이터셋의 크기가 어느 정도 선에서 적당하고 효율적으로 학습시킬 수 있을 것인지 작은 실험을 만들어 검증해보았어요. (관련 포스팅) 그리고 다른 팀원께서는 학습 이미지를 일일히 눈으로 확인을 해보고 라벨링이 잘못된 이미지 8개를 발견해서 정정해주셨고요. 또 다른 팀원께서는 훈련데이터 내의 클래스별로 데이터 개수가 다르다는 걸 발견하고 임밸런스된 데이터셋보다 밸런스를 맞춘 데이터셋으로 학습을 시켰을 때 성능이 더 잘나온다는 점을 발견해주셨어요. 이미지의 평균 사이즈도 확인했는데, 사이즈가 크게 튀는 이미지가 없이 다들 비슷한 사이즈를 가지고 있다는 점도 확인해주셨어요.

 

3. Augmentation

어그멘테이션 다양하게도 적용해봤다요... 하핫
금손인 저희 팀원분께서 만들어주신 슬라이드인데, 너무 잘만드셨죠!!

첨부터 저 모든 어그멘테이션을 다 적용한 건 아니였고, 또 팀원마다 각자 넣은 방식이 조금씩 다르기도 했어요. 
저는 첨에 파이토치인가? 거기 라이브러리에 있던 걸 가지고 했는데 성능이 안좋아서 albumentation? 그런 라이브러리 활용해서 했고, 강도도 점차 높여갔어요. 온라인 증강에는 믹스업, 컷믹스, 컷오프 다 사용했는데 배치 돌면서 3번에 한번씩 적용되는 방식으로 했고요. 어그멘테이션도 사이클을 돌아가면서 점차 기법이 늘어나게 됐습니다. 

어그멘테이션을 진행하면서 생성된 이미지들

어그멘테이션도 시행착오가 많았어요. 처음에는 자꾸 비슷한 사진들이 만들어져서 나중에는 확률값을 다르게 주면서 최대한 다양하고, 강도를 높여서 이미지를 만들려고 했어요. 대회 끝나고 이 대회를 기획한 강사님 말씀이 어그래피 라이브러리를 꼭 써볼 수 있도록 유도를 하셨다던데, 아쉽게도 저는 어그래피까지는 못써봤습니다. 

 

4. 모델

모델도 다양하게 써본 것 같아요. 팀원마다 써보고 싶은 것이 달라서, 본인의 관심에 맞는 것을 위주로 먼저 실험을 했고 각자 점수가 잘 나온 모델과 하이퍼파라미터를 공유했습니다. 

저는 초반에는 rasnet34, 50, densenet121, efficientb0, b4을 주로 썼고, 후반에는 다른 팀원분께서 cnn계열에서 이미 좋은 성능을 내고 계셔서 저는 swin_tiny, swin_base 모델에 집중했어요. 트랜스포머 계열의 모델로 성능을 높인 다음에 같이 하드보팅이나 소프트보팅을 해야겠다는 생각으로 그렇게 진행했고, 실제로 하드보팅을 했을 때는 결과가 꽤 잘 나왔어요. 

모델을 돌리고 하이퍼파라미터를 설정하면서 정말 많은 것들을 배울 수 있었는데요. 사소한 에러로 안돌아가는 문제를 해결하는 것부터, 이미지 사이즈와 배치 사이즈의 의미, 에폭이랑 얼리 스탑은 뭘 기준으로 설정하면 좋은지, 손실함수와 옵티마이저는 무엇이 있고 서로 어떻게 다른지, 그리고 스케줄러와 같은 기능도 익히게 됐어요. 강의에서 분명 들은 적은 있었겠지만 무슨 말인지 모르고 지나갔던 것들이 이번 대회를 통해서 피부로 와닿게 느낄 수 있었던 시간들이였습니다. 

 

5. 컨퓨전 메트릭스

컨퓨전 메트릭스를 그려보고 정답과 예측을 비교해보는 것도 큰 도움이 됐습니다. 제가 그렸던 컨퓨전 메트릭스 그래프는 날아가버리고 없지만... 밸리데이션 셋 안에서 잘 못 맞춘 클래스들을 뽑아봤었는데, 3번, 4번, 7번, 11번, 14번을 주로 혼동하는 것을 확인했습니다. 그래서 이걸 어떻게 하면 잘 맞추게 할까... 를 고민하다가!

저희 팀원 중 한분이 3번과 7번, 4번과 14번, 3, 4, 7, 14번 클래스만 단독으로 트레인데이터셋으로 구성해 학습시킨 모델을 만들어 소프트보팅을 해보자는 의견을 제시해주셨습니다. 그렇게 한 모델을 다른 기존에 점수 높은 모델과 소프트 보팅을 하는 방식으로 앙상블하면 점수가 높아지지 않을까! 하는 생각이였죠. 그렇게 해서 나온 모델이 최종적으로는 0.9441로 가장 높은 점수를 받았습니다. (저희 팀이 올린 리더보드 상의 점수 중에서)

저는 데이터셋에서 3, 4, 7, 14만 학습시키는 방법이 아니라, 데이터셋의 구성 자체를 3, 4, 7, 14 클래스 양을 확 늘리고 다른 클래스의 이미지는 상대적으로 적은 비율을 갖도록 해서 3, 4, 7, 14를 과대학습시킨 모델을 만드는 방식을 시도했습니다. 트랜스포머 계열인 swin계열로 특정 클래스를 과대 학습시키고, 이걸 다른 cnn 계열과 앙상블하면 좋을 것 같다고 생각했어요. 사실 이때 제가 감기 몸살로 팀원들과 소통이 좀 어려웠고 아쉽게도 리더보드에는 제출 횟수 초과로 올려보지는 못했어요. 그래도 가장 높은 점수를 받은 아웃풋을 기준으로 비교해봤을 때 94%였나? 높은 수준으로 답이 유사해서 점수도 아마 비슷하지 않았을까 짐작합니다.  

최종 결과는 두구두구두구 4등! 

아쉬움도 많이 남지만 또 다같이 최선을 다했던 경진대회라서 뿌듯함도 많이 남았습니다. 

 

+

추가로 시도해봤지만 큰 성과는 없었던 것들

이건 다른 팀원분께서 했던 노력들이였는데 다른 팀의 발표를 들어보니 다들 OCR을 한 번씩은 도전해보셨더라고요! 저는 OCR쪽으로는 생각을 못해봤는데. 아쉽게도 테스트 데이터셋에서 노이즈가 많아 제대로 읽히지 못했습니다. 

다음 경진대회는 NLP가 주제인데요. 가장 관심있는 주제이고 분야라서 더욱 기대가 됩니다.