การประเมินและการอนุมาน: จากลอจิตสู่ป้ายกำกับที่ทำนาย
ผู้เรียนจะคำนวณ softmax บนลอจิต ถอดรหัสดัชนีคลาสที่ทำนายเป็นป้ายกำกับ และประเมินแบบจำลองที่ปรับแต่งแล้วด้วยความแม่นยำและ F1 บนชุดทดสอบที่กันไว้
การประเมินและการอนุมาน: จากลอจิตสู่ป้ายกำกับที่ทำนาย เป็นบทเรียน Machine Learning Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Machine Learning Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Machine Learning Academy มีบทเรียนทั้งหมด 4 บทเรียน
โลจิตคืออะไร
ผลลัพธ์จากชั้นเชิงเส้นสุดท้ายของโมเดลจำแนกประเภทเรียกว่า โลจิต ซึ่งเป็นคะแนนดิบที่ยังไม่ปรับให้เป็นมาตรฐานสำหรับแต่ละคลาส สำหรับปัญหาแบบ 2 คลาส (ลบ/บวก) เวกเตอร์โลจิตอาจเป็น [-1.2, 3.5] ซึ่งหมายความว่าโมเดลให้น้ำหนักกับคลาส 1 (บวก) อย่างมาก โลจิตสามารถเป็นจำนวนจริงใดก็ได้ และไม่ใช่ค่าความน่าจะเป็น เราจึงต้องมีขั้นตอนเพิ่มเติม (ซอฟต์แมกซ์หรือซิกมอยด์) เพื่อแปลงเป็นค่าความน่าจะเป็นที่ตีความได้และมีผลรวมเป็น 1
import torch
import torch.nn.functional as F
# Example logits for 2-class problem (batch of 3)
logits = torch.tensor([[-1.2, 3.5], [2.1, -0.3], [0.4, 0.6]])
print('Logits:\n', logits)
# Convert to probabilities with softmax
probs = F.softmax(logits, dim=1)
print('Probabilities:\n', probs)
# Each row sums to 1
print('Row sums:', probs.sum(dim=1))ซอฟต์แมกซ์: การแปลงโลจิตเป็นค่าความน่าจะเป็น
ฟังก์ชัน softmax จะแปลงเวกเตอร์โลจิตที่เป็นจำนวนจริงให้เป็นการแจกแจงความน่าจะเป็น สำหรับคลาส i: softmax(z_i) = exp(z_i) / sum(exp(z_j)) ฟังก์ชันเอ็กซ์โพเนนเชียลจะขยายความแตกต่าง ดังนั้นความแตกต่างของโลจิต 2 จะทำให้คลาสหนึ่งมีความน่าจะเป็นมากกว่าอีกคลาสประมาณ 7 เท่า ซอฟต์แมกซ์ใช้กับการจำแนกประเภทแบบ หลายคลาส ซึ่งมีคลาสที่ถูกต้องได้เพียงคลาสเดียว
import torch
import torch.nn.functional as F
import numpy as np
logits = torch.tensor([1.0, 3.0, 0.5]) # 3 classes
probs = F.softmax(logits, dim=0)
print('Class probabilities:', probs.numpy().round(4))
# [0.0900, 0.6652, 0.2449] -- class 1 is most likely
print('Sum:', probs.sum().item()) # 1.0
# argmax gives the predicted class index
pred_class = torch.argmax(probs).item()
print('Predicted class:', pred_class) # 1argmax: การดึงป้ายกำกับที่ทำนาย
เมื่อมีเวกเตอร์โลจิตสำหรับตัวอย่างหนึ่งกลุ่มแล้ว torch.argmax(logits, dim=1) จะคืนค่าดัชนีของคลาสที่มีคะแนนสูงสุดสำหรับแต่ละตัวอย่าง นี่คือ ป้ายกำกับคลาสที่ทำนาย สำหรับ BERT ที่ปรับแต่งด้วย num_labels=2 ผลลัพธ์จะเป็น 0 (ลบ) หรือ 1 (บวก) เราไม่จำเป็นต้องใช้ซอฟต์แมกซ์ก่อน argmax เพราะซอฟต์แมกซ์เป็นฟังก์ชันเพิ่มตามลำดับ ดังนั้นโลจิตที่มากที่สุดจะแปลงเป็นค่าความน่าจะเป็นที่มากที่สุดเสมอ
import torch
# Logits from model output for a batch of 4 examples
logits = torch.tensor([
[-2.1, 3.4], # strongly positive
[ 1.8, -0.5], # negative
[ 0.1, 0.2], # uncertain, leans positive
[-3.0, -1.0] # both negative, less-negative wins
])
predictions = torch.argmax(logits, dim=1)
print('Predictions:', predictions.tolist()) # [1, 0, 1, 1]
labels = {'0': 'negative', '1': 'positive'}
for pred in predictions.tolist():
print(labels[str(pred)])การถอดรหัสดัชนีที่ทำนายเป็นชื่อคลาส
ผลลัพธ์ของโมเดลเป็นดัชนีจำนวนเต็ม ในระบบจริง คุณควรเก็บการจับคู่ระหว่างดัชนีกับป้ายกำกับที่มนุษย์อ่านเข้าใจได้ไว้ อาจจัดเก็บเป็นรายการหรือพจนานุกรม แล้วใช้จำนวนเต็มที่ทำนายเป็นดัชนี สำหรับ BERT ที่ปรับแต่งด้วย IMDB การจับคู่คือ {0: 'NEGATIVE', 1: 'POSITIVE'} สำหรับงานหลายคลาส เช่น การจำแนกหัวข้อ การจับคู่อาจมี 20 รายการขึ้นไป
import torch
from transformers import BertForSequenceClassification, BertTokenizer
# Assume model and tokenizer are already loaded and fine-tuned
id2label = {0: 'NEGATIVE', 1: 'POSITIVE'}
def predict(text, model, tokenizer, device):
model.eval()
inputs = tokenizer(text, return_tensors='pt',
truncation=True, max_length=256)
inputs = {k: v.to(device) for k, v in inputs.items()}
with torch.no_grad():
logits = model(**inputs).logits
pred_id = torch.argmax(logits, dim=1).item()
return id2label[pred_id]
# result = predict('This film was absolutely wonderful!', model, tokenizer, device)
# print(result) # POSITIVEคะแนนความมั่นใจจากค่าความน่าจะเป็น
การคืนเฉพาะป้ายกำกับที่ทำนายมักไม่เพียงพอสำหรับการใช้งานจริง คะแนนความมั่นใจ (ค่าความน่าจะเป็นของคลาสที่ทำนาย) จะบอกผู้ใช้ว่าโมเดลมั่นใจเพียงใด การทำนายเป็น POSITIVE ด้วยความมั่นใจ 99% แตกต่างอย่างมากจากการทำนายด้วยความมั่นใจ 52% การส่งต่อผลการทำนายที่มีความมั่นใจต่ำให้มนุษย์ตรวจสอบเป็นแนวปฏิบัติทั่วไปในระบบจริงที่ใช้จัดการการตัดสินใจสำคัญ
import torch
import torch.nn.functional as F
def predict_with_confidence(text, model, tokenizer, device):
model.eval()
id2label = {0: 'NEGATIVE', 1: 'POSITIVE'}
inputs = tokenizer(text, return_tensors='pt',
truncation=True, max_length=256)
inputs = {k: v.to(device) for k, v in inputs.items()}
with torch.no_grad():
logits = model(**inputs).logits
probs = F.softmax(logits, dim=1).squeeze()
pred_id = torch.argmax(probs).item()
confidence = probs[pred_id].item()
return id2label[pred_id], round(confidence, 4)
# label, conf = predict_with_confidence('Terrible movie.', model, tokenizer, device)
# print(label, conf) # NEGATIVE 0.9732การประเมินด้วยความแม่นยำและ F1
หลังรวบรวมผลการทำนายจากชุดทดสอบทั้งหมดแล้ว ให้คำนวณตัวชี้วัดมาตรฐานด้วย scikit-learn ความแม่นยำ คือสัดส่วนของผลการทำนายที่ถูกต้อง เหมาะสำหรับกรณีที่คลาสมีสัดส่วนสมดุล คะแนน F1 คือค่าเฉลี่ยฮาร์มอนิกของความเที่ยงและการเรียกคืน ซึ่งสำคัญเมื่อคลาสหนึ่ง (เช่น รีวิวเชิงบวก) มีความสำคัญมากกว่า หรือเมื่อคลาสมีสัดส่วนไม่สมดุล classification_report จะแสดงตัวชี้วัดทั้งหมดในตารางเดียวที่อ่านง่าย
from sklearn.metrics import classification_report, accuracy_score
import torch
all_preds, all_labels = [], []
model.eval()
with torch.no_grad():
for batch in test_loader:
outputs = model(
input_ids=batch['input_ids'].to(device),
attention_mask=batch['attention_mask'].to(device)
)
preds = torch.argmax(outputs.logits, dim=1).cpu().numpy()
all_preds.extend(preds)
all_labels.extend(batch['label'].numpy())
print('Accuracy:', accuracy_score(all_labels, all_preds))
print(classification_report(all_labels, all_preds,
target_names=['NEGATIVE', 'POSITIVE']))เมทริกซ์ความสับสนสำหรับ BERT
เมทริกซ์ความสับสน แสดงรายละเอียดของผลการทำนายเทียบกับป้ายกำกับจริง สำหรับการวิเคราะห์ความรู้สึก ช่องนอกแนวทแยงจะแสดงผลบวกลวง (ทำนายเป็น POSITIVE แต่จริง ๆ เป็น NEGATIVE) และผลลบลวง (ทำนายเป็น NEGATIVE แต่จริง ๆ เป็น POSITIVE) การแสดงภาพด้วยแผนที่ความร้อนของ seaborn ช่วยเผยให้เห็นข้อผิดพลาดที่เกิดเป็นรูปแบบ เช่น โมเดลทำนายคลาสใดคลาสหนึ่งมากเกินไปหรือไม่ หรือรีวิวบางประเภทถูกจำแนกผิดอย่างต่อเนื่องหรือไม่
from sklearn.metrics import confusion_matrix
import seaborn as sns
import matplotlib.pyplot as plt
import numpy as np
cm = confusion_matrix(all_labels, all_preds)
plt.figure(figsize=(6, 5))
sns.heatmap(cm, annot=True, fmt='d', cmap='Blues',
xticklabels=['NEG', 'POS'],
yticklabels=['NEG', 'POS'])
plt.ylabel('True Label')
plt.xlabel('Predicted Label')
plt.title('BERT Confusion Matrix on IMDB Test Set')
plt.tight_layout()
plt.savefig('bert_confusion.png')การอนุมานเป็นกลุ่มเพื่อประสิทธิภาพ
การอนุมานทีละตัวอย่างทำได้ช้า ควรประมวลผลตัวอย่างเป็นกลุ่มเพื่อใช้ประโยชน์จากการประมวลผลแบบขนานของ GPU กำหนด batch_size คงที่ใน DataLoader ส่งข้อมูลทั้งกลุ่มผ่านโมเดล แล้วรวบรวมผลลัพธ์ บน GPU การอนุมานเป็นกลุ่มอาจเร็วกว่าแบบทีละตัวอย่างถึง 50 เท่า ใช้ torch.no_grad() และย้ายเทนเซอร์ไปยังอุปกรณ์ที่ถูกต้องเพื่อประสิทธิภาพสูงสุด
import torch
from torch.utils.data import DataLoader, TensorDataset
from transformers import BertTokenizer
def batch_predict(texts, model, tokenizer, device, batch_size=32):
model.eval()
all_predictions = []
for i in range(0, len(texts), batch_size):
batch_texts = texts[i:i+batch_size]
enc = tokenizer(batch_texts, truncation=True, padding=True,
max_length=256, return_tensors='pt')
enc = {k: v.to(device) for k, v in enc.items()}
with torch.no_grad():
logits = model(**enc).logits
preds = torch.argmax(logits, dim=1).cpu().tolist()
all_predictions.extend(preds)
return all_predictionsซิกมอยด์สำหรับการจำแนกหลายป้ายกำกับ
เมื่อข้อความหนึ่งสามารถอยู่ใน หลายคลาสพร้อมกัน (เช่น รีวิวที่ทั้ง “ตลก” และ “สะเทือนอารมณ์”) ให้ใช้ sigmoid แทน softmax ซิกมอยด์จะทำงานแยกกันกับโลจิตของแต่ละคลาส และสร้างค่าความน่าจะเป็นระหว่าง 0 ถึง 1 สำหรับแต่ละคลาส โดยผลรวมไม่จำเป็นต้องเป็น 1 ใช้ค่าขีดแบ่ง (โดยทั่วไปคือ 0.5) กับค่าความน่าจะเป็นแต่ละค่าเพื่อสร้างผลการทำนายแบบไบนารีสำหรับแต่ละคลาส กำหนด problem_type='multi_label_classification' ใน BertForSequenceClassification
import torch
import torch.nn.functional as F
# 5 classes, multi-label: a text can have multiple labels
logits = torch.tensor([[1.2, -0.5, 2.1, -1.8, 0.3]])
probs = torch.sigmoid(logits)
print('Per-class probabilities:', probs)
threshold = 0.5
predicted_labels = (probs > threshold).int()
print('Predicted labels (multi-hot):', predicted_labels)
# e.g., [1, 0, 1, 0, 0] -- classes 0 and 2 are predictedการจัดการตัวอย่างที่จำแนกผิด
ควรตรวจสอบตัวอย่างที่จำแนกผิดด้วยตนเองเสมอ แสดงตัวอย่างที่โมเดลทำนายเป็น 0 แต่ป้ายกำกับจริงเป็น 1 (ผลลบลวง) และในทางกลับกัน รูปแบบที่พบบ่อย ได้แก่ การประชดประชัน (“ช่างเป็นหายนะของภาพยนตร์ที่ยอดเยี่ยมจริง ๆ”), การเปลี่ยนแปลงของขอบเขตข้อมูล (การใช้คำศัพท์แบบโบราณ) หรือ รีวิวยาว ที่โมเดลเห็นเพียง 256 โทเค็นแรก การทำความเข้าใจรูปแบบความล้มเหลวช่วยชี้แนวทางการสร้างคุณลักษณะหรือการรวบรวมข้อมูล
import numpy as np
all_preds = np.array(all_preds)
all_labels = np.array(all_labels)
texts = test_dataset['text'] if hasattr(test_dataset, '__getitem__') else []
false_negatives = np.where((all_preds == 0) & (all_labels == 1))[0]
false_positives = np.where((all_preds == 1) & (all_labels == 0))[0]
print('False negatives (predicted NEG, true POS):')
for idx in false_negatives[:3]:
print(' -', str(texts[idx])[:120] if texts else idx)
print('False positives (predicted POS, true NEG):')
for idx in false_positives[:3]:
print(' -', str(texts[idx])[:120] if texts else idx)การส่งออกผลการทำนายเป็น CSV
ในการใช้งานจริงหรือการแข่งขัน คุณมักต้องส่งออกผลการทำนายเป็นไฟล์ CSV ใช้ pandas สร้าง DataFrame ที่มีข้อความต้นฉบับ ป้ายกำกับจริง ป้ายกำกับที่ทำนาย และคะแนนความมั่นใจ รูปแบบนี้สะดวกต่อการแบ่งปันกับผู้เกี่ยวข้อง การตรวจสอบ และการใช้เป็นข้อมูลเข้าสำหรับกระบวนการรายงานขั้นต่อไป ควรรวมรุ่นของโมเดลและเวลาประทับของการทำนายไว้ในข้อมูลกำกับเสมอ
import pandas as pd
import torch.nn.functional as F
import torch
results = []
id2label = {0: 'NEGATIVE', 1: 'POSITIVE'}
model.eval()
for i, text in enumerate(sample_texts):
inputs = tokenizer(text, return_tensors='pt',
truncation=True, max_length=256)
with torch.no_grad():
logits = model(**inputs).logits
probs = F.softmax(logits, dim=1).squeeze()
pred = torch.argmax(probs).item()
results.append({
'text': text[:80],
'true_label': id2label[sample_labels[i]],
'predicted_label': id2label[pred],
'confidence': round(probs[pred].item(), 4)
})
df = pd.DataFrame(results)
df.to_csv('bert_predictions.csv', index=False)
print(df.head())ตรวจสอบความเข้าใจ
ทดสอบความเข้าใจแนวคิดการเรียนรู้ของเครื่องด้วย Python จากบทเรียนนี้
สรุปบทเรียน
ในบทเรียนนี้ คุณได้เรียนรู้ว่า โลจิตคือคะแนนดิบของโมเดลที่แปลงเป็นค่าความน่าจะเป็นด้วยซอฟต์แมกซ์สำหรับงานหลายคลาส หรือด้วยซิกมอยด์สำหรับงานหลายป้ายกำกับ argmax ให้ดัชนีคลาสที่ทำนาย ซึ่งจับคู่กับป้ายกำกับที่มนุษย์อ่านเข้าใจได้ผ่านพจนานุกรม id2label และ classification_report กับเมทริกซ์ความสับสนร่วมกันช่วยให้เห็นประสิทธิภาพของโมเดลได้ครบถ้วนนอกเหนือจากความแม่นยำ ต่อไปเราจะสำรวจ MLflow สำหรับติดตามการทดลอง พารามิเตอร์ และตัวชี้วัดจากการฝึกหลายรอบ
เรียนรู้ Python ด้วย AI tutor — ฟรี
เขียนและเรียกใช้โค้ดจริงในเบราว์เซอร์ของคุณ รับความช่วยเหลือทันทีจาก AI tutor 24/7 และเรียนรู้ต่อจากที่คุณหยุดบนเว็บหรือในแอป
- คอร์ส
- 30
- บทเรียน
- 120
คำถามที่พบบ่อย
บทเรียน “การประเมินและการอนุมาน: จากลอจิตสู่ป้ายกำกับที่ทำนาย” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “การประเมินและการอนุมาน: จากลอจิตสู่ป้ายกำกับที่ทำนาย” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Machine Learning Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Machine Learning Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “การประเมินและการอนุมาน: จากลอจิตสู่ป้ายกำกับที่ทำนาย”
ผู้เรียนจะคำนวณ softmax บนลอจิต ถอดรหัสดัชนีคลาสที่ทำนายเป็นป้ายกำกับ และประเมินแบบจำลองที่ปรับแต่งแล้วด้วยความแม่นยำและ F1 บนชุดทดสอบที่กันไว้ คุณปฏิบัติ Machine Learning Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Machine Learning Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน Machine Learning Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน
บทเรียน “การประเมินและการอนุมาน: จากลอจิตสู่ป้ายกำกับที่ทำนาย” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน Machine Learning Academy นี้ได้ไหม
ได้ บทเรียน Machine Learning Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- สถาปัตยกรรม Transformer: ความใส่ใจ โทเค็น และบริบท
- ตัวแยกโทเค็น Hugging Face: การเข้ารหัสข้อความสำหรับ BERT
- การปรับแต่ง BertForSequenceClassification
- การประเมินและการอนุมาน: จากลอจิตสู่ป้ายกำกับที่ทำนาย