Patrick's 데이터 세상
Transformer Encoder 카테고리 분류 개발 후기 - 1. Tokenizer 본문
Transformer Encoder 카테고리 분류 개발 후기 - 1. Tokenizer
patrick610 2022. 2. 27. 17:42
그동안 회사에서 작업했던 30개 카테고리 class 분류 모델 개발 과정 및 삽질 과정을 기록하려고 한다.
전체 프로세스에 대한 공유 목적이자 다시 공부하려는 목적이기도 하다.
https://github.com/hipster4020/category_classification
👉🏻 작업 환경
GPU type | NVIDIA GeForce RTX 3090 |
CPU count | 48 |
GPU count | 4 |
CUDA Version | 11.4 |
Python Version | 3.6.9 |
OS | Docker tensorflow - Ubuntu |
👉🏻 Issue
해당 분류 모델의 목적은 스크랩된 뉴스 본문 기사를 30개 클래스 카테고리로 분류하는 것이었다.
클래스는 각 기사당 최대 3개까지 예측하기 위해 30개 클래스에 대해 모두 각각의 0~1까지 범위의 확률을 낼 수 있도록 각각의 class에 sigmoid를 적용하여 예측값이 0.8 이상인 값 중 3개를 추출하고 1개도 없으면 etc로 분류하였다.
따라서, 각 기사 당 predict label은 1~3개가 된다.
모델은 Transformer의 self-attn과 feedforward network로 구성된 EncoderLayer모델을 활용하였다.
Tokenizer는 뉴스 기사 데이터를 Huggingface Tokenizer의 BPE 모델로 별도로 학습한 모델을 사용한다.
👉🏻 Tokenizer
Tokenizer 작업은 jupyter notebook으로 진행하였다.
• load data
import json
import re
from pprint import pprint
def load_jsonl(input_path) -> list:
data = []
with open(input_path, "r", encoding="utf-8") as f:
for line in f:
data.append(json.loads(line.rstrip("\n|\r")))
return data
data = load_jsonl('../../data/category.json')
json 타입으로 구성된 뉴스 본문 데이터를 불러와 list 타입으로 담는 작업
vocab_size = 24000
user_defined_symbols = ["<pad>", "<unk>", "<cls>", "<sep>", "<mask>", "<bos>", "<eos>", "<tsep>", "<name>", "<url>"]
user_defined_symbols += ["<unk0>", "<unk1>", "<unk2>", "<unk3>", "<unk4>", "<unk5>", "<unk6>", "<unk7>", "<unk8>", "<unk9>"]
unused_token_num = 100
unused_list = [f"<unused{i}>" for i in range(unused_token_num)]
user_defined_symbols += unused_list
pprint(user_defined_symbols)
vocabulary size를 24000으로 설정하고, 사용자 정의 토큰에 <pad>, <unk>, <cls>, <sep>, <mask>, <bos>, <eos>, <tsep>, <name>, <url>
<unk0>, <unk1>, <unk2>, <unk3>, <unk4>, <unk5>, <unk6>, <unk7>, <unk8>, <unk9>를 지정.
추가로 <unused> 토큰을 0~99까지 100개 사용자 정의 토큰에 추가하였다.
• train
from tokenizers import Tokenizer
from tokenizers.models import BPE
tokenizer = Tokenizer(BPE(unk_token="<unk>"))
pretrained 된 tokenizer 말고 직접 train 해서 쓸 것이기 때문에 import 된 Huggingface의 Tokenizer, models를 활용하여 BPE 학습을 진행한다.
from tokenizers import normalizers
from tokenizers.normalizers import NFKC, BertNormalizer
n1 = NFKC()
n2 = BertNormalizer(
clean_text=False,
handle_chinese_chars=False,
strip_accents=False,
lowercase=False,
)
tokenizer.normalizer = normalizers.Sequence([n1, n2])
NFKC : NFKC 유니코드로 정규화 진행
BertNormalizer : Bert 모델 Normalizer 사용
from tokenizers import pre_tokenizers
from tokenizers.pre_tokenizers import Metaspace
tokenizer.pre_tokenizer = pre_tokenizers.Sequence([Metaspace(replacement="_", add_prefix_space=True
)
]
)
pre_tokenizers.Sequence : 공백을 분할하고 특수 문자 "_"로 대체하는 Metaspace로 사전 토큰화
def gen():
for row in data:
yield processing(row['content'])
from tokenizers.trainers import BpeTrainer
trainer = BpeTrainer(vocab_size=vocab_size,
special_tokens=user_defined_symbols,
)
tokenizer.train_from_iterator(gen(), trainer)
tokenizer.model.save("temp")
trainers.BpeTrainer : BpeTrainer로 config 값 세팅(vocab_size : 24000 , user_defined_symbols : 위에 정의한 사용자 정의 토큰)
tokenizer.train_from_iterator : list 뉴스데이터와 trainer로 train 진행
tokenizer.model.save("temp") : 모델 저장
output = tokenizer.encode("본 고안은 이러한 특성을 이용해 사용한다.")
print(output.ids)
tokenizer.decode(output.ids)
from tokenizers import decoders
tokenizer.decoder = decoders.BPEDecoder(suffix='_')
tokenizer.decode(output.ids)
trained tokenizer에 test encoding 후 decoding 진행하면 정상적으로 결과 출력된다.
• convert transformers tokenizer and save
from transformers import GPT2TokenizerFast
fast_tokenizer = GPT2TokenizerFast(tokenizer_object=tokenizer)
fast_tokenizer.pad_token = "<pad>"
fast_tokenizer.unk_token = "<unk>"
fast_tokenizer.cls_token = "<cls>"
fast_tokenizer.sep_token = "<sep>"
fast_tokenizer.mask_token = "<mask>"
fast_tokenizer.bos_token = "<bos>"
fast_tokenizer.eos_token = "<eos>"
special_tokens_dict = {'additional_special_tokens': user_defined_symbols}
fast_tokenizer.add_special_tokens(special_tokens_dict)
새로 정의한 GPT2TokenizerFast에 padding, unknown, cls, sep, mask, bos, eos 토큰을 추가하고, 스페셜 토큰 사전에 사용자 정의 토큰을 추가한다.
fast_tokenizer.decode(fast_tokenizer.encode("본 고안은 이러한 특성을 이용해 사용한다."))
fast_tokenizer.save_pretrained("tokenizer")
테스트 문장 출력 확인 후 tokenizer save.
👉🏻 정리
huggingface BPE 학습한 모델을 GPT2TokenizerFast로 load하여 Transformer Encoder 모델에 사용할 준비를 마쳤다.
2부에서 Transformer 모델, Finetuning에 대해 다루려고 한다
'Deep Learning > 프로젝트 후기' 카테고리의 다른 글
2024년 회고록 (4) | 2024.12.31 |
---|---|
카피라이터 광고 문구 생성모델 학습 후기 (2) | 2023.08.11 |
국내 유통대기업 성격유형별 문체 특성 기반 맞춤형 광고 메시지 생성 모델 재구현 프로젝트 (0) | 2023.05.15 |
koELECTRA with Active Learning 감성 분류 개발 후기 (0) | 2022.06.09 |
Transformer Encoder 카테고리 분류 개발 후기 - 2. train (0) | 2022.03.05 |