Machine Learning Academy · Lektion

Finjustera BertForSequenceClassification

Ni kommer att läsa in en förtränad BERT-checkpoint, lägga till ett klassificeringshuvud, skapa en PyTorch DataLoader och finjustera modellen i två epoker på en IMDB-datamängd.

Lektion 3 av 413 steg

Finjustera BertForSequenceClassification är en gratis lektion i Machine Learning Academy på CoddyKit. Detta är lektion 3 av 4. Ni kan läsa hela lektionen gratis nedan och sedan öva praktiskt i webbläsaren med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt. Den ingår i lärvägen för Machine Learning Academy, och Era framsteg synkroniseras mellan webben och CoddyKit-appen. Kursen i Machine Learning Academy innehåller totalt 4 lektioner.

Vad är finjustering?

Finjustering tar en förtränad modell som redan förstår språkets struktur och anpassar den till en specifik uppgift med en liten märkt datamängd. BERT, som har förtränats på 3,3 miljarder ord, kan redan grammatik, semantik och kunskap om omvärlden. Finjusteringen lägger till ett uppgiftsspecifikt huvud (till exempel ett klassificeringslager) och tränar hela modellen från början till slut på Era märkta data under några epoker. Resultatet blir toppmodern prestanda med betydligt mindre data och beräkningskraft än vid träning från grunden.

Översikt över BertForSequenceClassification

BertForSequenceClassification är en BERT-modell med ett linjärt klassificeringshuvud ovanpå det slutliga dolda tillståndet för [CLS]-token. Det är standardklassen i Hugging Face för sentimentanalys, ämnesklassificering och alla uppgifter där en enda etikett tilldelas en hel text. Huvudet initieras slumpmässigt och tränas tillsammans med BERT-basen under finjusteringen.

from transformers import BertForSequenceClassification
import torch

# 2 classes: negative (0) and positive (1)
model = BertForSequenceClassification.from_pretrained(
    'bert-base-uncased',
    num_labels=2
)
print(model.config.num_labels)   # 2
print(model.classifier)          # Linear(in=768, out=2)

Läsa in IMDB-datasetet

IMDB-datasetet innehåller 50 000 filmrecensioner märkta som positiva (1) eller negativa (0). Vi använder Hugging Face-biblioteket datasets för att hämta och dela upp det. Datasetobjektet fungerar som en ordlista med listor och kan mappas med en tokeniseringsfunktion. Vi använder uppdelningen 25 000 för träning och 25 000 för test som tillhandahålls av det ursprungliga datasetets upphovspersoner.

from datasets import load_dataset
from transformers import BertTokenizer

dataset = load_dataset('imdb')
print(dataset)  # DatasetDict with train/test splits

tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')

def tokenize_fn(examples):
    return tokenizer(
        examples['text'],
        truncation=True,
        padding='max_length',
        max_length=256
    )

tokenized = dataset.map(tokenize_fn, batched=True)
tokenized.set_format('torch', columns=['input_ids', 'attention_mask', 'label'])

Skapa PyTorch DataLoaders

Efter tokeniseringen paketerar Ni Hugging Face-datasetet i PyTorch-objekt av typen DataLoader. batch_size styr hur många exempel modellen bearbetar per framåtpassering; 16 eller 32 är vanligt för BERT med tanke på GPU-minnets begränsningar. Blanda träningsmängden vid varje epok så att modellen inte överanpassar sig till exempelordningen, men håll valideringsmängden oförändrad för reproducerbar utvärdering.

from torch.utils.data import DataLoader

train_dataset = tokenized['train'].select(range(2000))  # small subset for demo
test_dataset = tokenized['test'].select(range(500))

train_loader = DataLoader(train_dataset, batch_size=16, shuffle=True)
test_loader = DataLoader(test_dataset, batch_size=32, shuffle=False)

print('Train batches:', len(train_loader))
print('Test batches:', len(test_loader))

Konfigurera optimeraren

Finjustering av BERT använder optimeraren AdamW med en låg inlärningshastighet (vanligtvis 2e-5 till 5e-5). En hög inlärningshastighet förstör de förtränade representationerna (katastrofalt glömskefenomen). Viktförlust (L2-regularisering) tillämpas på parametrar som inte är bias för att minska överanpassning. Hugging Faces get_linear_schedule_with_warmup används ofta för att värma upp LR under de första 10 % av stegen och sedan minska den linjärt.

from torch.optim import AdamW
from transformers import get_linear_schedule_with_warmup

optimizer = AdamW(model.parameters(), lr=2e-5, weight_decay=0.01)

num_epochs = 2
num_steps = len(train_loader) * num_epochs
warmup_steps = int(0.1 * num_steps)

scheduler = get_linear_schedule_with_warmup(
    optimizer,
    num_warmup_steps=warmup_steps,
    num_training_steps=num_steps
)

Träningsslingan för finjustering

PyTorch-träningsslingan för att finjustera BERT följer standardmönstret: iterera över batcher, beräkna framåtpasseringen, hämta förlusten från modellens utdata (BertForSequenceClassification returnerar automatiskt förlusten när etiketter skickas med), anropa loss.backward(), klipp gradienterna för att förhindra att de exploderar och uppdatera optimeraren och schemaläggaren. Att träna BERT i 2 epoker på IMDB ger vanligtvis cirka 92 % träffsäkerhet.

import torch

device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
model = model.to(device)

for epoch in range(2):
    model.train()
    total_loss = 0
    for batch in train_loader:
        optimizer.zero_grad()
        input_ids = batch['input_ids'].to(device)
        attention_mask = batch['attention_mask'].to(device)
        labels = batch['label'].to(device)

        outputs = model(input_ids=input_ids,
                        attention_mask=attention_mask,
                        labels=labels)
        loss = outputs.loss
        loss.backward()
        torch.nn.utils.clip_grad_norm_(model.parameters(), 1.0)
        optimizer.step()
        scheduler.step()
        total_loss += loss.item()

    print(f'Epoch {epoch+1} loss: {total_loss/len(train_loader):.4f}')

Utvärdering på valideringsmängden

Under utvärderingen anropar ni model.eval() för att inaktivera dropout och använder torch.no_grad() för att hoppa över gradientberäkningen, vilket sparar minne och gör inferensen snabbare. Hämta logits från modellens utdata (råa poäng före softmax), använd argmax för att få de förutsagda klassindexen och jämför dem med de korrekta etiketterna för att beräkna träffsäkerheten.

import torch
from sklearn.metrics import accuracy_score

model.eval()
all_preds, all_labels = [], []

with torch.no_grad():
    for batch in test_loader:
        input_ids = batch['input_ids'].to(device)
        attention_mask = batch['attention_mask'].to(device)
        labels = batch['label'].to(device)

        outputs = model(input_ids=input_ids,
                        attention_mask=attention_mask)
        preds = torch.argmax(outputs.logits, dim=1)
        all_preds.extend(preds.cpu().numpy())
        all_labels.extend(labels.cpu().numpy())

print('Accuracy:', accuracy_score(all_labels, all_preds))

Spara den finjusterade modellen

Efter finjusteringen sparar ni modellen och tokeniseraren tillsammans, så att de kan läsas in för inferens utan att behöva tränas om. model.save_pretrained(path) sparar modellvikterna och konfigurationen, medan tokenizer.save_pretrained(path) sparar vokabulären och inställningarna för tokenisering. Läs in dem igen med from_pretrained(path) i valfri ny Python-session.

import os

save_dir = './bert_imdb_finetuned'
os.makedirs(save_dir, exist_ok=True)

model.save_pretrained(save_dir)
tokenizer.save_pretrained(save_dir)
print('Model saved to', save_dir)

# Reload in a new session:
# from transformers import BertForSequenceClassification, BertTokenizer
# model = BertForSequenceClassification.from_pretrained(save_dir)
# tokenizer = BertTokenizer.from_pretrained(save_dir)

Använda Trainer-API:t

Hugging Faces klass Trainer kapslar in träningsslingan, utvärderingen, kontrollpunktssparandet och loggningen i ett enda högnivå-API. Definiera ett TrainingArguments-objekt med inlärningshastighet, batchstorlek och antal epoker och anropa sedan trainer.train(). Trainer hanterar automatiskt gradientklippning, schemaläggning av LR och träning med blandad precision, vilket minskar mängden standardkod avsevärt.

from transformers import Trainer, TrainingArguments
import numpy as np
from sklearn.metrics import accuracy_score

def compute_metrics(eval_pred):
    logits, labels = eval_pred
    preds = np.argmax(logits, axis=1)
    return {'accuracy': accuracy_score(labels, preds)}

training_args = TrainingArguments(
    output_dir='./bert_trainer',
    num_train_epochs=2,
    per_device_train_batch_size=16,
    per_device_eval_batch_size=32,
    learning_rate=2e-5,
    evaluation_strategy='epoch',
    save_strategy='epoch',
    load_best_model_at_end=True
)

trainer = Trainer(
    model=model,
    args=training_args,
    train_dataset=train_dataset,
    eval_dataset=test_dataset,
    compute_metrics=compute_metrics
)
trainer.train()

Övervaka träningen med TensorBoard

Skicka report_to='tensorboard' i TrainingArguments för att automatiskt logga förlust och mätvärden till TensorBoard. Starta TensorBoard med tensorboard --logdir ./bert_trainer/runs i en terminal för att visa förlustkurvor i realtid, scheman för inlärningshastigheten och utvärderingsmätvärden. Genom att övervaka träningsförlusten jämfört med valideringsförlusten kan ni upptäcka överanpassning tidigt och avsluta träningen vid rätt epok.

from transformers import TrainingArguments

training_args = TrainingArguments(
    output_dir='./bert_trainer',
    num_train_epochs=3,
    per_device_train_batch_size=16,
    learning_rate=2e-5,
    evaluation_strategy='steps',
    eval_steps=100,
    logging_steps=50,
    report_to='tensorboard',   # enable TensorBoard logging
    logging_dir='./bert_trainer/runs'
)
# Then: tensorboard --logdir ./bert_trainer/runs

Välja hur många lager som ska frysas

Ibland är datamängden för liten för att finjustera alla BERT:s 12 lager utan överanpassning. En vanlig strategi är att frysa de undre lagren (som lär sig allmänna språkliga egenskaper) och endast uppdatera de övre lagren (som lär sig uppgiftsspecifika egenskaper). Frys lager genom att ange requires_grad=False för valda parametergrupper. Övervaka valideringens träffsäkerhet för att välja det optimala frysdjupet utifrån datamängdens storlek.

from transformers import BertForSequenceClassification

model = BertForSequenceClassification.from_pretrained('bert-base-uncased', num_labels=2)

# Freeze embedding layer and first 6 encoder layers
for name, param in model.named_parameters():
    if 'embeddings' in name or 'encoder.layer.0' in name or \
       'encoder.layer.1' in name or 'encoder.layer.2' in name:
        param.requires_grad = False

# Count trainable parameters
trainable = sum(p.numel() for p in model.parameters() if p.requires_grad)
print(f'Trainable parameters: {trainable:,}')

Snabbtest

Testa er förståelse av begreppen inom Machine Learning with Python från den här lektionen.

Sammanfattning av lektionen

I den här lektionen har ni lärt er att BertForSequenceClassification lägger till ett linjärt huvud på [CLS] för klassificeringsuppgifter, att finjustering använder AdamW med en mycket låg inlärningshastighet för att undvika katastrofalt glömskefenomen och att Hugging Face Trainer-API:t förenklar träningsslingan med inbyggd utvärdering och kontrollpunktssparande. Härnäst tittar vi på hur man hämtar förutsägelser från logits och utvärderar den finjusterade modellen med träffsäkerhet och F1.

Gratis att börja

Lär dig Python med en AI-lärare – gratis

Skriv och kör riktig kod i webbläsaren, få omedelbar hjälp av en AI-lärare dygnet runt och fortsätt där du slutade – på webben eller i appen.

Kurser
30
Lektioner
120

Vanliga frågor

Är lektionen ”Finjustera BertForSequenceClassification” gratis?

Ja – hela texten till ”Finjustera BertForSequenceClassification” kan läsas gratis här på webben. Om Ni vill öva interaktivt med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt och låsa upp resten av kursen i Machine Learning Academy, kan Ni uppgradera till CoddyKit PRO. Kursen i Machine Learning Academy innehåller totalt 4 lektioner.

Vad lär jag mig i ”Finjustera BertForSequenceClassification”?

Ni kommer att läsa in en förtränad BERT-checkpoint, lägga till ett klassificeringshuvud, skapa en PyTorch DataLoader och finjustera modellen i två epoker på en IMDB-datamängd. Ni övar på Machine Learning Academy med praktisk kod som körs direkt i webbläsaren, medan en AI-handledare som är tillgänglig dygnet runt svarar på Era frågor under lektionen.

Behöver jag någon erfarenhet för att börja lära mig Machine Learning Academy?

Du behöver inga förkunskaper. Utbildningen i Machine Learning Academy på CoddyKit är upplagd för allt från nybörjare till avancerade elever, så att du kan börja här eller från början och gå fram i din egen takt. Detta är lektion 3 av 4.

Hur lång tid tar lektionen ”Finjustera BertForSequenceClassification”?

De flesta CoddyKit-lektioner tar cirka 5–10 minuter. Varje lektion är kort och interaktiv, så att du gör stadiga framsteg och kan fortsätta precis där du slutade – på webben eller i appen.

Kan jag skriva och köra kod i den här Machine Learning Academy-lektionen?

Ja. Varje Machine Learning Academy-lektion innehåller en inbyggd kodredigerare, så att du kan skriva och köra riktig kod direkt i webbläsaren och få omedelbar AI-feedback – utan lokal installation.

Alla lektioner i den här kursen

  1. Transformerarkitektur: Attention, tokens och kontext
  2. Hugging Face-tokeniserare: Koda text för BERT
  3. Finjustera BertForSequenceClassification
  4. Utvärdering och inferens: Från logits till predikterade etiketter
← Tillbaka till Machine Learning Academy