Skip to content

boostcampaitech6/level2-klue-nlp-10

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 

Repository files navigation

Lv.2 NLP KLUE 프로젝트 : 문장 내 개체간 관계 추출(RE)

개요

진행 기간: 24년 1월 3일 ~ 24년 1월 18일

데이터셋:

  • 학습 데이터셋 32,470개
  • 평가 데이터는 7,765개

평가 데이터의 50%는 Public 점수 계산에 활용되어 실시간 리더보드에 표기가 되고, 남은 50%는 Private 결과 계산에 활용되었습니다.

부스트캠프AI Tech 6기의 9~11주 차 과정인 NLP KLUE 대회입니다. 주제는 ‘문장 내 개체간 관계 추출’으로, 문장의 단어(Entity)에 대한 속성과 관계를 예측하는 자연어처리 N21 태스크인 관계 추출(Relation Extraction, RE)을 진행했습니다. 문장과 문장 내 subject_entity와 object_entity가 주어졌을 때 두 entity의 관계를 주어진 30개의 라벨 중 하나로 분류하는 task를 수행했습니다. no-relation 라벨을 제외한 micro-f1 scoreauprc로 평가합니다.

리더보드 결과


Fin-GPT

권예진 문지원 방제형 이경재 이종원

역할 분담

팀원 역할
권예진 EDA, validation set 구성, 앙상블 실험, K-Fold, marker 실험, GitHub 이슈및 main PR관리
문지원 모델 탐색 및 실험, EDA, focal loss 구현 및 실험, WandB logging 구현
방제형 EDA, 데이터 증강 방법 탐색 및 실험, GitHub main PR 관리, 개체 타입 제한 실험
이경재 모델 탐색 및 실험, prompt 실험, entity embedding 구현 및 실험, dropout rate 실험
이종원 코드 리팩토링 및 관리, 전처리 및 prompt, marker 실험, matching the blanks 실험

프로젝트 구조도

개발/협업 환경

하드웨어

Tesla V100 32GB * 5EA

소프트웨어 및 라이브러리

pandas==1.1.5
scikit-learn~=0.24.1
transformers==4.10.0
torch==1.10.0

GitHub

현업에서 진행하는 방식을 최대한 따르려고 노력했습니다. 이슈와 PR 템플릿을 작성하고, 팀 내의 커밋 컨벤션 규칙을 작성하여 후에 봐도 통일된 모습으로 쉽게 변경 사항을 찾을 수 있도록 했습니다. 기본 템플릿을 main 브랜치로 둔 뒤에, dev 브랜치에서 개발을 진행하였습니다. dev 브랜치에서도 새로운 기능을 개발할 때는 새로운 브랜치로 분기를 만들어 진행한 뒤 작성이 끝나면 dev 브랜치로 Pull Request를 작성하고, 팀원의 리뷰를 받은 뒤 병합을 진행하였습니다.

Notion

메인 Task 보드를 두고, 그곳에 자신의 업무 페이지를 작성하여 담당자를 할당한 후, 태그를 준비/진행 중/완료로 나누어 진행 상황을 공유했습니다. 해당 페이지에는 본인의 작업 기간을 표시하여 타임라인으로도 활용했습니다. 그리고 정보와 자료의 공유 공간으로 사용했습니다. 자신은 익숙하지만, 팀원들은 모를 수 있는 팁을 직접 작성하기도 하고, 팀원들이 읽어봤으면 하는 레퍼런스를 공유했습니다.

프로젝트 템플릿

주어진 Baseline 코드는 모델, 데이터로더, 학습까지 하나의 파일에 전부 작성되어 있었습니다. 앞으로 진행할 다른 대회에도 사용할 수 있도록 프로젝트 템플릿을 작성하여 그에 맞게 모듈화하여 구획하였습니다. 디렉토리는 원활한 실험을 위한 설정 파일을 담은 config, 학습, 검증, 평가, 증강 데이터를 담은 data, 학습이 끝난 모델과 inference 결과를 저장하는 output, 학습된 모델의 파라미터를 저장하는 checkpoint, Jupyter Notebook 작업을 수행하는 notebook, 데이터 전처리와 증강 등 다양한 곳에 사용한 모듈을 저장하는 utils으로 구분했습니다.

📦 level2-klue-nlp-10-RelationExtraction
├─ .github
│  ├─ .keep
│  ├─ ISSUE_TEMPLATE
│  │  ├─ bug_report.md
│  │  ├─ experiment.md
│  │  └─ feature_request.md
│  └─ PULL_REQUEST_TEMPLATE.md
├─ README.md
├─ code
│  ├─ .DS_Store
│  ├─ augmentation.py
│  ├─ best_model
│  │  └─ .ipynb_checkpoints
│  │     └─ empty.txt
│  ├─ custom_trainer.py
│  ├─ data_analysis.py
│  ├─ datasets.py
│  ├─ dict_label_to_num.pkl
│  ├─ dict_num_to_label.pkl
│  ├─ ensemble.py
│  ├─ inference.py
│  ├─ logs
│  │  └─ empty.txt
│  ├─ loss_function.py
│  ├─ metrics.py
│  ├─ model.py
│  ├─ prediction
│  │  ├─ .ipynb_checkpoints
│  │  │  └─ sample_submission-checkpoint.csv
│  │  └─ sample_submission.csv
│  ├─ preprocessing.py
│  ├─ requirements.txt
│  ├─ results
│  │  └─ empty.txt
│  ├─ split_data.py
│  ├─ train.py
│  └─ utils.py
└─ img

프로젝트 로드맵


데이터

Label 별 데이터셋 특징

id sentence subject_entity object_entity label source
0 〈Something〉는 조지 해리슨이 쓰고 비틀즈가 1969년 앨범 《Abbey Road》에 담은 노래다. "{'word': '비틀즈', 'start_idx': 24, 'end_idx': 26, 'type': 'ORG'}" "{'word': '조지 해리슨', 'start_idx': 13, 'end_idx': 18, 'type': 'PER'}" no_relation wikipedia
1 호남이 기반인 바른미래당·대안신당·민주평화당이 우여곡절 끝에 합당해 민생당(가칭)으로 재탄생한다. "{'word': '민주평화당', 'start_idx': 19, 'end_idx': 23, 'type': 'ORG'}" "{'word': '대안신당', 'start_idx': 14, 'end_idx': 17, 'type': 'ORG'}" no_relation wikitree
2 "이른바 'Z세대'로 불리는 1990년대 중반 이후 태어난 세대에게 대표 아이콘으로 통하는 미국 싱어송라이터 빌리 아일리시(본명 빌리 오코널, 19)가 팝 역사를 새로 썼다." "{'word': '빌리 아일리시', 'start_idx': 60, 'end_idx': 66, 'type': 'PER'}" "{'word': '싱어송라이터', 'start_idx': 53, 'end_idx': 58, 'type': 'POH'}" per:title wikitree

Validation set 생성과 최종 데이터셋 확정

데이터 증강

Back translation 방식을 활용하여 Google API로 한글을 영어로 번역한 뒤, 다시 한글로 번역하여 새로운 문장을 생성했습니다.


데이터 전처리와 성능 확인

Marker 사용

데이터의 라벨이 entity type과 밀접한 연관이 있다는 인사이트에 근거하여 sentence에 entity type 정보를 넣어줄수 있는 방법을 모색하고자 Marker를 사용하여 전처리했습니다.

Prompt type Input example micro-f1
s_sep_o 이순신[SEP]무신[SEP]이순신은 조선 중기의 무신이다. 70.75
s_and_o(와) 이순신과 무신의 관계[SEP]이순신은 조선 중기의 무신이다. 72.51
s_sep_o(&) 이순신 & 무신의 관계[SEP]이순신은 조선 중기의 무신이다. 72.49
question 이순신은 조선 중기의 무신이다.[SEP]이순신과 무신의 관계는 무엇입니까? 72.22

Prompt 활용

bert기반 pre-trained model을 사용하기 때문에 입력문장의 의미를 어느정도 이해한다고 생각했고, 따라서 문장 앞의 prompt부분을 더 다양한 양식으로 수정해 모델이 더 많은 정보를 이해할 수 있도록 했습니다.

Marker Type Input Example micro-f1
Basline 이순신은 조선의 무신이다. 72.51
Entity Mask [SUB-PER]은 조선의 [OBJ-JOB] 이다. -
Entity Marker [E1] 이순신 [/E1]은 조선의 [E2] 무신 [/E2]이다. -
Entity Marker Punct @ 이순신 @ 은 조선의 # 무신 # 이다. -
Typed Entity Marker <S:PERSON> 이순신 </S:PERSON>은 조선의 <O:JOB> 무신 </O:JOB>이다. 72.78
Typed Entity Marker Punct @ * 사람 * 이순신 @은 조선의 # ^ 직업 ^ 무신 # 이다. 73.45
Typed Entity Marker PunctV2 @ * 사람 * 이순신 @은 조선의 $ ^ 직업 ^ 무신 $ 이다. 73.73
Typed Entity Marker Non Object Type <S:PERSON> 이순신 </S:PERSON>은 조선의 무신 이다. 72.93

아키텍쳐 보완

Matching the Blanks 구현

Matching the blanks는 CLS 토큰 대신, Entity에 해당하는 token을 사용하여 RE task를 수행하여 성능 개선을 도모했다는 연구입니다. "ENTITY MARKERS – ENTITY START"를 구현했고, 뒤에 존재하는 ENTITY MARKER 토큰까지 사용하는 "ENTITY MARKERS – ENTITY START END"를 구현했다. 또한, CLS는 중요한 정보를 담고 있다고 생각했기에 CLS 토큰을 포함하도록 구현했습니다.

  • ENTITY MARKERS - [CLS] (Baseline) : [CLS] 토큰 사용.
  • ENTITY MARKERS - ENTITY START + [CLS] : [CLS], [E1] 토큰 사용.
  • ENTITY MARKERS - ENTITY START END + [CLS] : [CLS], [E1], [/E1] 토큰 사용.

marker matching the blank type micro-f1
typed entity marker no 72.78
typed entity marker entity start 73.38
typed entity marker entity start end 73.70

Relation Classification with Entity Type Restriction (RECENT) 구현

subject entity type과 object entity type의 조합이 추출해낼 수 있는 relation 유형이 제한되어 있으므로, Relation classification을 위해 entity type의 조합을 classifier에서 한정하는 방법론입니다.

RECENT Marker Type Micro-f1
No Typed_entity_marker_punct 73.4566
RECENT Typed_entity_marker_punct 73.0855

K-fold 구현

과적합을 방지하기 위해 K-fold 교차 검증을 시행했습니다. train 데이터의 label 불균형을 고려해 5개의 폴드로 나누어서 진행했습니다. 하지만 결과는 모든 train 데이터 전체를 학습한 것보다 높지 않았습니다.

Early Stopping 구현

학습시간을 줄이고 모델의 과적합을 방지하기 위하여 모델의 성능 개선이 미미할 때 조기에 학습을 종료시키는 early stopping을 적용하였습니다. patience값은 주로 3으로 설정했습니다.

Focal Loss Function 사용

Focal Loss Function을 사용하면 라벨 불균형 문제를 완화할 수 있을 것이라고 생각하고 기존의 손실함수인 Cross Entropy Loss Function을 사용했을 때와 비교하여 실험을 진행했습니다. 하지만 유의미한 성능 향상은 보이지 않아 최종 모델에서는 사용하지 않았습니다.

Loss function Micro_f1 auprc
Cross Entropy 73.4566 77.4988
Focal Loss 72.0505 78.1135

Dropout rate 변경

모델이 학습하는 과정에서 train의 score는 높아지는데 validation의 score가 낮아지는 양상을 보여 과적합이라고 생각했습니다. 기존의 0.1로 설정된 attention_drop_rate와 hidden_drop_rate를 변경해서 실험해보았습니다. 이때 dropout_rate를 높이면 계산되는 정보가 줄어들기 때문에 epoch도 변경해가며 진행하였습니다. 하지만 결과적으로 큰 성능의 향상은 없었습니다.

model epoch Micro_f1 auprc loss 비고
roberta-large 3 72.5172 75.1629 0.15655
roberta-large 3 71.4286 77.9807 0.1495
roberta-large 4 71.9271 74.6084 0.09437
roberta-large 4 72.2187 76.7080 0.09245
roberta-large 4 71.8731 76.3384 0.10485
roberta-large 3 72.4575 76.8794 0.15319
roberta-large 4 71.2468 75.8546 0.09478
roberta-large 3 71.5643 77.1326 0.15553

최종 Model 선택

  • 이번 RE task는 KLUE 데이터셋을 활용하여 진행했기에 klue 데이터로 fine-tuning된 모델에서 좋은 성능을 보였습니다. 특히, klue/RoBERTa-large가 다른 모델에 비해 높은 성능을 보였습니다.
  • 추가로 저희 팀에서는 klue/RoBERTa-base, klue/RoBERTa-large, klue/bert-base, monologg/KoELECTRA-base-v3-discriminator, vaiv/kobigbird-roberta-large, team-lucid/deberta-v3-base-korean, wooy0ng/korquad1-klue-roberta-large, kakaobank/kf-deberta-base 모델들을 실험했습니다.

앙상블

최종적으로 6개의 모델을 앙상블에 사용하였습니다.

Model prompt marker 특징 Public micro-f1 Ensemble Weight
klue/RoBERTa-large question typed entity marker punct 73.06 0.17
klue/RoBERTa-large s_and_o(&) no marker 72.22 0.15
klue/RoBERTa-large s_and_o(와) no marker 72.51 0.17
klue/RoBERTa-large s_and_o(와) typed entity marker punct 73.45 0.17
klue/RoBERTa-large s_and_o(와) typed entity marker punct K-Fold 73.34 0.17
klue/RoBERTa-large s_and_o(와) typed entity marker punctV2 73.73 0.17

최종결과

총 제출 횟수: 132

About

level2-klue-nlp-10 created by GitHub Classroom

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages