Evaluering og inferens: Fra logits til predikerte etiketter
Deltakere vil beregne softmax over logits, dekode predikerte klasseindekser til etiketter og evaluere den finjusterte modellen med nøyaktighet og F1 på et avsatt testsett.
Evaluering og inferens: Fra logits til predikerte etiketter er en gratis leksjon i Machine Learning Academy på CoddyKit. Dette er leksjon 4 av 4. Du kan lese hele leksjonen gratis nedenfor – og deretter øve praktisk i nettleseren med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Den er en del av læringsløpet i Machine Learning Academy, og fremdriften din synkroniseres mellom nettet og CoddyKit-appen. Kurset i Machine Learning Academy inneholder totalt 4 leksjoner.
Hva er logits?
Resultatet fra det siste lineære laget i en klassifiseringsmodell kalles logits: rå, ikke-normaliserte skårer for hver klasse. I et problem med to klasser (negativ/positiv) kan en logitvektor være [-1.2, 3.5], noe som betyr at modellen klart foretrekker klasse 1 (positiv). Logits kan være alle reelle tall; de er ikke sannsynligheter. Vi trenger et ekstra trinn (softmax eller sigmoid) for å konvertere dem til tolkbare sannsynlighetsverdier som summerer seg til 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: Konvertere logits til sannsynligheter
Funksjonen softmax konverterer en vektor med reelle logits til en sannsynlighetsfordeling. For klasse i: softmax(z_i) = exp(z_i) / sum(exp(z_j)). Eksponentialfunksjonen forsterker forskjeller: en logitforskjell på 2 gjør at den ene klassen blir omtrent 7 ganger mer sannsynlig enn den andre. Softmax brukes til flerklasseklassifisering, der nøyaktig én klasse er riktig.
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: Hente ut predikerte etiketter
Når vi har logitvektorer for en batch med eksempler, returnerer torch.argmax(logits, dim=1) indeksen til klassen med høyest skår for hvert eksempel. Dette er den predikerte klasseetiketten. For BERT som er finjustert med num_labels=2, er resultatet 0 (negativ) eller 1 (positiv). Vi trenger ikke bruke softmax før argmax, fordi softmax er monoton: den største logiten gir alltid den største sannsynligheten.
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)])Dekode predikerte indekser til klassenavn
Modellresultater er heltallsindekser. I et produksjonssystem vedlikeholder De en kobling fra indeks til en lett forståelig etikett. Lagre denne som en liste eller ordbok, og bruk den predikerte heltallsverdien som indeks. For BERT som er finjustert på IMDB, er koblingen ganske enkelt {0: 'NEGATIVE', 1: 'POSITIVE'}. For flerklasseoppgaver, som emneklassifisering, kan koblingen ha 20 eller flere oppføringer.
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) # POSITIVEKonfidensskårer fra sannsynligheter
Å returnere bare den predikerte etiketten er ofte ikke nok i reelle applikasjoner. En konfidensskår (sannsynligheten for den predikerte klassen) forteller brukerne hvor sikker modellen er. En prediksjon på POSITIVE med 99 % konfidens er svært forskjellig fra en med 52 % konfidens. Det er vanlig praksis i produksjonssystemer som håndterer sensitive avgjørelser, å merke prediksjoner med lav konfidens for menneskelig gjennomgang.
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.9732Evaluere med nøyaktighet og F1
Etter at De har samlet inn prediksjoner for hele testsettet, beregner De standardmåltall med scikit-learn. Nøyaktighet er andelen riktige prediksjoner – nyttig når klassene er balanserte. F1-skår er det harmoniske gjennomsnittet av presisjon og gjenkalling – viktig når én klasse (for eksempel positive anmeldelser) er viktigere, eller når klassene er ubalanserte. classification_report skriver ut alle måltallene i én oversiktlig tabell.
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']))Forvekslingsmatrise for BERT
En forvekslingsmatrise viser fordelingen av prediksjoner mot de sanne etikettene. For sentimentanalyse viser cellene utenfor diagonalen falske positive (predikert POSITIVE, men egentlig NEGATIVE) og falske negative (predikert NEGATIVE, men egentlig POSITIVE). Ved å visualisere dette med et seaborn-heatmap blir systematiske feil synlige: predikerer modellen én klasse for ofte? Blir bestemte typer anmeldelser konsekvent feilklassifisert?
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')Batch-inferens for effektivitet
Det går sakte å kjøre inferens på ett eksempel om gangen. Behandle eksempler i batcher for å utnytte parallelliteten på GPU-en. Angi en fast batch_size i DataLoader, send hele batcher gjennom modellen og samle inn resultatene. På en GPU kan batchbasert inferens være 50 ganger raskere enn inferens på ett enkelt eksempel. Bruk torch.no_grad() og flytt tensorene til riktig enhet for best mulig ytelse.
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_predictionsSigmoid for fleretikettklassifisering
Når en tekst kan tilhøre flere klasser samtidig (for eksempel en anmeldelse som både er «morsom» og «følelsesladet»), bruker De sigmoid i stedet for softmax. Sigmoid brukes uavhengig på hver klasselogit og gir en sannsynlighet mellom 0 og 1 for hver klasse, uten at sannsynlighetene må summere seg til 1. Bruk en terskel (vanligvis 0,5) på hver sannsynlighet for å få en binær prediksjon per klasse. Angi problem_type='multi_label_classification' i 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 predictedHåndtere feilklassifiserte eksempler
Undersøk alltid feilklassifiserte eksempler manuelt. Skriv ut eksempler der modellen predikerte 0, mens den sanne etiketten er 1 (falske negative), og omvendt. Vanlige mønstre omfatter sarkasme («For en strålende filmkatastrofe»), domeneendring (gammeldags ordforråd) eller lange anmeldelser, der modellen bare ser de første 256 tokenene. Når De forstår feilkildene, blir det enklere å forbedre funksjonene eller samle inn mer data.
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)Eksportere prediksjoner til CSV
I produksjons- eller konkurransesammenheng trenger De ofte å eksportere prediksjoner til en CSV-fil. Bruk pandas til å opprette en DataFrame med den opprinnelige teksten, den sanne etiketten, den predikerte etiketten og konfidensskåren. Dette formatet er enkelt å dele med interessenter, revidere og bruke som inndata i etterfølgende rapporteringsprosesser. Ta alltid med modellversjonen og tidspunktet for prediksjonen i metadataene.
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())Kort test
Test forståelsen Deres av konseptene innen maskinlæring med Python fra denne leksjonen.
Oppsummering av leksjonen
I denne leksjonen har De lært at: logits er rå modellskårer som konverteres til sannsynligheter med softmax for flerklasseoppgaver eller sigmoid for fleretikettoppgaver, argmax gir indeksen til den predikerte klassen, som kobles til en lett forståelig etikett via en id2label-ordbok, og classification_report og forvekslingsmatrisen sammen gir et fullstendig bilde av modellens ytelse utover nøyaktighet. Neste tema er MLflow for sporing av eksperimenter, parametere og måltall på tvers av flere treningskjøringer.
Lær deg Python med en AI-veileder – gratis
Skriv og kjør ekte kode i nettleseren, få umiddelbar hjelp fra en AI-veileder som er tilgjengelig døgnet rundt, og fortsett der du slapp – på nettet eller i appen.
- Kurs
- 30
- Leksjoner
- 120
Ofte stilte spørsmål
Er leksjonen «Evaluering og inferens: Fra logits til predikerte etiketter» gratis?
Ja – hele teksten i «Evaluering og inferens: Fra logits til predikerte etiketter» er gratis å lese her på nettet. For å øve interaktivt med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt, og for å låse opp resten av Machine Learning Academy-kurset, kan du oppgradere til CoddyKit PRO. Kurset i Machine Learning Academy inneholder totalt 4 leksjoner.
Hva lærer jeg i «Evaluering og inferens: Fra logits til predikerte etiketter»?
Deltakere vil beregne softmax over logits, dekode predikerte klasseindekser til etiketter og evaluere den finjusterte modellen med nøyaktighet og F1 på et avsatt testsett. Du øver på Machine Learning Academy med praktisk kode som du kjører direkte i nettleseren, mens en AI-veileder som er tilgjengelig døgnet rundt, svarer på spørsmålene dine mens du jobber deg gjennom leksjonen.
Trenger jeg erfaring for å begynne med Machine Learning Academy?
Ingen tidligere erfaring er nødvendig. Machine Learning Academy på CoddyKit er lagt opp for både nybegynnere og viderekomne, så De kan begynne her eller helt fra start og lære i Deres eget tempo. Dette er leksjon 4 av 4.
Hvor lang tid tar leksjonen «Evaluering og inferens: Fra logits til predikerte etiketter»?
De fleste CoddyKit-leksjoner tar omtrent 5–10 minutter. Hver leksjon er kort og interaktiv, slik at De gjør jevne fremskritt og kan fortsette akkurat der De slapp – både på nettet og i appen.
Kan jeg skrive og kjøre kode i denne Machine Learning Academy-leksjonen?
Ja. Alle Machine Learning Academy-leksjoner har en innebygd kodeeditor, slik at De kan skrive og kjøre ekte kode direkte i nettleseren og få umiddelbar tilbakemelding fra AI – uten lokal konfigurering.
Alle leksjonene i dette kurset
- Transformerarkitektur: Attention, tokens og kontekst
- Hugging Face-tokenizere: Kode tekst for BERT
- Finjustere BertForSequenceClassification
- Evaluering og inferens: Fra logits til predikerte etiketter