Dusit-P commited on
Commit
be20e17
·
verified ·
1 Parent(s): 0cd3724

Update README.md

Browse files
Files changed (1) hide show
  1. README.md +285 -16
README.md CHANGED
@@ -20,7 +20,6 @@ datasets:
20
  โมเดลสำหรับวิเคราะห์อารมณ์ (2 คลาส: NEG/POS) ภาษาไทย โดยใช้ **WangchanBERTa** เป็น backbone และเพิ่มหัว (heads) แบบ LSTM/CNN-LSTM หลายสถาปัตยกรรมสำหรับเปรียบเทียบและใช้งานตามบริบท
21
 
22
  รีโปนี้บรรจุโมเดล 4 ตัว (เก็บเป็นโฟลเดอร์ย่อย):
23
-
24
  - `WCB/` — WangchanBERTa (ใช้ [CLS])
25
  - `WCB_BiLSTM/` — WangchanBERTa → BiLSTM → Pooling
26
  - `WCB_CNN_BiLSTM/` — WangchanBERTa → CNN → BiLSTM → Pooling
@@ -28,6 +27,8 @@ datasets:
28
 
29
  แต่ละโฟลเดอร์มี `model.safetensors` และ `config.json` (เมตาดาต้า: `id2label/label2id`, `max_length`, `pooling_after_lstm`, `base_model`)
30
 
 
 
31
  ## สรุปผลการประเมิน (5-fold CV)
32
 
33
  | Model | Accuracy (%) | F1-Score (%) | AUC (%) |
@@ -43,6 +44,7 @@ datasets:
43
  - **เร็ว/เสถียร**: `WCB` เร็วที่สุดและเสถียรสุด เหมาะงานทรัพยากรจำกัด.
44
 
45
  ### เวลาเทรน (โดยเฉลี่ย)
 
46
  | Model | วินาที/รอบ | เวลารวม (ชม.) |
47
  |---|---:|---:|
48
  | WCB | 54.67 | 4.58 |
@@ -50,14 +52,24 @@ datasets:
50
  | WCB_CNN_BiLSTM | 68.72 | 5.76 |
51
  | WCB_4Layer_BiLSTM | 72.91 | 6.11 |
52
 
 
 
53
  ## โครงสร้างรีโป
54
 
55
  ```
56
  .
57
  ├─ WCB/
 
 
58
  ├─ WCB_BiLSTM/
 
 
59
  ├─ WCB_CNN_BiLSTM/
 
 
60
  ├─ WCB_4Layer_BiLSTM/
 
 
61
  ├─ common/
62
  │ ├─ models.py
63
  │ └─ __init__.py
@@ -66,34 +78,291 @@ datasets:
66
  └─ README.md
67
  ```
68
 
 
 
69
  ## วิธีใช้งาน
70
 
 
 
 
 
 
 
 
 
71
  ```python
72
  import torch
73
- from common.models import load_model
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
74
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
75
  MODEL_DIR = "WCB_BiLSTM"
76
 
77
- tokenizer, model, cfg = load_model(MODEL_DIR)
78
- text = "มือถือรุ่นนี้ดีมาก ราคาคุ้มค่า"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
79
 
80
- enc = tokenizer(text, truncation=True, padding=True,
81
- return_tensors="pt", max_length=cfg.get("max_length", 128))
82
  with torch.no_grad():
83
- logits = model(enc["input_ids"], enc["attention_mask"])
84
- probs = torch.softmax(logits, dim=1)[0].tolist()
85
- pred_id = int(torch.argmax(logits, dim=1))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
86
 
87
- id2label = {int(k): v for k, v in cfg["id2label"].items()}
88
- print("label:", id2label[pred_id], "probs:", probs)
 
 
 
 
 
 
 
 
89
  ```
90
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
91
  ## เลือกโมเดลให้เหมาะงาน
92
 
93
- - **ต้องการความแม่นยำสูงสุด** `WCB_BiLSTM`
94
- - **ทรัพยากรจำกัด/ต้องการความเร็ว** → `WCB`
95
- - **โฟกัส AUC/การจัดอันดับความเสี่ยง** `WCB_CNN_BiLSTM`
96
- - **สมดุลโดยรวม** `WCB_4Layer_BiLSTM`
 
 
 
 
 
 
 
 
 
 
 
 
 
97
 
98
- ## License
99
  Apache-2.0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
20
  โมเดลสำหรับวิเคราะห์อารมณ์ (2 คลาส: NEG/POS) ภาษาไทย โดยใช้ **WangchanBERTa** เป็น backbone และเพิ่มหัว (heads) แบบ LSTM/CNN-LSTM หลายสถาปัตยกรรมสำหรับเปรียบเทียบและใช้งานตามบริบท
21
 
22
  รีโปนี้บรรจุโมเดล 4 ตัว (เก็บเป็นโฟลเดอร์ย่อย):
 
23
  - `WCB/` — WangchanBERTa (ใช้ [CLS])
24
  - `WCB_BiLSTM/` — WangchanBERTa → BiLSTM → Pooling
25
  - `WCB_CNN_BiLSTM/` — WangchanBERTa → CNN → BiLSTM → Pooling
 
27
 
28
  แต่ละโฟลเดอร์มี `model.safetensors` และ `config.json` (เมตาดาต้า: `id2label/label2id`, `max_length`, `pooling_after_lstm`, `base_model`)
29
 
30
+ ---
31
+
32
  ## สรุปผลการประเมิน (5-fold CV)
33
 
34
  | Model | Accuracy (%) | F1-Score (%) | AUC (%) |
 
44
  - **เร็ว/เสถียร**: `WCB` เร็วที่สุดและเสถียรสุด เหมาะงานทรัพยากรจำกัด.
45
 
46
  ### เวลาเทรน (โดยเฉลี่ย)
47
+
48
  | Model | วินาที/รอบ | เวลารวม (ชม.) |
49
  |---|---:|---:|
50
  | WCB | 54.67 | 4.58 |
 
52
  | WCB_CNN_BiLSTM | 68.72 | 5.76 |
53
  | WCB_4Layer_BiLSTM | 72.91 | 6.11 |
54
 
55
+ ---
56
+
57
  ## โครงสร้างรีโป
58
 
59
  ```
60
  .
61
  ├─ WCB/
62
+ │ ├─ model.safetensors
63
+ │ └─ config.json
64
  ├─ WCB_BiLSTM/
65
+ │ ├─ model.safetensors
66
+ │ └─ config.json
67
  ├─ WCB_CNN_BiLSTM/
68
+ │ ├─ model.safetensors
69
+ │ └─ config.json
70
  ├─ WCB_4Layer_BiLSTM/
71
+ │ ├─ model.safetensors
72
+ │ └─ config.json
73
  ├─ common/
74
  │ ├─ models.py
75
  │ └─ __init__.py
 
78
  └─ README.md
79
  ```
80
 
81
+ ---
82
+
83
  ## วิธีใช้งาน
84
 
85
+ ### 🔧 ติดตั้ง Dependencies
86
+
87
+ ```bash
88
+ pip install torch transformers huggingface-hub safetensors
89
+ ```
90
+
91
+ ### 📦 วิธีที่ 1: โหลดโมเดลจาก Hugging Face Hub (แนะนำ)
92
+
93
  ```python
94
  import torch
95
+ import torch.nn.functional as F
96
+ from transformers import AutoTokenizer
97
+ from huggingface_hub import hf_hub_download
98
+ from safetensors.torch import load_file
99
+ import json
100
+ import importlib.util
101
+
102
+ # ===== ตั้งค่า =====
103
+ REPO_ID = "Dusit-P/thai-sentiment" # เปลี่ยนเป็น repo ของคุณ
104
+ MODEL_NAME = "WCB_BiLSTM" # เลือก: WCB, WCB_BiLSTM, WCB_CNN_BiLSTM, WCB_4Layer_BiLSTM
105
+
106
+ # ===== 1. ดาวน์โหลดไฟล์จำเป็น =====
107
+ config_path = hf_hub_download(REPO_ID, filename=f"{MODEL_NAME}/config.json")
108
+ weights_path = hf_hub_download(REPO_ID, filename=f"{MODEL_NAME}/model.safetensors")
109
+ models_py = hf_hub_download(REPO_ID, filename="common/models.py")
110
+
111
+ # ===== 2. โหลด config =====
112
+ with open(config_path, "r", encoding="utf-8") as f:
113
+ config = json.load(f)
114
+
115
+ # ===== 3. โหลด tokenizer =====
116
+ base_model = config.get("base_model", "airesearch/wangchanberta-base-att-spm-uncased")
117
+ tokenizer = AutoTokenizer.from_pretrained(base_model)
118
+
119
+ # ===== 4. โหลดโมเดล =====
120
+ # Import models.py
121
+ spec = importlib.util.spec_from_file_location("models", models_py)
122
+ models = importlib.util.module_from_spec(spec)
123
+ spec.loader.exec_module(models)
124
+
125
+ # สร้างโมเดล
126
+ architecture = config.get("architecture", MODEL_NAME)
127
+ num_labels = config.get("num_labels", 2)
128
+ pooling = config.get("pooling_after_lstm", "masked_mean")
129
+
130
+ model = models._build(architecture, base_model, num_labels, pooling)
131
+
132
+ # โหลด weights
133
+ state_dict = load_file(weights_path)
134
+ model.load_state_dict(state_dict, strict=False)
135
+ model.eval()
136
+
137
+ # ===== 5. ทำนาย =====
138
+ text = "มือถือรุ่นนี้ดีมาก ราคาคุ้มค่า แนะนำเลย!"
139
 
140
+ # Tokenize
141
+ inputs = tokenizer(
142
+ text,
143
+ truncation=True,
144
+ padding=True,
145
+ max_length=config.get("max_length", 128),
146
+ return_tensors="pt"
147
+ )
148
+
149
+ # Predict
150
+ with torch.no_grad():
151
+ logits = model(inputs["input_ids"], inputs["attention_mask"])
152
+ probs = F.softmax(logits, dim=1)[0]
153
+ pred_id = torch.argmax(logits, dim=1).item()
154
+
155
+ # แสดงผล
156
+ id2label = {int(k): v for k, v in config["id2label"].items()}
157
+ print(f"Text: {text}")
158
+ print(f"Prediction: {id2label[pred_id]}")
159
+ print(f"Probabilities: NEG={probs[0]:.4f}, POS={probs[1]:.4f}")
160
+ ```
161
+
162
+ **Output ตัวอย่าง:**
163
+ ```
164
+ Text: มือถือรุ่นนี้ดีมาก ราคาคุ้มค่า แนะนำเลย!
165
+ Prediction: positive
166
+ Probabilities: NEG=0.0234, POS=0.9766
167
+ ```
168
+
169
+ ---
170
+
171
+ ### 📦 วิธีที่ 2: Clone Repo แล้วใช้งาน
172
+
173
+ ```bash
174
+ git clone https://huggingface.co/Dusit-P/thai-sentiment
175
+ cd thai-sentiment
176
+ pip install -r requirements.txt
177
+ ```
178
+
179
+ ```python
180
+ import torch
181
+ import torch.nn.functional as F
182
+ from transformers import AutoTokenizer
183
+ from safetensors.torch import load_file
184
+ from common.models import _build
185
+ import json
186
+
187
+ # ===== เลือกโมเดล =====
188
  MODEL_DIR = "WCB_BiLSTM"
189
 
190
+ # ===== โหลด config =====
191
+ with open(f"{MODEL_DIR}/config.json", "r") as f:
192
+ config = json.load(f)
193
+
194
+ # ===== โหลด tokenizer =====
195
+ base_model = config.get("base_model", "airesearch/wangchanberta-base-att-spm-uncased")
196
+ tokenizer = AutoTokenizer.from_pretrained(base_model)
197
+
198
+ # ===== โหลดโมเดล =====
199
+ model = _build(
200
+ config.get("architecture", MODEL_DIR),
201
+ base_model,
202
+ config.get("num_labels", 2),
203
+ config.get("pooling_after_lstm", "masked_mean")
204
+ )
205
+
206
+ state_dict = load_file(f"{MODEL_DIR}/model.safetensors")
207
+ model.load_state_dict(state_dict, strict=False)
208
+ model.eval()
209
+
210
+ # ===== ทำนาย =====
211
+ text = "ของแพงไป คุณภาพไม่คุ้มราคา"
212
+
213
+ inputs = tokenizer(
214
+ text,
215
+ truncation=True,
216
+ padding=True,
217
+ max_length=config.get("max_length", 128),
218
+ return_tensors="pt"
219
+ )
220
 
 
 
221
  with torch.no_grad():
222
+ logits = model(inputs["input_ids"], inputs["attention_mask"])
223
+ probs = F.softmax(logits, dim=1)[0]
224
+ pred_id = torch.argmax(logits, dim=1).item()
225
+
226
+ id2label = {int(k): v for k, v in config["id2label"].items()}
227
+ print(f"Prediction: {id2label[pred_id]}")
228
+ print(f"Probabilities: {probs}")
229
+ ```
230
+
231
+ ---
232
+
233
+ ### 📦 วิธีที่ 3: ทำนายหลายข้อความพร้อมกัน (Batch Prediction)
234
+
235
+ ```python
236
+ import torch
237
+ import torch.nn.functional as F
238
+ from transformers import AutoTokenizer
239
+ from huggingface_hub import hf_hub_download
240
+ from safetensors.torch import load_file
241
+ import json
242
+ import importlib.util
243
+
244
+ # ===== Setup =====
245
+ REPO_ID = "Dusit-P/thai-sentiment"
246
+ MODEL_NAME = "WCB_BiLSTM"
247
+
248
+ # ===== โหลดโมเดล (ตามวิธีที่ 1) =====
249
+ config_path = hf_hub_download(REPO_ID, filename=f"{MODEL_NAME}/config.json")
250
+ weights_path = hf_hub_download(REPO_ID, filename=f"{MODEL_NAME}/model.safetensors")
251
+ models_py = hf_hub_download(REPO_ID, filename="common/models.py")
252
+
253
+ with open(config_path, "r") as f:
254
+ config = json.load(f)
255
+
256
+ base_model = config.get("base_model", "airesearch/wangchanberta-base-att-spm-uncased")
257
+ tokenizer = AutoTokenizer.from_pretrained(base_model)
258
+
259
+ spec = importlib.util.spec_from_file_location("models", models_py)
260
+ models = importlib.util.module_from_spec(spec)
261
+ spec.loader.exec_module(models)
262
+
263
+ model = models._build(
264
+ config.get("architecture", MODEL_NAME),
265
+ base_model,
266
+ config.get("num_labels", 2),
267
+ config.get("pooling_after_lstm", "masked_mean")
268
+ )
269
+
270
+ state_dict = load_file(weights_path)
271
+ model.load_state_dict(state_dict, strict=False)
272
+ model.eval()
273
+
274
+ # ===== ทำนายหลายข้อความ =====
275
+ texts = [
276
+ "อาหารอร่อยมาก บริการดีมาก",
277
+ "ของแพงไป รสชาติก็ธรรมดา",
278
+ "บรรยากาศดี แต่รอนานไป",
279
+ "คุ้มค่ามาก แนะนำเลย"
280
+ ]
281
+
282
+ # Tokenize batch
283
+ inputs = tokenizer(
284
+ texts,
285
+ truncation=True,
286
+ padding=True,
287
+ max_length=config.get("max_length", 128),
288
+ return_tensors="pt"
289
+ )
290
+
291
+ # Predict batch
292
+ with torch.no_grad():
293
+ logits = model(inputs["input_ids"], inputs["attention_mask"])
294
+ probs = F.softmax(logits, dim=1)
295
+ pred_ids = torch.argmax(logits, dim=1)
296
+
297
+ # แสดงผล
298
+ id2label = {int(k): v for k, v in config["id2label"].items()}
299
 
300
+ print("=" * 70)
301
+ for i, text in enumerate(texts):
302
+ label = id2label[pred_ids[i].item()]
303
+ neg_prob = probs[i][0].item()
304
+ pos_prob = probs[i][1].item()
305
+
306
+ print(f"Text: {text}")
307
+ print(f" → Prediction: {label}")
308
+ print(f" → Confidence: NEG={neg_prob:.4f}, POS={pos_prob:.4f}")
309
+ print("-" * 70)
310
  ```
311
 
312
+ **Output ตัวอย่าง:**
313
+ ```
314
+ ======================================================================
315
+ Text: อาหารอร่อยมาก บริการดีมาก
316
+ → Prediction: positive
317
+ → Confidence: NEG=0.0156, POS=0.9844
318
+ ----------------------------------------------------------------------
319
+ Text: ของแพงไป รสชาติก็��รรมดา
320
+ → Prediction: negative
321
+ → Confidence: NEG=0.8923, POS=0.1077
322
+ ----------------------------------------------------------------------
323
+ Text: บรรยากาศดี แต่รอนานไป
324
+ → Prediction: positive
325
+ → Confidence: NEG=0.3421, POS=0.6579
326
+ ----------------------------------------------------------------------
327
+ Text: คุ้มค่ามาก แนะนำเลย
328
+ → Prediction: positive
329
+ → Confidence: NEG=0.0089, POS=0.9911
330
+ ----------------------------------------------------------------------
331
+ ```
332
+
333
+ ---
334
+
335
  ## เลือกโมเดลให้เหมาะงาน
336
 
337
+ | Use Case | โมเดลที่แนะนำ | เหตุผล |
338
+ |----------|--------------|--------|
339
+ | **ต้องการความแม่นยำสูงสุด** | `WCB_BiLSTM` | Acc/F1 สูงสุด (90.93% / 90.54%) |
340
+ | **ทรัพยากรจำกัด / ต้องการความเร็ว** | `WCB` | เร็วที่สุด (54.67 วิ/รอบ) และเสถียรสุด |
341
+ | **โฟกัส AUC / การจัดอันดับ** | `WCB_CNN_BiLSTM` | AUC สูงสุด (95.83%) และเสถียร |
342
+ | **สมดุลโดยรวม** | `WCB_4Layer_BiLSTM` | ประสิทธิภาพดีรอบด้าน |
343
+
344
+ ---
345
+
346
+ ## 🚀 Demo Application
347
+
348
+ ลองใช้งานโมเดลผ่าน Gradio Demo:
349
+ - **URL:** [https://huggingface.co/spaces/Dusit-P/thai-sentiment-demo](https://huggingface.co/spaces/Dusit-P/thai-sentiment-demo)
350
+
351
+ ---
352
+
353
+ ## 📄 License
354
 
 
355
  Apache-2.0
356
+
357
+ ---
358
+
359
+ ## 🙏 Acknowledgments
360
+
361
+ - **WangchanBERTa**: [airesearch/wangchanberta-base-att-spm-uncased](https://huggingface.co/airesearch/wangchanberta-base-att-spm-uncased)
362
+ - **Dataset**: [wisesight_sentiment](https://huggingface.co/datasets/wisesight_sentiment)
363
+
364
+ ---
365
+
366
+ ## 📧 Contact
367
+
368
+ หากมีคำถามหรือข้อเสนอแนะ กรุณาติดต่อผ่าน [GitHub Issues](https://github.com/your-repo/issues)