한국어 텍스트 감정분류 모델(KoBERT)
MD(Model Description)
위 모델은 한국어 감정 정보가 포함된 단발성 대화 데이터셋과 네이버 블로그 를 통해 7가지 감정 데이터셋을 분류하는 모델입니다.
7가지 감정범주:
label2id = {
"공포": 0,
"놀람": 1,
"분노": 2,
"슬픔": 3,
"중립": 4,
"행복": 5,
"혐오": 6,
}
메인 모델
monologg/kobert모델의 사전 학습된 KoBERT 모델을 미세조정하였습니다(fine tunning)
구성
# Tokenizer
!git clone https://github.com/monologg/KoBERT-Transformers.git
from kobert_transformers.tokenization_kobert import KoBertTokenizer
#Default Settings
tokenizer = KoBertTokenizer.from_pretrained("monologg/kobert")
model = BertForSequenceClassification.from_pretrained("monologg/kobert")
#Datasets Preprocessing
import json
with open('/content/train_datasets.json', 'r', encoding='utf-8') as files:
train_dataset = json.load(files)
with open('/content/test_datasets.json', 'r', encoding='utf-8') as files_t:
val_dataset = json.load(files_t)
from datasets import Dataset
# 리스트 데이터를 Hugging Face Dataset으로 변환
train_dataset = Dataset.from_list(train_dataset)
val_dataset = Dataset.from_list(val_dataset)
# 토큰화 함수 정의
def tokenize_function(examples):
return tokenizer(
examples['Sentence'], # 텍스트 필드 이름
padding='max_length',
truncation=True,
max_length=128
)
train_dataset = train_dataset.map(tokenize_function, batched=True)
val_dataset = val_dataset.map(tokenize_function, batched=True)
# 불필요한 컬럼 제거
train_dataset = train_dataset.remove_columns(['Sentence'])
val_dataset = val_dataset.remove_columns(['Sentence'])
# 데이터셋 포맷 지정 (PyTorch tensors)
train_dataset.set_format('torch')
val_dataset.set_format('torch')
Model Config Settings
model.config
BertConfig {
"_attn_implementation_autoset": true,
"_name_or_path": "monologg/kobert",
"architectures": [
"BertModel"
],
"attention_probs_dropout_prob": 0.1,
"classifier_dropout": null,
"hidden_act": "gelu",
"hidden_dropout_prob": 0.1,
"hidden_size": 768,
"id2label": {
"0": "LABEL_0",
"1": "LABEL_1",
"2": "LABEL_2",
"3": "LABEL_3",
"4": "LABEL_4"
},
"initializer_range": 0.02,
"intermediate_size": 3072,
"label2id": {
"LABEL_0": 0,
"LABEL_1": 1,
"LABEL_2": 2,
"LABEL_3": 3,
"LABEL_4": 4
},
"layer_norm_eps": 1e-12,
"max_position_embeddings": 512,
"model_type": "bert",
"num_attention_heads": 12,
"num_hidden_layers": 12,
"pad_token_id": 1,
"position_embedding_type": "absolute",
"transformers_version": "4.47.0",
"type_vocab_size": 2,
"use_cache": true,
"vocab_size": 8002
}
- 라벨이 5개 밖에 없는 것을 확인할 수 있습니다.
Configuration Settings
from transformers import BertConfig, BertForSequenceClassification, AutoTokenizer
import torch
# 감정별 라벨 매핑
label2id = {
"공포": 0,
"놀람": 1,
"분노": 2,
"슬픔": 3,
"중립": 4,
"행복": 5,
"혐오": 6,
}
id2label = {v: k for k, v in label2id.items()}
# BertConfig에 라벨 매핑 추가
config = BertConfig.from_pretrained(
"monologg/kobert",
num_labels=7,
id2label=id2label,
label2id=label2id
)
model = BertForSequenceClassification.from_pretrained("monologg/kobert", config=config)
tokenizer = KoBertTokenizer.from_pretrained("monologg/kobert")
- 사실은
num_labels=7
을 할 필요가 없습니다. - 세팅 이후에
model.config
로 세팅값을 확인해보면 7가지 레이블 값이 입력된 것을 확인 할 수 있습니다.
Detail Configuration
설정 항목 | 값 |
---|---|
학습률 | 2e-5 |
학습 배치사이즈 | 64 |
평가 배치사이즈 | 1 |
평가 지표 | F1 Score (Macro) |
FP16 사용 여부 | True |
평가지표
Epoch | Training Loss | Validation Loss | F1 Macro | Precision Macro | Recall Macro |
---|---|---|---|---|---|
1 | No log | 1.273796 | 0.496522 | 0.509767 | 0.506992 |
2 | 1.478500 | 1.216168 | 0.532564 | 0.534552 | 0.537554 |
3 | 1.155800 | 1.216068 | 0.536442 | 0.537659 | 0.539811 |
4 | 0.996200 | 1.235898 | 0.536210 | 0.537586 | 0.541298 |
5 | 0.901000 | 1.248866 | 0.540000 | 0.539427 | 0.543429 |
f1-score
기반으로 평가, → 0.54 성능이 그렇게 좋진 못합니다batch_size
,Learning_Rate
등의 하이퍼 파라미터를 조정할 필요가 보여집니다.(최소 10에포크 이상)T4
기준 배치사이즈는64
는VRAM 4G
정도 차지하므로 더욱 늘려도 상관 없을듯 합니다.
최종 훈련코드
training_args = TrainingArguments(
output_dir='./results',
learning_rate=2e-5,
per_device_train_batch_size=16,
per_device_eval_batch_size=16,
num_train_epochs=10,
eval_strategy="epoch",
save_strategy="epoch",
metric_for_best_model="f1_macro",
load_best_model_at_end=True
)
Inference
model = BertForSequenceClassification.from_pretrained('./result/pp')
tokenizer = KoBertTokenizer.from_pretrained('./result/pp')
# GPU 사용 여부 확인 및 디바이스 설정
device = torch.device("cuda") if torch.cuda.is_available() else torch.device("cpu")
model.to(device) # 모델을 디바이스로 이동
model.eval()
# 2. 입력 데이터 준비
texts = [
"오늘 정말 기분이 좋다 ㅎㅎ!",
"왜 이렇게 힘든 일이 많지? ㅠㅠ",
"정말 화가 난다!",
"평범한 하루였어.",
"너무 재밌다 ㅋㅋㅋ!",
]
# 3. 토큰화 및 입력 형식 변환
def preprocess_and_tokenize(texts, tokenizer, max_length=128):
inputs = tokenizer(
texts,
padding=True, # 배치 크기에 맞게 패딩
truncation=True, # 최대 길이 초과 시 자름
max_length=max_length,
return_tensors="pt", # PyTorch 텐서 반환
)
return inputs
inputs = preprocess_and_tokenize(texts, tokenizer)
# 입력 데이터를 GPU로 이동
inputs = {key: val.to(device) for key, val in inputs.items()}
# 4. 인퍼런스 수행
with torch.no_grad():
outputs = model(**inputs)
logits = outputs.logits
predictions = torch.argmax(logits, dim=-1).cpu().numpy()
# 예측 결과 매핑
predicted_labels = [id2label[pred] for pred in predictions]
# 6. 결과 출력
for text, label in zip(texts, predicted_labels):
print(f"Input: {text}")
print(f"Predicted Label: {label}\n")
- Downloads last month
- 20
This model does not have enough activity to be deployed to Inference API (serverless) yet. Increase its social
visibility and check back later, or deploy to Inference Endpoints (dedicated)
instead.
Model tree for UICHEOL-HWANG/kobert
Base model
monologg/kobert