다시 이음

MATCHSUM 구현하기 - 세부사항 확인 및 구현 본문

AI 일별 공부 정리

MATCHSUM 구현하기 - 세부사항 확인 및 구현

Taeho(Damon) 2022. 12. 13. 10:50

안녕하세요.

 

오늘은 사용할 데이터셋을 정하고 MATCHSUM을 구현하고 그 과정에서 겪은 문제점에 대해 적어보려고 합니다.

 

1. Choose Dataset

논문에서 사용한 데이터셋 정보

*Ext = 문서를 pruning한 후 문장의 개수(길이)

**Sel = 후보군 요약(C)을 구성하는 문장의 개수(길이)

***Size = 최종 후보군 요약문의 개수

논문에서 CNN/DM 데이터셋을 사용할때 가장 좋은 성능을 보여주기 때문에 한국어 데이터셋 중에 CNN/DM과 비슷한 형태의 데이터가 있는지 확인해보고 사용하도록 하겠습니다.

 

AI-HUB 데이터를 살펴봐서 사용할 수 있는 요약 데이터셋을 아래와 같이 정리했습니다.

  • 도서자료 요약 (다양한 주제 도서 원문 1천자 이내, 요약 1~5문장) (https://aihub.or.kr/aihubdata/data/view.docurrMenu=115&topMenu=100&aihubDataSe=realm&dataSetSn=93)
  • 논문자료 요약 (다양한 한국어 학술논문 및 특허명세서 원문 , 요약 2~4문장)
    (https://aihub.or.kr/aihubdata/data/view.do?currMenu=115&topMenu=100&aihubDataSe=realm&dataSetSn=90)
  • 문서요약 텍스트(신문기사, 기고문, 잡지기사, 법원 판결문 원문, 요약 3문장)
    (https://aihub.or.kr/aihubdata/data/view.do?currMenu=115&topMenu=100&aihubDataSe=realm&dataSetSn=97)

위의 표는 데이터셋 별 정보로 CNN/DM의 tokens 개수가 중요하다는 것을 이미 논문을 통해 파악해보았습니다.

 

데이터셋 원문 token 개수 요약문 token개수 요약문 개수
도서자료 요약 94 25 2
논문자료 요약 171 24 2
문서요약 텍스트 208 52 3

*데이터셋의 샘플 데이터를 사용하여 전체 데이터와는 다를 수 있습니다.

 

CNN/DM 데이터셋과 가장 비슷한 데이터는 문서요약 텍스트 데이터셋으로 진행하도록 하겠습니다.

 

 

2. Candidates Pruning

 

논문에서는 Candidates Pruning을 하기 위해서 BERTEXT 모델을 사용하여 5개의 후보군 요약을 추출합니다.

원 문서에서 5개의 문장만을 남겨두고 그 5개의 문서를 2개,3개 조합을 통해 20개의 후보군 요약을 생성하게 됩니다.

 

하지만 현재 사용하는 데이터의 경우 extractive 열에 문서요약 모델을 사용하여 추출한 값이 벌써 존재합니다만.. 코드를 확인한 결과 Textrank 모델과 SummaRuNNer모델을 사용했습니다.

 

그대로 사용하고 싶었지만 논문과 최대한 비슷하게 진행을 해보고 싶기때문에 KoBERTSum 모델을 사용해서 진행을 해보려고 했습니다.

 

문서 텍스트 요약 데이터셋을 모두 사용하는 것은 용량 및 시간이 너무 크게 들어서 validation 데이터셋에서 21306행 정도만 추출해서 사용하도록 하겠습니다.

 

Fine tuning에는 스포츠 기사 데이터를 textrank를 사용하여 라벨링한 데이터를 사용하였습니다.

논문과는 다르게 제가 사용한 kobertsum에는 trigram blocking 방법을 사용하여 중복문이 summary에 포함이 되지 않습니다.

 

Pruning 순서 정리

  • 원문서의 문장 개수를 5개로 pruning하기 위해 KoBERTSUM을 사용하였습니다.
    • 논문에서는 BERTEXT(trigram blocking 제외) 모델로 pruning을 합니다.
  • 5개의 문장을 2,3개 문장으로 조합하여 총 20개의 후보군 요약문을 작성합니다.
    • 이 과정에서 조합된 후보군 요약문을 pruing한 문장과 ROUGE score 연산하여 내림차순으로 정렬하였습니다.
    • matchsum 오픈소스 코드에서 get_candidate.py를 한국어에 맞게 변환하여 사용하였습니다.
  •  논문에서는 tokenizer의 encode 메소드를 사용하여 토큰화 하고 있고 스페셜 토큰을 수동으로 입력해주고 있습니다. 그보다 tokenizing을 통해 bert 모델에 넣기 쉽게 만드는 게 좋다고 생각해서 변환시켜주었습니다. 그래서 결과적으로 논문에서는 텍스트를 tokenizing을 하여 그 부분을 아래와 같이 가져오지만 저는 후보군 요약문과 원문, gold summary(중요 요약) 텍스트만을 가져오게 했습니다.

candidate pruning 논문 사용 방법 예시
변경 후 결과 예시

더보기

KoBERSUM 구조

#사용한 KoBERTSum 모델 구조
(bert): Bert(
    (model): BertModel(
      (embeddings): BertEmbeddings(
        (word_embeddings): Embedding(8002, 768, padding_idx=1)
        (position_embeddings): Embedding(512, 768)
        (token_type_embeddings): Embedding(2, 768)
        (LayerNorm): LayerNorm(torch.Size([768]), eps=1e-12, elementwise_affine=True)
        (dropout): Dropout(p=0.1)
      )
      (encoder): BertEncoder(
        (layer): ModuleList(
          (0): BertLayer(
            (attention): BertAttention(
              (self): BertSelfAttention(
                (query): Linear(in_features=768, out_features=768, bias=True)
                (key): Linear(in_features=768, out_features=768, bias=True)
                (value): Linear(in_features=768, out_features=768, bias=True)
                (dropout): Dropout(p=0.1)
              )
              (output): BertSelfOutput(
                (dense): Linear(in_features=768, out_features=768, bias=True)
                (LayerNorm): LayerNorm(torch.Size([768]), eps=1e-12, elementwise_affine=True)
                (dropout): Dropout(p=0.1)
              )
            )
            (intermediate): BertIntermediate(
              (dense): Linear(in_features=768, out_features=3072, bias=True)
            )
            (output): BertOutput(
              (dense): Linear(in_features=3072, out_features=768, bias=True)
              (LayerNorm): LayerNorm(torch.Size([768]), eps=1e-12, elementwise_affine=True)
              (dropout): Dropout(p=0.1)
            )
          )
          (1): BertLayer(
            (attention): BertAttention(
              (self): BertSelfAttention(
                (query): Linear(in_features=768, out_features=768, bias=True)
                (key): Linear(in_features=768, out_features=768, bias=True)
                (value): Linear(in_features=768, out_features=768, bias=True)
                (dropout): Dropout(p=0.1)
              )
              (output): BertSelfOutput(
                (dense): Linear(in_features=768, out_features=768, bias=True)
                (LayerNorm): LayerNorm(torch.Size([768]), eps=1e-12, elementwise_affine=True)
                (dropout): Dropout(p=0.1)
              )
            )
            (intermediate): BertIntermediate(
              (dense): Linear(in_features=768, out_features=3072, bias=True)
            )
            (output): BertOutput(
              (dense): Linear(in_features=3072, out_features=768, bias=True)
              (LayerNorm): LayerNorm(torch.Size([768]), eps=1e-12, elementwise_affine=True)
              (dropout): Dropout(p=0.1)
            )
          )
          (2): BertLayer(
            (attention): BertAttention(
              (self): BertSelfAttention(
                (query): Linear(in_features=768, out_features=768, bias=True)
                (key): Linear(in_features=768, out_features=768, bias=True)
                (value): Linear(in_features=768, out_features=768, bias=True)
                (dropout): Dropout(p=0.1)
              )
              (output): BertSelfOutput(
                (dense): Linear(in_features=768, out_features=768, bias=True)
                (LayerNorm): LayerNorm(torch.Size([768]), eps=1e-12, elementwise_affine=True)
                (dropout): Dropout(p=0.1)
              )
            )
            (intermediate): BertIntermediate(
              (dense): Linear(in_features=768, out_features=3072, bias=True)
            )
            (output): BertOutput(
              (dense): Linear(in_features=3072, out_features=768, bias=True)
              (LayerNorm): LayerNorm(torch.Size([768]), eps=1e-12, elementwise_affine=True)
              (dropout): Dropout(p=0.1)
            )
          )
          (3): BertLayer(
            (attention): BertAttention(
              (self): BertSelfAttention(
                (query): Linear(in_features=768, out_features=768, bias=True)
                (key): Linear(in_features=768, out_features=768, bias=True)
                (value): Linear(in_features=768, out_features=768, bias=True)
                (dropout): Dropout(p=0.1)
              )
              (output): BertSelfOutput(
                (dense): Linear(in_features=768, out_features=768, bias=True)
                (LayerNorm): LayerNorm(torch.Size([768]), eps=1e-12, elementwise_affine=True)
                (dropout): Dropout(p=0.1)
              )
            )
            (intermediate): BertIntermediate(
              (dense): Linear(in_features=768, out_features=3072, bias=True)
            )
            (output): BertOutput(
              (dense): Linear(in_features=3072, out_features=768, bias=True)
              (LayerNorm): LayerNorm(torch.Size([768]), eps=1e-12, elementwise_affine=True)
              (dropout): Dropout(p=0.1)
            )
          )
          (4): BertLayer(
            (attention): BertAttention(
              (self): BertSelfAttention(
                (query): Linear(in_features=768, out_features=768, bias=True)
                (key): Linear(in_features=768, out_features=768, bias=True)
                (value): Linear(in_features=768, out_features=768, bias=True)
                (dropout): Dropout(p=0.1)
              )
              (output): BertSelfOutput(
                (dense): Linear(in_features=768, out_features=768, bias=True)
                (LayerNorm): LayerNorm(torch.Size([768]), eps=1e-12, elementwise_affine=True)
                (dropout): Dropout(p=0.1)
              )
            )
            (intermediate): BertIntermediate(
              (dense): Linear(in_features=768, out_features=3072, bias=True)
            )
            (output): BertOutput(
              (dense): Linear(in_features=3072, out_features=768, bias=True)
              (LayerNorm): LayerNorm(torch.Size([768]), eps=1e-12, elementwise_affine=True)
              (dropout): Dropout(p=0.1)
            )
          )
          (5): BertLayer(
            (attention): BertAttention(
              (self): BertSelfAttention(
                (query): Linear(in_features=768, out_features=768, bias=True)
                (key): Linear(in_features=768, out_features=768, bias=True)
                (value): Linear(in_features=768, out_features=768, bias=True)
                (dropout): Dropout(p=0.1)
              )
              (output): BertSelfOutput(
                (dense): Linear(in_features=768, out_features=768, bias=True)
                (LayerNorm): LayerNorm(torch.Size([768]), eps=1e-12, elementwise_affine=True)
                (dropout): Dropout(p=0.1)
              )
            )
            (intermediate): BertIntermediate(
              (dense): Linear(in_features=768, out_features=3072, bias=True)
            )
            (output): BertOutput(
              (dense): Linear(in_features=3072, out_features=768, bias=True)
              (LayerNorm): LayerNorm(torch.Size([768]), eps=1e-12, elementwise_affine=True)
              (dropout): Dropout(p=0.1)
            )
          )
          (6): BertLayer(
            (attention): BertAttention(
              (self): BertSelfAttention(
                (query): Linear(in_features=768, out_features=768, bias=True)
                (key): Linear(in_features=768, out_features=768, bias=True)
                (value): Linear(in_features=768, out_features=768, bias=True)
                (dropout): Dropout(p=0.1)
              )
              (output): BertSelfOutput(
                (dense): Linear(in_features=768, out_features=768, bias=True)
                (LayerNorm): LayerNorm(torch.Size([768]), eps=1e-12, elementwise_affine=True)
                (dropout): Dropout(p=0.1)
              )
            )
            (intermediate): BertIntermediate(
              (dense): Linear(in_features=768, out_features=3072, bias=True)
            )
            (output): BertOutput(
              (dense): Linear(in_features=3072, out_features=768, bias=True)
              (LayerNorm): LayerNorm(torch.Size([768]), eps=1e-12, elementwise_affine=True)
              (dropout): Dropout(p=0.1)
            )
          )
          (7): BertLayer(
            (attention): BertAttention(
              (self): BertSelfAttention(
                (query): Linear(in_features=768, out_features=768, bias=True)
                (key): Linear(in_features=768, out_features=768, bias=True)
                (value): Linear(in_features=768, out_features=768, bias=True)
                (dropout): Dropout(p=0.1)
              )
              (output): BertSelfOutput(
                (dense): Linear(in_features=768, out_features=768, bias=True)
                (LayerNorm): LayerNorm(torch.Size([768]), eps=1e-12, elementwise_affine=True)
                (dropout): Dropout(p=0.1)
              )
            )
            (intermediate): BertIntermediate(
              (dense): Linear(in_features=768, out_features=3072, bias=True)
            )
            (output): BertOutput(
              (dense): Linear(in_features=3072, out_features=768, bias=True)
              (LayerNorm): LayerNorm(torch.Size([768]), eps=1e-12, elementwise_affine=True)
              (dropout): Dropout(p=0.1)
            )
          )
          (8): BertLayer(
            (attention): BertAttention(
              (self): BertSelfAttention(
                (query): Linear(in_features=768, out_features=768, bias=True)
                (key): Linear(in_features=768, out_features=768, bias=True)
                (value): Linear(in_features=768, out_features=768, bias=True)
                (dropout): Dropout(p=0.1)
              )
              (output): BertSelfOutput(
                (dense): Linear(in_features=768, out_features=768, bias=True)
                (LayerNorm): LayerNorm(torch.Size([768]), eps=1e-12, elementwise_affine=True)
                (dropout): Dropout(p=0.1)
              )
            )
            (intermediate): BertIntermediate(
              (dense): Linear(in_features=768, out_features=3072, bias=True)
            )
            (output): BertOutput(
              (dense): Linear(in_features=3072, out_features=768, bias=True)
              (LayerNorm): LayerNorm(torch.Size([768]), eps=1e-12, elementwise_affine=True)
              (dropout): Dropout(p=0.1)
            )
          )
          (9): BertLayer(
            (attention): BertAttention(
              (self): BertSelfAttention(
                (query): Linear(in_features=768, out_features=768, bias=True)
                (key): Linear(in_features=768, out_features=768, bias=True)
                (value): Linear(in_features=768, out_features=768, bias=True)
                (dropout): Dropout(p=0.1)
              )
              (output): BertSelfOutput(
                (dense): Linear(in_features=768, out_features=768, bias=True)
                (LayerNorm): LayerNorm(torch.Size([768]), eps=1e-12, elementwise_affine=True)
                (dropout): Dropout(p=0.1)
              )
            )
            (intermediate): BertIntermediate(
              (dense): Linear(in_features=768, out_features=3072, bias=True)
            )
            (output): BertOutput(
              (dense): Linear(in_features=3072, out_features=768, bias=True)
              (LayerNorm): LayerNorm(torch.Size([768]), eps=1e-12, elementwise_affine=True)
              (dropout): Dropout(p=0.1)
            )
          )
          (10): BertLayer(
            (attention): BertAttention(
              (self): BertSelfAttention(
                (query): Linear(in_features=768, out_features=768, bias=True)
                (key): Linear(in_features=768, out_features=768, bias=True)
                (value): Linear(in_features=768, out_features=768, bias=True)
                (dropout): Dropout(p=0.1)
              )
              (output): BertSelfOutput(
                (dense): Linear(in_features=768, out_features=768, bias=True)
                (LayerNorm): LayerNorm(torch.Size([768]), eps=1e-12, elementwise_affine=True)
                (dropout): Dropout(p=0.1)
              )
            )
            (intermediate): BertIntermediate(
              (dense): Linear(in_features=768, out_features=3072, bias=True)
            )
            (output): BertOutput(
              (dense): Linear(in_features=3072, out_features=768, bias=True)
              (LayerNorm): LayerNorm(torch.Size([768]), eps=1e-12, elementwise_affine=True)
              (dropout): Dropout(p=0.1)
            )
          )
          (11): BertLayer(
            (attention): BertAttention(
              (self): BertSelfAttention(
                (query): Linear(in_features=768, out_features=768, bias=True)
                (key): Linear(in_features=768, out_features=768, bias=True)
                (value): Linear(in_features=768, out_features=768, bias=True)
                (dropout): Dropout(p=0.1)
              )
              (output): BertSelfOutput(
                (dense): Linear(in_features=768, out_features=768, bias=True)
                (LayerNorm): LayerNorm(torch.Size([768]), eps=1e-12, elementwise_affine=True)
                (dropout): Dropout(p=0.1)
              )
            )
            (intermediate): BertIntermediate(
              (dense): Linear(in_features=768, out_features=3072, bias=True)
            )
            (output): BertOutput(
              (dense): Linear(in_features=3072, out_features=768, bias=True)
              (LayerNorm): LayerNorm(torch.Size([768]), eps=1e-12, elementwise_affine=True)
              (dropout): Dropout(p=0.1)
            )
          )
        )
      )
      (pooler): BertPooler(
        (dense): Linear(in_features=768, out_features=768, bias=True)
        (activation): Tanh()
      )
    )
  )
  (ext_layer): ExtTransformerEncoder(
    (pos_emb): PositionalEncoding(
      (dropout): Dropout(p=0.1)
    )
    (transformer_inter): ModuleList(
      (0): TransformerEncoderLayer(
        (self_attn): MultiHeadedAttention(
          (linear_keys): Linear(in_features=768, out_features=768, bias=True)
          (linear_values): Linear(in_features=768, out_features=768, bias=True)
          (linear_query): Linear(in_features=768, out_features=768, bias=True)
          (softmax): Softmax()
          (dropout): Dropout(p=0.1)
          (final_linear): Linear(in_features=768, out_features=768, bias=True)
        )
        (feed_forward): PositionwiseFeedForward(
          (w_1): Linear(in_features=768, out_features=2048, bias=True)
          (w_2): Linear(in_features=2048, out_features=768, bias=True)
          (layer_norm): LayerNorm(torch.Size([768]), eps=1e-06, elementwise_affine=True)
          (dropout_1): Dropout(p=0.1)
          (dropout_2): Dropout(p=0.1)
        )
        (layer_norm): LayerNorm(torch.Size([768]), eps=1e-06, elementwise_affine=True)
        (dropout): Dropout(p=0.1)
      )
      (1): TransformerEncoderLayer(
        (self_attn): MultiHeadedAttention(
          (linear_keys): Linear(in_features=768, out_features=768, bias=True)
          (linear_values): Linear(in_features=768, out_features=768, bias=True)
          (linear_query): Linear(in_features=768, out_features=768, bias=True)
          (softmax): Softmax()
          (dropout): Dropout(p=0.1)
          (final_linear): Linear(in_features=768, out_features=768, bias=True)
        )
        (feed_forward): PositionwiseFeedForward(
          (w_1): Linear(in_features=768, out_features=2048, bias=True)
          (w_2): Linear(in_features=2048, out_features=768, bias=True)
          (layer_norm): LayerNorm(torch.Size([768]), eps=1e-06, elementwise_affine=True)
          (dropout_1): Dropout(p=0.1)
          (dropout_2): Dropout(p=0.1)
        )
        (layer_norm): LayerNorm(torch.Size([768]), eps=1e-06, elementwise_affine=True)
        (dropout): Dropout(p=0.1)
      )
    )
    (dropout): Dropout(p=0.1)
    (layer_norm): LayerNorm(torch.Size([768]), eps=1e-06, elementwise_affine=True)
    (wo): Linear(in_features=768, out_features=1, bias=True)
    (sigmoid): Sigmoid()
  )
)

 

3. MatchSum

 

Matchsum 오픈소스 코드를 살펴본 결과, input data로 text_id(원문 token id), candidate_id, summary_id를 사용하는 것을 볼 수 있었고 fastNLP 라이브러리에 Trainer를 사용했지만 현재 버전에서는 fastNLP를 잘 사용하지 않고 변경되어 사용되지 않는 부분도 포함되어 있어 전체적으로 transformers Trainer로 변환하여 사용하기 위해 변경하였습니다.

 

논문 오픈소스의 dataloader.py 부분은 trainer 내의 collate_fn 부분에 tokenizing을 진행하게 하여 변환하였고 Metric에 사용되는 부분은 pytorch_metric_learning.losses 의 BaseMetricLossFunction을 사용하여 변환하였습니다.

 

훈련 시작 전에 파이프라인을 많이 건들여야 해서 시간 소비가 상당했고 훈련이 가능한 뒤 부터는 훈련에 필요한 GPU용량 확보가 어려워서 기존 논문에 사용한 파라미터에서 변경해서 진행했습니다.

 

  변경 전 변경 후
Candidate Summary 개수의 조정 Default: 20 8
Candidate Summary max_length Default: 180 180 유지 ( 대부분이 180 이상이기 때문에 더이상 줄이는 것은 좋지 않다고 판단)
Document max_length Default: 512 512 유지(원문 길이의 대부분이 512 근처였고 이 부분을 줄이면 요약성능이 확연히 줄어들 것이라 판단하여 유지)
Batch Size 조정 Default: 1 4(코랩프로에서 사용가능한 한계까지)
epoch 조정 Default: 5 3

 

구현하면서 생긴 문제점과 해결방법

  1. 오픈소스의 기반이 fastNLP라서 구성을 맞춰도 실행되지가 않았습니다. --> 해결을 위해 사용할 라이브러리를 변경하고 맞춰 구성을 변경하였습니다.
  2. fastNLP의 Trainer 사용이 불가하여 huggingface에 Trainer로 사용하는데 사용하는 Metric 구성이 달라서 customize 하였습니다.
  3. Matchsum 모델 조정중에 기본 코드와 변경하였을때 발생한 오류. shape '[1, 20, 768]' is invalid for input of size 768  --> 오픈소스에서 데이터 형태가 제대로 확인되지 않아서 발생한 오류로 text, candidate, summary의 데이터 형태가 다르게 입력되어야 정상 작동됩니다. 다음에 논문을 보고 구현을 한다면 데이터셋의 형태를 먼저 확인해야겠습니다.
  4. 오픈소스를 기본으로 두고 하다보니 계속해서 앞단계 변경을 해야하는 경우가 생깁니다. --> 하나씩 변경하기 보단 전체적인 구도를 파악하면 더 빠르고 실수 없이 구현할 수 있을 것 같습니다.
    1. fastNLP에서의 Trainer는 어떤지 모르겠으나 huggingface Trainer는 bert사용시 input_ids, attention_mask, token_type_ids가 필요한데 오픈소스에서 한 encode 방식으로는 진행할 수 가 없어서 통째로 변경.
    2. 오픈소스대로는 get_candidate하는 과정에서 candidate한 문장들을 모두 split하였다가 join하는 방법을 거치는데 이 과정을 간과했다가 model과 Trainer 변경하면서 input_size에서 오류가 계속 생겨서 확인하다가 발견하여 다시 return.
    3. 데이터프레임에 list형태로 저장된 columns가 csv로 저장하면 리스트가 아니라 갑자기 string이 합쳐진다는 걸 처음알았다.. json형태로 저장하고 다시 불러오니 그대로 형태가 유지되어 저장방법 변경.
    4. 저장 방법을 바꾸고 dataloader에 collate_fn이 제대로 작동하지 않아서 찾아보니 그동안 저장되던 text, summary 데이터가 문자열이 합쳐져있는 형태였어야 했는데 csv 저장방법때문에 운이 좋게 input 형태가 맞아들어간 것이었고 추가적으로 변경해줌.
  5.  GPU 용량 문제가 심각합니다.. 데이터의 양을 엄청 줄이고 candidate 개수도 8개로 통제하였지만 이것만으로도 1 epoch에 1시간 반정도가 소요될정도라 원래대로 실행하기에는 무리가 있었다.
  6. 훈련에는 성공하였으나 evaluate하는 부분에서 오류가 발생. 확인해보니 metric이 dataset 자료형이 아닌 데이터프레임이 와야 하는 것으로 데이터셋 정의 부분을 새롭게 변경.
  7. Trainer 라이브러리를 바꾸는게 쉽지가 않았다. 사용되는 arguments나 메소드 차이가 심해서 다 바꿔주어야 했고 심지어 제대로 되지 않으면 라이브러리 소스코드를 다 훑어봐야해서 그렇게 효율적인 것은 아닌 것 같다.
  8. evaluate를 하는 과정에서 너무나도 Rouge score가 낮아서 전체 코드를 다시 봤는데 이번엔 사용할 텍스트가 join되어 있으면 안되고 리스트 형태로 존재해야 사용이 가능한 형태.. 성능이 이상하리만큼 낮거나 높으면 의심해야한다를 다시 깨달았다.
  9. evaluate가 제대로 작동하지 않고, ealry stopping callback을 사용할 수 없던 이유는 predict된 predictions에 predictions, label_ids이 모두 None이 아니어야 evaluate가 작동을 한다.

 

4. MatchSum 결과

컴퓨팅 환경 문제로 train을 5epoch 밖에 못했지만 성능은

'ROUGE-1': 0.383,  'ROUGE-2': 0.195, 'ROUGE-L': 0.279 으로 데이터 크기가 21306행 밖에 되지 않는 것에 비해 좋은 성능을 보여줬습니다.

 

제가 구현한 Matchsum 모델은 아래의 링크를 통해 github에서 확인하실 수 있습니다.

 

GitHub - thogood212/MATCHSUM_Kor: MatchSum model - Korean version(Text Summarization)

MatchSum model - Korean version(Text Summarization) - GitHub - thogood212/MATCHSUM_Kor: MatchSum model - Korean version(Text Summarization)

github.com


처음으로 논문과 오픈소스를 통해서 구현을 시도해보고 많은 부분이 부족하다는 것도 알았고 데이터와 파이프라인, 사용하는 라이브러리에 대한 이해가 무엇보다 많이 중요하다는 걸 깨달았습니다. 

그리고 논문을 읽는 것도 중요하지만 그걸 소스코드 하나 없었다면 이렇게 할 수 있었을까라는 생각도 많이 하게 되어서 좀더 공부를 통해서 모델 전체의 구조나 데이터 연결을 빠르게 파악할 수 있게 노력해야겠다고 생각했습니다.