💡 Early Risk Detection 베이스라인 코드가 어떤 flow를 가지는지 알아봅시다.
데이터셋을 구성하는 방법입니다.
기본적으로 PAN12를 사용하고 있습니다.
이 데이터는 .json 형식으로 구성 돼 있는데
로 구성되어 있습니다.
이 클래스는 raw dataset을 구축하는 역할을 수행합니다.
크게 다음과 같은 순서로 raw dataset을 구축합니다.
load dataset
.json 파일을 로드합니다.list 만들기
self.raw_dataset = [{"text": self.diags[idx], "labels": self.labels[idx]} for idx in range(len(self.diags))]
getitem()
이 클래스는 sentence를 embedding하는 역할을 수행합니다.
📌 많은 경우 raw_dataset을 tokenizer로 encoding을 하고 model의 forward에 넣는 과정이 일반적입니다.
하지만, 베이스라인 모델 같은 경우, 모델 내부에 embedding을 하는 장치가 없기 때문에 미리 임베딩된 데이터셋이 필요합니다.
그러나, 이 부분은 모델 내부에서 embedding이 일어나도록
refactoring이 이루어질 필요가 있습니다.
Input
Output
📌 embedding을 할 때 batch을 구성하여 모델이 넣긴 하지만,
.map함수를 쓰면 더 빠르게 연산할 수 있지 않을까 생각이 든다.
**.pickle 형태로 저장합니다.**
pan_BERT = {
"train_dataset": train_dataset.embedded_diags,
"dev_dataset": dev_dataset.embedded_diags,
"train_label": train_dataset.embedded_labels,
"dev_label": dev_dataset.embedded_labels,
"test_dataset": test_dataset.embedded_diags,
"test_label": test_dataset.embedded_labels,
}
📌 일반적으로는 다음과 같은 형태를 따른다.
pan_BERT = {
"train": {
"text": ...,
"label": 1,
"dev": ...
}
}
따라서, 위와 같은 방식으로
refactoring이 필요하다.
현재 Huggingface Trainer 대신 custom Trainer를 사용 중 입니다.
📌 확장 가능성과 유지보수를 위해 Huggingface Trainer를 사용하는 것이 좋아보입니다.
하지만, shape이 일정한 dataset만 input으로 받을 수 있는 문제를 해결해야만 migration이 가능할 듯 보입니다.
예를 들어, 나는 [[16 * 512], [8 * 512], [16 * 512], [1 * 512], … ] 같은 dataloader를 구성하고 싶습니다.
그러나, Huggingface Trainer는 오로지 다음과 같이 dataloader를 구성합니다.
[[16 * 512], [16 * 512], [16 * 512], [16 * 512], … ]
train 메서드 입니다.
이 메서드는 기본적으로 GRU 모델을 train을 염두해 두고 있습니다.
특이한 점은 하나의 datapoint가 여러개의 text를 가지고 있습니다.
input_data가 주어지면 다음과 같이 batch를 구성합니다.
input_data = [N * M]
batch_data = [batch_size * M, ...]
그리고 일반적인 경우 다음과 같이 backward가 진행됩니다.
for batch_data in data_loader:
probs = model(batch_data, ...)
losses = loss_func(probs)
losses.backward()
이 때, 모델은 1개의 datapoint를 parallel하게 연산할 수 있습니다.
다시 말해, 1개의 datapoint는 1번만 model에 들어갑니다.
하지만, 베이스라인 모델은 GRU 계열 모델입니다. 따라서 1개의 datapoint를 linear하게 연산합니다.
다른 말로, 1개의 datapoint는 len(datapoint) 만큼 model이 실행됩니다.
문제는 베이스라인 모델은 [batch_size * datapoint] 라는 형태를 input으로 받지 못하게 설계되어있다는 점입니다.
오직 [datapoint] 만 가능합니다.
따라서 for datapoint in batch: model(datapoint) 형태로 설계했습니다.
베이스라인 모델
BiF_AGRU 라는 모델을 사용했습니다.
자세한 구조는 다음 페이지를 참고해주시기 바랍니다.
🔍 model_opt.zero_grad()
모델 매개변수의 변화도를 재설정합니다. 기본적으로 변화도는 더해지기(add up) 때문에 중복 계산을 막기 위해 반복할 때마다 명시적으로 0으로 설정합니다.
1 epoch이 끝날 때 마다 실행됩니다.
Input
Output
save best model
if last_best >= cur_best:
torch.save(self.model, model_path)
cur_best = last_best
저장된 best model를 가지고 prediction을 진행합니다.
📌 현재 prediction의 경우 단독적인
.py되어 있습니다.
이 부분은 Trainer의 method로 편입시킬 필요가 있다고 생각합니다.
또한, Trainer는 이미 저장된 model이 있을 경우 resume 할 수 있도록 init을 할 필요가 있다고 보여집니다.