Project

오늘의 목표 및 진척상황

  • RoBERTa Special Token에 따른 Code 수정
  • Question 형태의 Text Pair 실험 설계
  • Question Text Pair와 Max Length 실험
  • Pororo를 활용한 Data Augmentation 실험

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

  1. RoBERTa Code 수정

    모든 Sentence에서 Unknown Token이 잡히지 않는 것이 의아해서, Tokenizer를 꼼꼼하게 확인해봤다. 생각지 못했는데, RoBERTa는 BERT와 다른 Special Token을 사용했다. 이전의 Code에서 Input Data를 생성할 때 [SEP]와 같은 구분자를 넣었었는데, 이게 적절하지 않았다는걸 뒤늦게서야 발견했다. 이에, Unknown Token을 찾는 Code와 Data를 Tokenizing 하는 Code를 수정하고, 재실험을 해야 했다.

    먼저, [SEP] 대신 RoBERTa의 구분자 Token인 </s></s>를 넣어서 성능을 확인했다. 신기하게도 기존보다 약 4%가량 성능이 하락했다. 애초에 이 모델을 알려줬던 캠퍼보다 내 Score가 월등히 높았던 게 이상했는데, 확실히 이 Score는 엉성함에서 온 이상한 성능이었던 게 맞는 것 같다. 기존에 엉뚱한 구분자를 사용했던 모델이 과연 일반화 성능이 좋을 것인지에 대해서는 의문이다. 아무튼, 앞으로는 실험의 객관성을 해치지 않기 위해 Tokenizer의 기존 구분자를 활용할 예정이다.

    Unknown Token은 <unk>였다. 신기하게도 tokenizer.tokenize(text)와 같이 검사를 할 경우, Vocab에 없더라도 <unk>로 Return하지 않았다. 검사 조건을 tokenizer.decode(tokenizer.encode(text))와 같이 작성해서 검토를 해야했다. 더 신기한건, 전체 Entity에서 잡힌 Unknown Token은 겨우 4개였고, 그 Text는 '뢴, 툠, 뇰, 쳅'이었다.

  1. Question Text Pair 실험 Code 설계

    기존의 Text에 Entity를 표시해야 했기에, <_sbj_>, <_obj_>라는 Special Token을 사용하기로 했다. 오늘 Team Meeting 덕분에, Text를 Replace하는 것이 위험할 수 있다는 것을 알게 되었다. Index 기준으로 Code를 다시 작성해야 했는데 이게 생각보다 까다로웠다. 각 Index와 Token을 쌍으로 저장했다가 뒤쪽 Index부터 Token을 채우는 식으로 구현했고, Pair로 입력될 Text는 간단하게 구현했다.

  1. Question Text Pair와 <unk> Token, Max Length 실험

    Question Sentence를 Pair로 입력한 실험에서는 76% 정도의 성능을 얻었다. Special Token을 정상적으로 고쳤던 Code에 비하면 약 2.5% 정도의 성능 향상이었다.

    다음으로는 Entity의 <unk> Token을 Vocab에 추가해서 학습을 진행했는데, 여기서 다양한 이슈가 있었다. 먼저, Tokenizer에 add_special_token이나, add_token을 하더라도 tokenizer.vocab_size가 늘어나지는 않는다는 것을 알게 됐다. 이것 때문에 Model의 Embedding Vector가 제대로 Resize 되지 않는 이슈가 발생했었다. 둘째로, 학습이 전혀 진행되지 않았다. 이는 아직도 의문인 점인데, 딸랑 4개의 Vocab이 추가 되었을 뿐인데 학습이 진행되지 않았다. Code상에 오류가 있을 수도 있겠으나, 기존에 사용하던 Code이고, BERT에서는 이상없이 학습이 되기 때문에 이는 아닐 것이라고 생각한다. 아무튼, 학습이 진행되지 않는 이슈에 경우 생각보다 다양한 원인을 파악해야 될 것 같다.

    그 다음으로는 Max Length를 조정해가며 실험을 진행했다. 최초에는 Default로 100을 사용했고, 150과 180에 대해 실험을 진행했다. Validation Loss 상으로는 유의미하게 큰 차이를 보이지는 않았지만, 각각 Loss가 최저점을 찍는 위치가 달랐다. Loss 상으로는 180이 가장 작은 값을 보여주었으나, LB기준 성능은 더 낮았다. 150은 100보다 0.6% 정도 높은 성능을 보였다.

  1. Pororo Data Augmentation을 위한 실험

    Office Hour간, 소개해주신 Pororo가 무엇인지 확인해봤다. MRC Task의 Example을 따라해보니, 엄청 쉽게 번역을 수행할 수 있었다. 이를 통해 Data Augmentation을 수행할 수 있으리라 생각됐다. 적용 이전에 Model의 다양한 정보를 확인하는 실험을 진행했다. 기본 문장을 다른 언어로 번역한 후, 한국어로 다시 번역해 이 안에 Entity 두 개가 온전히 있는지를 기준으로 했다.

    먼저, Base Model과 Fast Model의 성능을 파악했다. Base Model의 경우 50개 중 22개의 Data를 사용할 수 있었고, Fast Model은 17개로 큰 차이가 있었다. 이에 Base Model을 선택했다.

    둘째로, []나, $$, ""와 같은 기호를 Entity에 씌우는 방법을 실험했다. 모든 경우에 있어서 각 기호들이 온전히 남아있는 경우는 없었고, 번역 자체의 질이 떨어지며 Entity가 남는 경우도 훨씬 적었다. 이에 특별한 Sign은 사용하지 않는 것으로 결정했다.

    셋째로, 번역 시 Parameter를 실험했다. len_panelty는 문장이 길수록 Panelty를 주는 것인줄 알았는데, 오히려 반대였다. top_k와 top_p는 해당 갯수의 Text를 쉼표로 구분해서 출력해주는데, 큰 의미가 없었다. no_repeat_ngram은 문장 길이와는 무관하고, 번역의 질이 변경됐다. 위 값 모두 실험 결과 Default에서 가장 좋은 성능을 보여, 그대로 사용하기로 결정했다.

    넷째로, 각 언어별 성능을 확인했다. 50개의 Sample을 기준으로 영어의 경우 중 22개, 일본어는 17개, 중국어는 5개만 활용이 가능했다. 더 많은 데이터를 위해 삼중 번역도 확인해보았는데, 문장 자체의 퀄리티가 굉장히 낮아지는 문제가 생겼다. 중국어의 경우, 한국어 → 중국어 → 영어 → 한국어로 번역했을 때 7개의 Data가 활용 가능해지긴 했다. 하지만, 시간 대비 효율이 매우 낮은 작업이기에 후순위로 판단하고 있다.

    다섯째, Dataframe의 Broad Casting이 가능한지 실험했다. 위 번역 과정을 함수화해서, Dataframe에 apply하면 Broad Casting이 되지 않을까 생각해봤다. 위 방법과 각 Row에 Iterable하게 적용하는 방법의 시간을 Check해봤는데, 거의 동일한 시간이 걸렸다. 결국 Broad Casting의 방법을 찾지는 못했고, Colab에서 여러 개의 Session을 통해 작업을 진행하고 있다.

추가로 진행 할 사항

  • 추가 Data 활용한 실험
  • R-BERT와 같은 형태의 Model 및 Task 실험

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

[P2] Day 56  (0) 2021.04.26
[P2] Sunday 18 April  (0) 2021.04.26
[P2] Day 55  (0) 2021.04.26
[P2] Day 54  (0) 2021.04.26
[P2] Day 53  (0) 2021.04.26

+ Recent posts