- Semantic Text Similarity (STS) Task
- 두 문장을 입력받고 두 문장의 의미적 유사도를 점수로 나타내기
- 두 문장이 의미가 유사할수록 높은 점수를 주고 그렇지 않을 수록 낮은 점수를 줘야함 (0점 ~ 5점 사이)
- 입력 및 출력 결과물
- 입력 : 문장 쌍의 id, 문장 1, 문장 2, 주어진 문장의 유사도 점수
- 출력 : 문장 쌍의 id, 평가 데이터에 있는 각 문장 쌍의 유사도 점수
- 환경
- 팀 구성 및 컴퓨팅 환경 : 5인 1팀. 인당 V100 서버를 VS code와 SSH로 연결하여 사용
- 협업 환경 : Notion, GitHub
- 의사소통 : Slack, Zoom
- 프로젝트 구조 및 사용 데이터셋
- 프로젝트 구조: Transformer 계열의 모델을 통해 구현한 Cross Encoder를 통해 각 문장의 유사도를 측정하고 그 값을 0에서 5사이의 값으로 스케일링 한 후 출력
- 사용 데이터셋: 문장 짝과 그 문장 짝의 유사도를 가지고 있는 데이터셋을 활용하였고 각각 Train은 9324개, Valid는 550개, Test는 1100개의 데이터로 이루어져 있음
팀원 | 구성 및 역할 |
---|---|
김주성 | Loss 함수 변경, Dropout 테스트, LR Scheduler 테스트 |
문지혜 | 모델 리서치, loss part 모델 성능 실험 |
이준범 | 데이터 증강, 하이퍼 파라미터 조정 |
정세연 | EDA, 데이터 전처리, 모델 성능 실험 |
홍찬우 | Cross validation, cosine scheduler, 모델 성능 실험 |
- 세부적인 수행 과정 및 목록 : 프로젝트 수행 과정
-
탐색적 분석 및 전처리 (학습데이터 소개)
- 학습데이터 소개
- 국민청원 게시판 제목 데이터, 네이버 영화 감성 분석 코퍼스, 업스테이지 슬랙 데이터에서 추출한 문장 사용
- 두 문장과 문장 쌍에 대한 유사도 데이터 사용
- 탐색적 분석
- 데이터의 분포 확인
- 데이터의 라벨 별 분포를 EDA를 통해
- Unknown Token 확인
- 데이터의 문장을 직접 보았을 때, 사람의 이름에 해당하는 정보는
<PERSON>
으로 가려 놓은 것을 확인할 수 있었음 ex . “ 님과 어제 저녁에 식사를 하였습니다!” <PERSON>
을 새로운 토큰으로 추가하여<PERSON>
를 [UNK] 토큰이 아닌 special token으로 학습할 수 있게 하였음
- 데이터의 문장을 직접 보았을 때, 사람의 이름에 해당하는 정보는
- re 라이브러리를 통한 데이터 전처리
- 문장 내 특수 문자와 자음, 모음이 단독으로 반복되는 경우를 전처리
- 필요 이상으로 반복되는 경우 3번 반복되는 형태로 통일시키는 방식으로 전처리를 수행하였음
- 문장 내 특수 문자와 자음, 모음이 단독으로 반복되는 경우를 전처리
- 문장 위치 교환을 통한 데이터 증강
- A, B 문장 짝을 B, A 문장 짝으로 바꾼 뒤 추가로 학습하는 것도 성능 향상에 도움이 될 것 같아 수행
- 학습 데이터가 2배로 많아져서 학습에 2배의 시간이 걸렸지만 성능이 꽤나 향상되었음
- 문장의 맞춤법 교정을 통한 데이터 전처리
- 문장 내의 맞춤법 교정을 수행하면 같은 단어가 다르게 표기되어 생기는 문제점을 해결할 수 있을 것이라는 생각으로 맞춤법 교정을 수행
- 큰 성능 상승을 가져오지는 못 했지만 소소한 성과는 거둘 수 있었음
- 데이터의 분포 확인
- 학습데이터 소개
-
모델 개요
- ELECTRA
- 2020년에 발표된 모델로 기존 BERT 계열의 모델들과 달리 대체 토큰 탐지라는 훈련 방식을 통해서 훈련을 하고 이를 통해서 ELECTRA는 기존의 모델들보다 더 적은 자원으로도 더 좋은 성능을 보여줌
- RoBERTa
- Dynamic masking 기법과 더 많은 데이터를 학습에 활용하여 BERT 모델을 더 강인하게 개선한 모델 (2019년 발표)
- KLUE 벤치마크가 있어, 한국어 STS task에 적용하기 용이하다는 장점이 있음
- ALBERT
- 2019년에 발표된 모델로 factorized embedding parameterization와 cross-layer parameter sharing를 통해 BERT보다 훨씬 적은 parameter로 더 좋은 성능을 보여줌
- ELECTRA
-
모델 선정 및 분석
- klue/RoBERTA_small & klue/RoBERTA_base & klue/RoBERTA_large
- 프로젝트 초반, 한국어 NLP 벤치마크인 KLUE를 통해 모델 학습을 진행하였음.
- 해당 모델을 기반으로 옵티마이저, loss 등 모델의 구조를 변경하고, 하이퍼파라미터를 조정하여 다양한 실험을 시도하였음
- smartmind/albert-kor-base-tweak
- 동일 조건으로 학습 시 klue/roberta보다 좋은 성능을 보이지 못해 사용하지 않음
- snunlp/KR-ELECTRA-discriminator ✅
- 프로젝트 후반, RoBERTa 모델이 일정 수준 이상으로 성능이 개선되지 않아 학습을 시도한 모델
- 동일 조건으로 학습 하였을 때, 조사한 모델 중 가장 높은 성능을 달성함
- klue/RoBERTA_small & klue/RoBERTA_base & klue/RoBERTA_large
-
모델 평가 및 개선 방법
- 데이터 증강
- Train Dataset과 Validation Dataset의 score label 불균형을 맞춰주기 위해 압도적으로 수가 많은 0점대 문장을 고정하고, 나머지 점수대의 sentence1, 2를 서로 바꿔 데이터 증강
- 데이터 전처리 작업
- Unknown Token 중
<PERSON>
token을 corpus에 추가 - 문장 내 특수 문자와 자음, 모음이 단독으로 반복되는 경우를 전처리
- 맞춤법 오류 바로잡기
- Unknown Token 중
- Loss function 변경
- L1 Loss를 MSE(L2) Loss로 변경
- 사용하는 데이터가 0~5 사이로 범위가 정해져있기때문에 이상치에 강한 L1보다는 Regularization에 좋은 L2를 사용하는 것이 좋을 것 같아 사용했고 성능이 향상되었음
- BCE Loss, Contrastive Loss 등 다양한 loss function 적용
- STS task에 적용 가능하거나, 성능 향상을 도모할 수 있는 loss 를 적용해 보았으나 성능 향상에 도움이 되지 않거나, 학습이 제대로 이루어지지 않음
- L1 Loss를 MSE(L2) Loss로 변경
- Dropout
- 모델의 과적합을 Dropout을 방지하기 위해 Dropout을 0.1로 적용하였더니 성능이 향상되었음, 하지만 Dropout의 비율이 높아지면 오히려 성능이 떨어지는 모습을 보였음
- 앙상블
- 서로 다른 조건에서 학습된 모델들의 앙상블을 통해서 성능 상승을 이루어냈음
- 앙상블 결과를 구할 때, 평균값으로 값을 구하였는데 이때 단순히 각 모델 출력값들의 평균을 사용하는 것보다 각 모델들의 출력 값에 시그모이드 함수를 취한 후 평균을 내고 그 값에 다시 역 시그모이드 함수를 취하는 것이 더 좋은 결과를 낼 수 있을 것 같아 적용하였고 약간의 성능 상승을 이루어냈음
- 데이터 증강
-
모델 성능
index | Model | Test Pearson | Data handling | 비고 |
---|---|---|---|---|
1 | snunlp/KR-ELECTRA-discriminator | 0.9336 | 문장 순서 변경 | 10 epoch |
2 | snunlp/KR-ELECTRA-discriminator | 0.9295 | 문장 순서 변경 | 30 epoch |
3 | snunlp/KR-ELECTRA-discriminator | 0.9304 | 자음/모음 단독으로 반복 전처리, 사람 토큰 추가, 문장 순서 변경 |
25 epoch |
4 | snunlp/KR-ELECTRA-discriminator | 0.9317 | 자음/모음 단독으로 반복 전처리, 사람 토큰 추가, label 1 이상인 데이터에 대해서만 문장 순서 변경 |
25 epoch |
5 | snunlp/KR-ELECTRA-discriminator | 0.9325 | 맞춤법 교정 전처리, label 1 이상인 데이터에 대해서만 문장 순서 변경 |
25 epoch |
- 최종 제출 모델 : [1],[4],[5] 앙상블 모델 (test pearson : 0.9307)
- 제출 모델 중 가장 성능이 좋은 모델 : [1],[4] soft voting 앙상블 모델 (test pearson :0.9337)
-
잘한 점들
- EDA를 통해 데이터의 라벨 별 데이터 분포를 확인하고 이를 바탕으로 데이터 전처리 및 증강을 수행하였으며, 이 과정에서 다양한 자연어 데이터의 증강 기법을 알아보았다.
- 가설을 세우고 검증하는 방식으로 프로젝트를 진행하였다.
- 팀원 각자 가설을 검증한 내용을 팀에 공유를 잘해서 진행 상황을 알기 쉬웠다.
- 대회 끝까지 최선을 다했다!!
-
시도 했으나 잘 되지 않았던 것들
- LR_scheduler을 적용해 보았으나 성능 향상이 이루어지지 않음
- pre-trained 모델의 optimal Scheduler을 확인하고 선택해야 함
- optimal Scheduler을 적용한 경우에도 scheduler을 적용하지 않았을 때 더 성능이 높은 경우도 있었음
- LR rate 변경
- 다양한 LR rate를 테스트해보았는데 기존보다 성능이 좋아진 경우가 없었음
- MSE Loss 이외의 다양한 loss function 사용
- 문제의 출력을 0~1 사이의 값으로 변환해서 이진 분류 문제에 사용되는 BCE Loss를 사용하면 성능이 더 좋아지지 않을까 생각해서 시도했지만 성능이 나아지지 않았음
- Data에서 영어, 특수 문자 제거
- Data에 순수한 한글만 남아있으면 한국어 모델에서 더 좋은 성능을 보여줄 것이라 생각했지만 그렇지 않았음, 영어와 특수문자가 가지는 의미를 생각하지 않고 그냥 삭제해버려서 그런 것 같음
- 한국어 문장을 영어로 번역해서 사용
- 다양한 API를 사용해 번역을 시도했지만, 번역 성능이 너무 안 좋거나 시간이 오래 걸려 깊게 연구하지 못 했음
- 문장 내 단어 순서 바꾸기를 통한 데이터 증강
- 본래 문장의 의미가 훼손되므로 성능에 유의미한 변화가 없었다.
- LR_scheduler을 적용해 보았으나 성능 향상이 이루어지지 않음
-
아쉬웠던 점들
- 깃헙을 통한 코드 공유를 하지 않았다.
- 역할 분담을 하기 보다, 각자 스스로 가설을 세우고 확인하는 식으로 했기에 협업이 부족했다.
- 모델을 선정하고 테스트를 할 때 성능 향상에만 신경을 쓰고, 왜 잘되는지 고민이 부족했다.
- 하나의 팀이라기보다는 5명의 개인이었다.
-
프로젝트를 통해 배운 점 또는 시사점
- 프로젝트 계획을 구체적으로 짜고, 역할 분담을 명확하게 하여 효율적인 프로젝트 수행이 필요하다. 프로젝트 로드맵을 세우고, 그 과정 안에서 각자 수행해야하는 내용(역할 분담)을 나누어 매번 진행상황을 공유해야함을 알게 되었다.
- Pytorch Lightning 코드의 구조를 알고 baseline에 추가적인 기능을 구현할 수 있게 되었다.
- Cross Validation(k-fold)의 개념을 정확히 이해하게 되었다.
- 모델 선정과 데이터 전처리 및 증강이 성능 향상에 가장 중요하다는 것을 알게 되었다.
- 가설을 많이 세우는 것보다 중요한 것 3~4개를 세우고 정확히 검증하는 것이 더 중요함을 깨달았다.
- 단순히 논문을 보고 따라하는 것이 아니라 논문을 보며 어떻게 자신의 상황에 적용할 수 있을지를 고민해보아야 한다는 것을 알게 되었다.
- EDA를 통해 데이터를 평가하고 데이터 전처리나 증강을 하는 것이 중요함을 깨달았다.
- 베이스 라인 코드를 보며 데이터가 어떻게 모델에 입력되고 모델을 지나서 어떤 아웃풋이 나오고 그 아웃풋이 어떤 함수를 거쳐 score가 만들어지는지 볼 것 (파이프라인 어떻게 구성되어 있는지 보는 것!)
- 가설을 세우고 이 가설을 검증할 실험을 한다! 가설을 세울 때, 팀원들과 같이 고민해보고 각자 서로 다른 방법을 실험해보는 것이 가장 효율적일 것이다!
- 작은 모델로 가설을 검증하고 그 가설이 맞다고 판단되면 더 큰 모델에 적용된다! 낮에 가설검증, 실험하고 밤에는 GPU 돌려놓고 잠자고 일어나기
- 다른 코드를 참고해도 되나, 성능이 왜 좋게 나오는지에 대해 깊게 고민해야 됨! 그리고 참고한 코드에서 더 나아가 보기!