Project

[Project]문장 유형 분류 AI 경진대회

moonzoo 2023. 3. 7. 21:09

INTRO

평소에 NLP에 관심이 많아 프로젝트와 논문 공부를 하던 중 우연히 문장을 입력받아 문장의 ‘유형’, ‘시제’, ‘극성’, ‘확실성’을 예측하는 Text Multilabel Classfication Task의 DACON 문장 유형 분류 AI 경진 대회에 참가하게 됐습니다.

대회기간이 짧아 모델의 구조를 수정하기보다는 데이터의 품질을 향상시키고 여러 Pretrained모델 중 가장 성능이 잘나오는 몇개의 모델을 찾고자 했습니다.

- 데이터 증강, 데이터 전처리 기법을 사용해 데이터셋의 품질과 양을 향상시켰습니다.

- Pretrained 모델의 일부분을 얼리고 미세조정을 진행했습니다.

- 여러 한국어 Pretrained 모델의 성능을 비교해보면서 성능이 좋은 모델들을 앙상블 했습니다. 

이러한 과정들을 거쳐 상위 5%라는 결과를 얻었습니다.

https://dacon.io/competitions/official/236037/overview/description

 

문장 유형 분류 AI 경진대회 - DACON

분석시각화 대회 코드 공유 게시물은 내용 확인 후 좋아요(투표) 가능합니다.

dacon.io

 

라이브러리 설치 및 세팅

!pip install transformers

!pip install adabelief-pytorch == 0.2.0

라이브러리 설치와 불러오기를 진행합니다.

모델의 학습또는 추론 시 값이 달라지는 것을 방지하기 위해 난수 고정을 진행합니다.

데이터 로더와, 모델 학습시 배치사이즈를 지정해줍니다.

NUM_EPOCHS는 3~6 정도로 pretrained 모델마다 바꿔가면서 세팅해줬습니다.

L_RATE는 모델의 학습률, MAX_LEN은 Input text의 길이를 최대 128자로 자르겠다는 의미입니다.

 

EDA

Train / Test 데이터셋의 문장 길이를 보면 Train 데이터셋의 일부만 300자가 넘어갑니다.

1. 데이터 문장의 길이 = max_input_lenght = 256으로 설정

Train / Test 문장의 통계치를 보면 문장의 길이가 대부분 짧은 것을 확인하실 수 있습니다.

 

2. Train / Test 문장은 같은데 라벨이 중복인 경우가 있다. Train 문장만 중복 제거 처리

 

라벨 시각화를 진행해보면 72개의 라벨중 64개의 라벨만 존재하고 불균형이 심한걸 확인할 수 있다.

3. 4개의 유형을 각각 예측하는 모델 4개를 만들어 결과를 합치는 것이 성능이 더 좋을 수 있다.

 

Data Augmentation

학습 데이터를 늘리기 위해 Back-Translation, Random Swap 방식의 데이터 증강 기법을 적용했습니다. Back-Translation은 구축된 번역기 Papago 크롤링을 통해 train data의 text를 영어로 번역하고 번역된 text를 다시 한국어로 번역했습니다. 두 번의 번역을 거쳐 생성된 문장은 의미는 유사하지만, 사용되는 단어 종류나 위치가 다르기 때문에 새로운 train data로 활용했습니다. Random Swap은 문장 내 임의의 두 단어의 위치를 교체하는 방식입니다. 역시 기존의 문장과 다른 새로운 문장을 생성하기 때문에 새로운 train data로 활용했습니다. 

 

데이터 준비 및 전처리

데이터의 문장 컬럼을 보면 텍스트 전처리가 크게 필요하지 않은 깔끔한 뉴스 데이터입니다.

그래서 전처리에 텍스트 전처리에 초점을 두지 않고 데이터 증강과 모델링에 시간을 투자했습니다.

진행하면 좋을 수 있는 간단한 전처리는 특수문자, 이모티콘 제거 등이 있습니다.

데이터 라벨은 각 4가지 문장의 유형을 합친 것 입니다.

 

Label Encoding

4개의 유형을 각각 라벨인코더를 사용해 범주형 변수를 변환해주도록 합니다.

 

Dataset

BERT 모델에 들어갈 input 포멧에 맞게 데이터를 변환해줄 필요가 있습니다.

훈련 데이터와 테스트 데이터를 BERT 입력 포맷에 맞게 변환해 줍니다.

앞서 학습, 테스트 데이터셋 포맷 변환을 위해 만들어둔 함수를 학습 데이터와 테스트 데이터에 적용 시켜줍니다.

다음으로 dataloader을 사용했는데 dataloader은  데이터를 1개, 1개 학습을 시키는 방법도 가능하지만

Pytorch의 dataloader를 활용하면 Mini-Batch 단위의 학습이 가능하고 무작위로 데이터를 섞을 수 있다는 장점이 있기 때문에 거의 대부분의 파이토치 학습 코드에선 dataloader을 사용하고 있습니다.

여기서 주의 하실점은 테스트 dataloader에서는 shuffle을 False로 지정해주셔야 합니다.

 

모델링

우선 사용 모델은 허깅페이스의 klue/roberta-large를 사용했습니다. 다른 언어모델을 여러개 사용해봤지만 가장 안정적으로 타겟값을 괜찮은 성능으로 예측하는 모델이여서 klue 모델에 가장 많은 가중치를 줬습니다.

 

모델에서 일부분을 얼리고 미세조정을 진행했습니다.

데이터 셋의 크기와 성질에 따라 미세조정 방식이 조금씩 달라질 수 있습니다. 사용 시 상황에 따라 사용시 성능이 좋아질 수 있는데 지금 사용하고자 하는 대부분의 언어모델의 경우 같은 훨씬 큰 데이터에서 학습된 모델이고 같은 한글 데이터로 학습된 언어 모델이기 때문에 성질이 비슷할 것입니다. 그렇기 때문에 일부분을 얼리고 미세조정을 진행하는 것이 일반적으로 성능이 더 좋게 나오게 됩니다. 숫자를 조절해가면서 성능을 비교해보면 성능이 오르는 것을 확인하실 수 있습니다.

 

다음으로 학습 코드는 다른 코드들과 큰차이가 없으므로 생략하겠습니다.

다만 대부분의 코드와 다르게 여기서는 adabelief를 사용하였습니다. 이는 앞서 가볍게 언급했듯이 Adam을 수정한 옵티마이저로 Adam보다 성능이 좋다는 연구 결과가 있어 사용 했습니다.

평가지표는 대회에서 지정해준 weighted f1 score를 그대로 사용했습니다.

적합한 loss function을 찾기 위해 논문과 비슷한 사례들을 찾아봤고 focal Loss가 베이스라인의 loss인 Cross Entropy의 클래스 불균형 문제를 개선하는 장점이 있어 focal loss를 최종 loss function으로 선정했습니다. (예시코드에선 적용x)

 

모델 4개 생성

한 번에 모든 라벨을 예측하려면 4x3x3x2로 72가지의 라벨을 예측해야 하지만, 데이터가 부족해 64가지의 라벨 데이터밖에 존재하지 않았습니다. 그래서 유형별로 모델을 다르게 커스텀해 4개의 모델로 4가지 유형의 라벨을 각각 예측했습니다. 모델은 huggingface의 pretrained 모델을 사용했고 여러 pretrained 모델의 성능을 테스트하며 가장 좋은 조합을 찾고자 했습니다. 짧은 대회의 특성상 모델의 레이어를 모두 수정할 시간이 없어 pretrained 모델의 일부분을 얼리고 미세조정을 진행해 logit을 뽑아내고 Weighted Voting을 진행했습니다. 가장 성능이 좋게 나온 조합은 klue-roberta-large와 kobigbird를 미세조정 한 모델의 logit을 Weighted Voting을 한 것이었습니다.

 

깃허브에 이외에도 허깅페이스 모델을 사용해 여러 모델을 앙상블 하는 코드도 올려뒀으니 참고하시면 될 것 같습니다.

REVIEW 

이 외에도 모델별 커스텀 레이어, 하이퍼파라미터 튜닝 등 다양한 시도를 하고자 노력했지만 10일이라는 짧은 대회 기간과 학습 환경의 열악함으로 아쉽게 대회를 마무리하게 됐습니다. 그러나 전체 Private 14위로 상위 5%의 우수한 성적으로 첫 딥러닝 컴피티션을 마무리하는 결과를 얻었습니다. 딥러닝을 배우기 전까지는 머신러닝 공모전에만 참여할 수 있어서 활동 범위가 좁았는데 딥러닝을 공부하니 다양한 Task의 문제를 해결하기 위해 도전할 수 있어 딥러닝에 더 흥미를 갖게 된 계기가 됐습니다. 대회에서 사용한 프로그래밍 언어는 Python만을 사용했고 머신러닝 프레임워크는 Pytorch를 사용했습니다. pretrained model을 불러오기 위해 huggingface 라이브러리를 활용했습니다.

 

https://github.com/moonjoo98/DACON/tree/main/%5BDACON%5D%EB%AC%B8%EC%9E%A5%EC%9C%A0%ED%98%95

 

GitHub - moonjoo98/DACON: 2021~2022년에 참여한 DACON 공모전 정리입니다.

2021~2022년에 참여한 DACON 공모전 정리입니다. Contribute to moonjoo98/DACON development by creating an account on GitHub.

github.com