(5강) BERT 기반 단일 문장 분류 모델 학습

💡
주어진 문장에 대해 특정 라벨을 예측하는 모델에 대해 알아본다.

KLUE 데이터 셋 소개

KLUE란, 한국어 자연어 이해 벤치마크를 의미한다. 이는 살면서 직면하게 되는 거의 모든 자연어 Task의 유형을 포함하고 있다. 문장 분류, 관계 추출, 문장 유사도, 자연어 추론, 개체명 인식, 품사 태깅, 질의 응답, 목적형 대화 등이 존재한다.

이 중에서도 의존 구문 분석은 단어간의 관계를 분석하는 Task로, 자연어 이해에 있어 매우 중요한 Task이다.

단일 문장 분류 Task 소개

문장 분류의 세부적인 Task를 살펴보면 다음과 같다.

위와 같은 Task를 수행하기 위해, 한국어로 구성된 Dataset도 존재한다.

  • Kor_hate : 혐오 표현과 공격적이거나 비꼬는 문장에 대한 데이터
  • Kor_sarcasm : 비꼬는 표현의 문장 데이터
  • Kor_sae : 다양한 형태의 질문과 명령으로 이루어진 문장 데이터
  • Kor_3i4k : 단어나 문장 조각, 평서문, 수사적인 질문 등의 데이터

단일 문장 분류 모델 학습

BERT는 [CLS] Token의 Vector를 이용해 Classification을 수행한다. 이 Vector를 Dense Layer에 통과 시켜, 우리가 원하는 Task에 맞도록 Class에 대한 Logit을 Return하도록 설계한다.

주요 매개변수는 다음과 같다.

실습 코드

단일 문장 분류


Reference

BERT Fine-Tuning

Sequence Classification

네이버 영화리뷰 감정분석

Sentiment Analysis with BERT

BERT Text Classification Using Pytorch


Project

오늘의 목표 및 진척상황

  • Custom Loss 실험
  • Tokenizing Max Length 실험
  • Classfication Layer Dropout 실험
  • Baseline 개선
  • 다양한 Model 성능 실험
  • 외부 데이터 정제 및 실험

직면했던 문제와 학습한 내용

  1. Custom Loss 실험

    Idea는 Test Set의 분포도 Train Set과 마찬가지로 Imblance하다고 예상되니, 다수의 Class에 대해 집중하는 형태의 Loss를 사용하는 것이었다.

    Loss를 적용하기 위해서 Trainer 객체에 Loss를 입력하는 방식을 살펴보니, 단순히 Parameter에 넘겨주는 형식이 아니었다. Trainer 객체를 상속 받은 Class를 정의하고, 그 안에서 compute_loss Method를 Overriding해야하는 구조였다.

    Loss는 Weighted Cross Entropy의 형태로 구성했는데, Weight는 각 Label의 갯수에 비례해서 가중치를 받을 수 있도록 설계했다. 성능은 오히려 감소했고, Weight에 Gamma 값을 추가해서 이것저것 실험해봤지만 결국 기본 Loss가 가장 좋은 성능을 보였다.

  1. Tokenizing Max Length 실험

    Team에서 좋은 Idea를 공유해줬다. 이전에 토론 글은 아무 생각없이 지나쳤는데, 팀원이 다시 얘기해주니 이제서야 들렸던 것 같다. 요는, Tokenized Text가 Default로 설정된 100보다 긴 경우가 많다는 것이다. 팀원의 성능도 향상되었고, 현재 Score가 1위인 팀원도 적용한 Idea이기에, 즉각 실험을 진행했다. 그런데 이상하게도, Public LB에서 Accuracy Score가 떨어지는 결과가 나왔다. 현재 최고 Model을 기준으로 Validation Set Loss가 거의 유사했던 것으로 보아, Test Set의 갯수 부족으로 인한 현상으로 생각된다. 추후에 재실험을 진행할 필요가 있는 Idea이다.

  1. Classification Layer Dropout 실험

    Model의 Architecture를 살펴보니, Embedding Layer와 Classification Layer의 Dropout Layer가 따로 구성되는 것을 확인했다. 이전에 Hidden Layer의 Dropout Probability 실험은 완전 실패했었으나, 왠지 모르게 Dropout에 대한 맹신으로 재실험을 진행했다. Classification Layer의 Dropout만 아주 살짝 바꿨는데, 즉각 성능이 하락하는 것을 확인했다. 너무나도 아쉽지만, 이번 대회에서는 사용하지 못할 것으로 보인다.

  1. Baseline 개선

    꾸준히 Baseline을 개선해나가고 있다. 오늘은 가장 첫 Cell에 wandb.config 객체를 생성하고, 이에 따라서 모든 학습 일정이 조정되도록 개선했다. 즉, 첫 Cell에 대한 값만 살짝 바꿔주는 것으로 실험을 진행 할 수 있게 되었다. 처음에 구성할 떄는 몸이 배배 틀렸었는데, 한 번 구성하고 나니까 이렇게 편할 수가 없다. (Wandb도 설정할 때는 죽을 것 같았는데, 오늘 톡톡히 효과를 본 것 같다.)

  1. 다양한 Model 실험

    Default로 주어진 Model로는 한계가 있다고 판단되어, 다양한 Model을 실험했다.

    먼저, 좋다고 알려져 있는 KoElectra Model로 실험을 시작했다. KoElectra-small Model을 학습시키는데, 1000 step이 넘어가도 전혀 학습이 되지 않았다. Code의 문제인 것 같아 Code를 뜯어보는데, 아무리 뜯어봐도 문제를 찾을 수가 없었다. 자포자기한 상태로 오래 내버려두니 1500 step이 넘어서야 학습이 되는 것 처럼 보였다. KoElectra-base Model도 즉각적인 학습은 되지 않고, step이 조금 지나서야 학습이 되기 시작했다.

    KoElectra-small은 성능이 너무 낮고, KoElectra-base는 BERT와 큰 차이가 없었다.

    이후, 토론 게시판이나 캠퍼들의 정보를 통해 XLM-RoBERTa Model을 알게 되었고, 실험을 진행했다. 사실 큰 기대를 안했는데, 예상을 못할 정도로 높은 성능을 보였다. (현재 LB 기준 2위) Base Model은 BERT와 크게 다르지 않았으나, Large Model은 확실한 성능 향상을 보여주었다.

    보라색 선(Large Model)이 검은색 선(Baseline)보다 Loss가 낮고, Acc가 높은 것을 볼 수 있다.

    이후, KoBERT와 같은 모델을 학습시켜보았으나 여기서는 좋은 성능을 얻을수는 없었다.

  1. 외부 데이터 정제 및 실험

    Data에 대한 처리가 관건이라는 생각이 들어서, Master님이 소개해주신 'Kor-RE-Gold'의 Data를 정제하기 시작했다. 정제를 계속 하다보니, 처리할 요소는 많은데, 실질적으로 Data가 많은 것은 아니었다. 이래저래 Data를 탐색하고 있었는데, 토론 게시판에 '김규진' 캠퍼와 '오수지' 팀원이 올려준 Data를 찾아볼 수 있었다. '김규진' 캠퍼가 공유해준 Data에 대해서 먼저 실험을 하고 있는데, Data가 너무 많고 중간 결과가 좋지 않은 상태이다.

    매우 불안정한 학습을 보여, LR을 낮추고 다시 실험했으나, 성능 향상이 기대되지 않는다.

추가로 진행 할 사항

  • 외부 Data 탐색 및 실험
  • Cosine LR Scheduler 실험
  • Subject, Object Token 및 Embedding Layer 추가 실험
  • Dense Layer 추가 실험
  • 대괄호로 묶어서 이중 번역 돌리는 Text Augmentation
  • Pororo Library 확인
  • Input 형태 변경으로 Task 치환

'네이버 부스트캠프 AI Tech' 카테고리의 다른 글

[P2] Sunday 18 April  (0) 2021.04.26
[P2] Saturday 17 April  (0) 2021.04.26
[P2] Day 54  (0) 2021.04.26
[P2] Day 53  (0) 2021.04.26
[P2] Day 52  (0) 2021.04.26

+ Recent posts