Views
No views yet
1label2id = {
2 "공포": 0,
3 "놀람": 1,
4 "분노": 2,
5 "슬픔": 3,
6 "중립": 4,
7 "행복": 5,
8 "혐오": 6,
9}1# Tokenizer
2!git clone https://github.com/monologg/KoBERT-Transformers.git
3
4from kobert_transformers.tokenization_kobert import KoBertTokenizer
5
6#Default Settings
7tokenizer = KoBertTokenizer.from_pretrained("monologg/kobert")
8model = BertForSequenceClassification.from_pretrained("monologg/kobert")
9
10#Datasets Preprocessing
11import json
12
13with open('/content/train_datasets.json', 'r', encoding='utf-8') as files:
14 train_dataset = json.load(files)
15
16with open('/content/test_datasets.json', 'r', encoding='utf-8') as files_t:
17 val_dataset = json.load(files_t)
18
19
20from datasets import Dataset
21
22# 리스트 데이터를 Hugging Face Dataset으로 변환
23train_dataset = Dataset.from_list(train_dataset)
24val_dataset = Dataset.from_list(val_dataset)
25
26
27# 토큰화 함수 정의
28def tokenize_function(examples):
29 return tokenizer(
30 examples['Sentence'], # 텍스트 필드 이름
31 padding='max_length',
32 truncation=True,
33 max_length=128
34 )
35
36train_dataset = train_dataset.map(tokenize_function, batched=True)
37val_dataset = val_dataset.map(tokenize_function, batched=True)
38
39# 불필요한 컬럼 제거
40train_dataset = train_dataset.remove_columns(['Sentence'])
41val_dataset = val_dataset.remove_columns(['Sentence'])
42
43# 데이터셋 포맷 지정 (PyTorch tensors)
44train_dataset.set_format('torch')
45val_dataset.set_format('torch')model.config1BertConfig {
2 "_attn_implementation_autoset": true,
3 "_name_or_path": "monologg/kobert",
4 "architectures": [
5 "BertModel"
6 ],
7 "attention_probs_dropout_prob": 0.1,
8 "classifier_dropout": null,
9 "hidden_act": "gelu",
10 "hidden_dropout_prob": 0.1,
11 "hidden_size": 768,
12 "id2label": {
13 "0": "LABEL_0",
14 "1": "LABEL_1",
15 "2": "LABEL_2",
16 "3": "LABEL_3",
17 "4": "LABEL_4"
18 },
19 "initializer_range": 0.02,
20 "intermediate_size": 3072,
21 "label2id": {
22 "LABEL_0": 0,
23 "LABEL_1": 1,
24 "LABEL_2": 2,
25 "LABEL_3": 3,
26 "LABEL_4": 4
27 },
28 "layer_norm_eps": 1e-12,
29 "max_position_embeddings": 512,
30 "model_type": "bert",
31 "num_attention_heads": 12,
32 "num_hidden_layers": 12,
33 "pad_token_id": 1,
34 "position_embedding_type": "absolute",
35 "transformers_version": "4.47.0",
36 "type_vocab_size": 2,
37 "use_cache": true,
38 "vocab_size": 8002
39}1from transformers import BertConfig, BertForSequenceClassification, AutoTokenizer
2import torch
3
4# 감정별 라벨 매핑
5label2id = {
6 "공포": 0,
7 "놀람": 1,
8 "분노": 2,
9 "슬픔": 3,
10 "중립": 4,
11 "행복": 5,
12 "혐오": 6,
13}
14
15id2label = {v: k for k, v in label2id.items()}
16
17# BertConfig에 라벨 매핑 추가
18config = BertConfig.from_pretrained(
19 "monologg/kobert",
20 num_labels=7,
21 id2label=id2label,
22 label2id=label2id
23)
24
25model = BertForSequenceClassification.from_pretrained("monologg/kobert", config=config)
26tokenizer = KoBertTokenizer.from_pretrained("monologg/kobert")num_labels=7을 할 필요가 없습니다.model.config로 세팅값을 확인해보면 7가지 레이블 값이 입력된 것을 확인 할 수 있습니다.| 설정 항목 | 값 |
|---|---|
| 학습률 | 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 정도 차지하므로 더욱 늘려도 상관 없을듯 합니다.1training_args = TrainingArguments(
2 output_dir='./results',
3 learning_rate=2e-5,
4 per_device_train_batch_size=16,
5 per_device_eval_batch_size=16,
6 num_train_epochs=10,
7 eval_strategy="epoch",
8 save_strategy="epoch",
9 metric_for_best_model="f1_macro",
10 load_best_model_at_end=True
11)1model = BertForSequenceClassification.from_pretrained('./result/pp')
2tokenizer = KoBertTokenizer.from_pretrained('./result/pp')
3
4
5# GPU 사용 여부 확인 및 디바이스 설정
6device = torch.device("cuda") if torch.cuda.is_available() else torch.device("cpu")
7model.to(device) # 모델을 디바이스로 이동
8model.eval()
9
10# 2. 입력 데이터 준비
11texts = [
12 "오늘 정말 기분이 좋다 ㅎㅎ!",
13 "왜 이렇게 힘든 일이 많지? ㅠㅠ",
14 "정말 화가 난다!",
15 "평범한 하루였어.",
16 "너무 재밌다 ㅋㅋㅋ!",
17]
18
19# 3. 토큰화 및 입력 형식 변환
20def preprocess_and_tokenize(texts, tokenizer, max_length=128):
21 inputs = tokenizer(
22 texts,
23 padding=True, # 배치 크기에 맞게 패딩
24 truncation=True, # 최대 길이 초과 시 자름
25 max_length=max_length,
26 return_tensors="pt", # PyTorch 텐서 반환
27 )
28 return inputs
29
30inputs = preprocess_and_tokenize(texts, tokenizer)
31
32# 입력 데이터를 GPU로 이동
33inputs = {key: val.to(device) for key, val in inputs.items()}
34
35
36
37# 4. 인퍼런스 수행
38with torch.no_grad():
39 outputs = model(**inputs)
40 logits = outputs.logits
41 predictions = torch.argmax(logits, dim=-1).cpu().numpy()
42
43
44# 예측 결과 매핑
45predicted_labels = [id2label[pred] for pred in predictions]
46
47# 6. 결과 출력
48for text, label in zip(texts, predicted_labels):
49 print(f"Input: {text}")
50 print(f"Predicted Label: {label}\n")