한국어 텍스트 감정분류 모델(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
- 109
Inference Providers
NEW
This model is not currently available via any of the supported Inference Providers.
Model tree for UICHEOL-HWANG/kobert
Base model
monologg/kobert