이번 level2 첫 대회는 Relation Extraction, 즉 문장 내 단어(entity)간의 관계 추출 task이다.
정말 많은 실험을 해보았고, 많은 것들을 배우고 느낄 수 있었다.
대회 기간 중 꽤나 오랜기간 동안 1등을 하고 있었고, 2-3등을 계속 유지하고 있어 기대를 좀 했지만, 5등이면 그래도 만족한다!
1. AI 프로젝트 관점에서의 회고
1-1. 협업에 관하여
협업에 있어서는 우선 level2에서 새로운 팀원들로 팀을 구성하였기 때문에, 약간의 걱정이 있었다.
정말 말이 잘 통했던 level1 팀원들과도 협업에는 조금 어려움이 있었는데, level2 팀원들은 아직 잘 모르기 때문에 걱정이 앞섰던 것 같다.
다행히도 level1에서 아쉬웠던 점들을 많이 개선했고, github나 진행 상황 공유도 훨씬 더 잘 이루어진 것 같아서 뿌듯했다.
1-1-1. 역할 공유와 중간 점검
역할 공유가 잘 되지 않았던 것은 지난 level1 대회에서 가장 아쉬웠던 부분이였다.
각자 할 일을 나누는 것은 잘 진행되었으나, 서로 한 일들을 공유하고 맞춰가는 부분이 잘 되지 않았었는데, 이번 level2 대회에서는 진행 상황을 서로서로 잘 맞춰갈 수 있었다. github 역시 적극적으로 잘 이용했는데, MRC 대회가 시작하기 전에, egoing님의 깃허브 강의는 반드시 다시 들을 계획이다.
다만, 중간 점검을 조금 더 자주 해서, 역할 공유 뿐만 아니라 프로젝트의 전반적인 흐름을 정리하고, 우리가 무엇을 해왔고, 앞으로는 어떤 것에 집중해야 할 지 정리하는 시간을 가져야할 것 같다.
1-1-2. baseline코드와 template의 필요성
앞으로도 나는 다양한 대회 및 프로젝트를 진행할텐데, 이때 baseline 코드는 항상 있어야 할 것이다. 물론 대부분의 대회에서 baseline 코드를 제공하지만, 나만의 정형화된 baseline template이 있다면 훨씬 효율적으로 코드를 작성하고 조금 더 효율적으로 작업할 수 있을 것이다. 이번 대회에서 우리는 나름대로 다양한 모델 및 tokenizer 변경, wandb 연동, yaml 파일 관리 등에 있어 체계화된 코드를 작성했지만, 다음 대회에서는 이를 좀 더 다듬어 재활용 가능한 코드(template)로 만들 것이다.
1-2. 문제 정의와 다양한 접근 방식
사실 대회의 특성 상 문제 정의는 정해져 있는 경우가 많다.
그러나 RE(Relation Extraction) task와 관련된 다양한 최신 논문들을 읽으며 RE task를 다양한 방식을 통해 해결할 수 있다는 것을 배웠다. SuRE라는 논문에서는 RE task를 Summarization(요약) task로서 해결하고자 하였고, 멘토님이 알려주신 논문과 다른 팀들의 얘기를 종합해 보면 QA(질의응답) task로서도 RE task를 풀 수 있다는 것을 알 수 있었다.
문제를 정의하고, 그 문제를 해결할 다양한 (최신)solution을 잘 찾는 것도 굉장히 중요한 작업 중 하나라는 것을 느꼈고, 같은 대회가 반복되는 부스트캠프의 특성 상 조금 더 새롭고, 최신의 방식을 사용해 문제를 해결한다면 남들과 다른 차별점이 될 수 있을 것이라 생각했다.
1-3. Dev dataset과 다양한 실험
이번 대회에서 끝까지 해결되지 않았던 단 하나의 의문은 바로
"왜 dev dataset으로 평가했을때는 f1 score가 80점대가 나오는데, 제출만 하면(test dataset) 70점대로 떨어지는가?" 이다.
고민 끝에 내린 결론은, dev dataset과 test dataset이 label 분포가 다르기 때문이라고 생각했다.
이에 dev dataset을 아래 세 가지 방식으로 뽑은 뒤 f1 score를 구해 이를 test score과 비교해봤다.
- 전체 dataset의 label 비율에 맞춰서 구성
- 전체 dataset에서 랜덤하게 추출
- 데이터 수가 지나치게 많은 label(no-relation)은 그 비율을 낮춰서 추출
결론적으로는 그닥 효과가 없었고, 끝내 왜 이런 score 차이가 나는지는 알지 못했다.
그러나 "1) 전체 dataset의 label 비율에 맞춰서 구성" 일때 그 차이가 가장 적었고, 정확한 test score를 추정할 수는 없어도 경향만 맞으면 이를 고정된 evaluation dataset으로 사용해도 괜찮다고 생각했다.
제한된 제출 횟수에서 다양한 실험을 하기 위해서는, 제출해보지 않아도 test score를 추정할 수 있는 신뢰성 있는 evaluation dataset이 필요하다. 앞으로 어떤 대회를 시작한다면, dev dataset을 여러 방식으로 구성한 뒤 각 score를 제출했을 때의 score과 비교하여, 가장 차이가 적은 dev dataset을 evaluation dataset으로 사용해야겠다.
1-4. Why? 계속 하기
바로 위에서 말한 dev dataset을 정했으면, 가설을 세우고 조건을 바꿔가며 실험하는 ablation test를 계속 해 볼 필요가 있는 것 같다.
이번 대회에서는 다른 요인들은 다 통일시키고 일반 loss와 focal loss, koelectra와 klue/roberta 등 특정 조건만 바꿔가면서 실험을 진행하였는데, 대회 뒤로 갈 수록 이런 실험을 덜 했던 것 같다. 모델 하나를 써도 왜 이 모델을 사용했는지, 이 모델을 썼을때 왜 성능이 잘 나왔는지 계속 고민한다면, 성능은 저절로 높아져 있을 것이라 생각한다.
1-5. 기타 질문들 및 배웠던 것들
- 앙상블을 할 때 JSD(Jenson-Shannon Divergence)를 활용하여 각 모델 별 예측 label들의 분포를 확인해(f1 score 60 이상인 모델 중) 분포가 먼 애들을 앙상블 모델로 선정하였더니 성능이 좋았다.
- 분포가 멀다는 것은(JSD가 크다는 것은) 그만큼 다양한 예측을 한 모델들을 섞어서 서로 보완할 수 있다는 것이기 때문에 성능이 좋았던 것 같다.
- 발표 팀 중 streamlit을 활용해 모델이 예측하는 label 분포 등을 시각화한 팀이 있었는데, 매우 인상적이였다. 다음번엔 꼭 해볼 것 이다.
- streamlit 뿐만 아니라, 서비스개발 기초에서 배운 다른 내용들도 가능하다면 시도해보자!
- mlflow의 장점 중 하나는 팀원들 각각이 사용한 모델을 쉽게 불러올 수 있다는 것인데, wandb 뿐만 아니라 mlflow를 사용해 보는 것도 좋은 시도인 것 같다.
- 대회를 할 때 이를 서비스 관점에서도 생각해보자. 이를테면 RE task를 어떤 서비스에 활용할 수 있을까 .. ?
2. NLP 프로젝트 관점에서의 회고
2-1. NLP에서 EDA의 중요성(+ 데이터 뜯어보기)
text data는 image나 tabular data에 비해서는 EDA가 덜 중요하다고 생각했다.
그러나 모델보다는 data가 중요하다는 것을 느끼며 EDA의 중요성을 다시 한 번 느낄 수 있었다.
특히, 대회 초반에만 EDA를 해보는 것이 아닌 모델이 잘 맞추지 못하는 data를 중간중간 살펴보며 모델의 학습 방식을 개선하고, 오탐률이 높은 data만 증강하는 등의 전략을 취하는 것은 성능 향상에 핵심적인 요소라고 생각한다.
Text data를 EDA를 할 때는 결측치나 라벨 분포, 문장의 길이(토큰 길이) 등 뿐만 아니라 외국어의 비율, 특수 문자는 어떤 것들이 사용되었는지 등도 살펴볼 수 있을 것이다. 무의미한 괄호로 부사어구가 있는 경우에는 이를 삭제하여 문장이 좀 더 압축적인 의미를 제공할 수 있도록 실험해 보는 것도 좋은 아이디어 인 것 같다.
2-2. 언제까지 정해진 PLM만 쓸 것인가(klue/roberta, koelectra 등)
대회를 진행하며 사용했던 모델은 대부분이 klue/roberta-large 였다. klue dataset을 활용하는 대회였고, 따라서 klue/roberta-large의 성능이 앞도적으로 좋았기 때문에 어쩔 수 없었던 것 같다.
그러나 실력의 향상 관점에서 BART, T5, GPT 등의 생성 모델 혹은 다른 plm을 활용해 보는 것도 큰 도움이 될 것 같다. 사실 앞에서 말했듯, 문제를 해결하는 방법은 여러가지가 있을 수 있으므로 모두가 사용하는 roberta가 아닌 새로운 방식으로 접근 해 보는 것도 좋은 인사이트를 얻을 수 있을 것이다.
2-3. Data augmentation은 별로일까?
2-3-1. 단순 복사
데이터 단순 복사는 박장원 멘토님이 처음 알려주신 방법이였는데, 이번 대회에서 사용해봤다.
내가 사용한 방법은 모든 데이터에 대해 2배, 3배를 복사한 후 랜덤으로 섞어 학습에 사용해보는 것이였는데 성능 하락이 있었다.
성능 하락의 원인은 dataset이 잘못된 경우(label이 잘못 매칭됨)도 분명 있을텐데, 모든 데이터 증강은 이러한 잘못된 데이터들 때문에 전체적으로 잘못된 방향으로 학습하기 때문이라고 생각한다.
데이터 단순 복사는 다른 팀에서 data수가 적은 label만 복사해서 학습시켰더니 성능 향상이 있었다고 한다.
2-3-2. backtranlation(역번역)
역번역은 level1때 큰 성능향상이 없었기 때문에, 별로 신경쓰지 않았다.
다만 papago를 활용해 "no-relation" class를 제외한 data들을 역번역 한 팀이 있었는데, 성능 향상이 있었다고 한다.
또 한국어→영어→한국어, 한국어→일본어→한국어 등의 모델들을 앙상블하여 사용했다고 했는데, 파파고 api도 시도해보면 좋을 것 같다.
2-3-3. AEDA / MLM
AEDA(문장에 특수문자 랜덤 삽입) 혹은 MLM을 사용한 data augmentation은 별로 시도해보지 못했는데, 다음번엔 이를 꼭 도전해볼 것이다. 특히 MLM을 활용한 data augmentation은 굉장히 시도해볼 가치가 있다고 생각한다.
2-4. Class Unbalancing
Class unbalancing은 이번 대회 뿐만 아니라 다양한 대회 및 실제 현업에서 자주 등장할만한 문제라고 생각한다.
이에 대한 해결책으로 이번에 Focal loss를 처음 알게 되었는데, 생각보다 성능 향상의 폭이 크지는 않았다.
정확히는 gamma 값에 따라 영향을 좀 받는 것 같았다. 김성현 마스터님은 1등 팀 발표 피드백에서 "focal loss를 사용하면 성능이 올랐을텐데, 그렇지 않다니 의아하다." 라고 말씀하셨는데 우리 팀 역시 base loss를 썼을 때가 성능이 더 좋은 경우가 많았기 때문에 다음 대회에서는 이에 대한 분석을 조금 더 해봐야겠다.
2-5. 바보같은 예측에 주목하자(오탐률)
결국 성능을 올리려면, 모델이 잘 맞추는 data는 잘 맞추도록 유지하면서 잘 맞추지 못하는 data에 주목해야 할 것이다.
학습을 하다보면 f1 score과 loss가 동시에 올라가는 경우가 있었는데, 학습을 통해 전체적으로는 잘 맞추는 방향으로 가지만 못 맞추는 data는 더욱 더 못 맞추게 되기 때문인 것 같다.
오탐률이 높은 data를 잘 살펴봐서(EDA) 이들만의 어떤 특징을 발견한다면, 이러한 data들만 추가적으로 학습(contrastive learning) 시킬 수도 있을 것이고, 이는 높은 성능 향상으로 이어질 것이다.
2-6. 기타 질문, 배웠던 것 및 개선 사항
- 모델 경량화 관점에서도 생각해보자 (RE task의 경우 Ours: cross-sentence ALB 와 논문을 찾았으나 적용해보지는 못함)
- baseline 코드에서는 warmup step이 500으로 설정되어있었는데, 전체 step / 2로 놓고 했을때 많은 경우 성능이 좋다고 하니 다음 대회에서는 이를 실험해보자!
- label들을 일일이 보면서 잘못된 label은 직접 수정했던 팀도 있었다고 하는데, (시간이 남는다면) 시도해볼 만 한 일이라 생각한다.
3. 앞으로의 계획(MRC 대회 계획)
- 가장 중요한 것은 다양한 논문을 찾아보는 것! 누구나 시도하는 방식 말고 다양한, 새로운 시도를 해보자(거인의 어깨 위에 올라서라)
- 다양한 방식, 새로운 시도를 했으면 그것을 표로 만들어 ablation test 결과를 꼭 제시하자.
- 대회를 체계적으로 진행하자!
'기타 > Naver Boost Camp' 카테고리의 다른 글
네이버 부스트캠프 AI Tech 4기 7주차 회고(level 1대회 회고_Semantic Text Similarity) (0) | 2022.11.09 |
---|---|
네이버 부스트캠프 AI Tech 4기 5주차 회고 (0) | 2022.10.24 |
네이버 부스트캠프 AI Tech 4기 1주차 회고 (6) | 2022.09.23 |
댓글