Skip to content

Data_Processing_for_Multi_Task_Pretrain

think_wisely edited this page May 24, 2021 · 2 revisions

1. Why

  • Custom Model은 Hugging Face에서 제공하는 Model과 다른 특징을 가지고 있다.
  1. 새로 정의된 Layer들은 초기화 된 Parameter 값을 가지고 있다.
  2. Custom Model의 Size가 더 크고 깊은 형태로 구현되어 있다.
  3. Multi Task 형태의 Branch를 갖는 Model이 있다.
  • 위와 같은 이유로 인해서, Model 형태에 적합하고 Pre-train에 사용할 Dataset이 필요했다.

2. Processing

  • AI Hub에서 제공하는 QA Data를 우리의 목적에 맞게 처리하는 과정이다.
  • Json Parsing 후, Model Input에 적합한 Dataset 형태로 구성했다.

3. Code

# 파일 불러오기. 해당 파일은 AI Hub로 부터 받을 수 있음. 파일 경로에 유의할 것.
import json
with open('outer_datas/ko_nia_normal_squad_all.json', encoding='utf-8') as json_file :
    normal_data = json.load(json_file)
# Json Parsing해서 List로 저장하기.
from tqdm import tqdm

question_type_map = {'work_how':0, 'work_what':1, 'work_when':2, 'work_where':3, 'work_who':4, 'work_why':5}
context_lst = []
question_lst = []
answers_lst = []
qa_id_lst = []
question_type_lst = []

for datas in tqdm(normal_data['data']) :
    context = datas['paragraphs'][0]['context']
    for qas in datas['paragraphs'][0]['qas'] :
        question = qas['question']
        answer_start = qas['answers'][0]['answer_start']
        answer_text = qas['answers'][0]['text']
        qa_id = qas['id']
        question_type = question_type_map[qas['classtype']]

        context_lst.append(context)
        question_lst.append(question)
        answers_lst.append({'answer_start':[answer_start], 'text':[answer_text]})
        qa_id_lst.append(qa_id)
        question_type_lst.append(question_type)
# Dataset 형태로 만들기.
from datasets import Dataset, Features, Sequence, Value, DatasetDict

ai_hub_dataset = Dataset.from_dict({'id' : qa_id_lst,
                                    'context' : context_lst,
                                    'answers' : answers_lst,
                                    'question' : question_lst,
                                    'question_type' : question_type_lst
                                   })
# 각종 함수 등 정의.
import re
import pickle

def save_pickle(save_path, data_set):
    file = open(save_path, "wb")
    pickle.dump(data_set, file)
    file.close()
    return None

def preprocess(text):
    text = re.sub(r'\n', ' ', text)
    text = re.sub(r"\\n", " ", text)
    text = re.sub(r"\s+", " ", text)
    text = re.sub(r'#', ' ', text)
    text = re.sub(r"[^a-zA-Z0-9가-힣ㄱ-ㅎㅏ-ㅣぁ-ゔァ-ヴー々〆〤一-龥<>()\s\.\?!》《≪≫\'<>〈〉:‘’%,『』「」<>・\"-“”∧]", "", text)
    return text

def run_preprocess(data_dict):
    context = data_dict["context"]
    start_ids = data_dict["answers"]["answer_start"][0]
    before = data_dict["context"][:start_ids]
    after = data_dict["context"][start_ids:]
    process_before = preprocess(before)
    process_after = preprocess(after)
    process_data = process_before + process_after
    ids_move = len(before) - len(process_before)
    data_dict["context"] = process_data
    data_dict["answers"]["answer_start"][0] = start_ids - ids_move
    return data_dict

new_f = Features({'answers': Sequence(feature={'text': Value(dtype='string', id=None), 'answer_start': Value(dtype='int32', id=None)}, length=-1, id=None),
                  'context': Value(dtype='string', id=None),
                  'id': Value(dtype='string', id=None),
                  'question': Value(dtype='string', id=None),
                  'question_type' : Value(dtype='int32', id=None)
                })
# Train과 Validation을 나누기 위한 Index 생성 작업.
import numpy as np

valid_indeces = np.random.choice(len(ai_hub_dataset), 1000, replace=False)
train_indeces = np.array(list(set(range(len(ai_hub_dataset))) - set(valid_indeces)))
# 최종적으로 Dataset Dict로 만듦.
import pandas as pd

ai_hub_train_datset, ai_hub_valid_datset = [], []
for data in ai_hub_dataset.select(train_indeces) :
    ai_hub_train_datset.append(run_preprocess(data))
for data in ai_hub_dataset.select(valid_indeces) :
    ai_hub_valid_datset.append(run_preprocess(data))

ai_hub_train_datset = pd.DataFrame(ai_hub_train_datset)
ai_hub_valid_datset = pd.DataFrame(ai_hub_valid_datset)
ai_hub_dataset = DatasetDict({'train': Dataset.from_pandas(ai_hub_train_datset, features=new_f), 'validation': Dataset.from_pandas(ai_hub_valid_datset, features=new_f)})
# Dataset Dict 저장하기. 파일 경로 수정 필요.
save_pickle("/opt/ml/outer_datas/ai_hub_dataset.pkl", ai_hub_dataset)

4. Result

  • 위와 같이 정제된 Data를 Pre-train에 사용할 수 있었다.
  • Pre-train의 유무를 기준으로 동일비교 했을 때, 약 5%가량의 성능 차이를 확인할 수 있었다.
  • 최종 Solution에 사용된 모든 Model은 위 Data로 Pre-train 되었다.