CodeBlanks Logo Icon CodeBlanks

Sonuç

Model çıktısını yazdırırsın.

Sonuç: sınıflandırıcıyı eğitmek

Encoder'ın ağırlıklarını bu projede eğitmiyoruz (bu, bir sonraki BERT grubunda fine-tuning ile yapılacak). Bunun yerine cümle vektörlerinin üstüne bir lojistik regresyon koyuyoruz; buna doğrusal sondalama (linear probe) denir:

from sklearn.linear_model import LogisticRegression

C = cumle_vektoru(encoder(X, pad), pad)
model = LogisticRegression(max_iter=1000).fit(C, y)
print(model.predict(cumle_vektoru(encoder(X_test, pad_test), pad_test)))

Sondalama, bir temsilin bir bilgiyi "taşıyıp taşımadığını" ölçmenin standart yoludur.

Değerlendirme ve sınırlar

Eğitimde görülmemiş cümlelerle sınamak gerekir. Eğitilmemiş rastgele bir encoder bile, kelime gömmeleri ortalamaya taşındığı için "iyi"/"kötü" gibi belirgin kelimeleri yakalayabilir. Yine de beş cümlelik bir eğitim kümesiyle bazı test cümleleri yanlış sınıflanır; "iyi değil" gibi olumsuzlamayı çözmek için encoder'ın eğitilmesi gerekir:

test = ["iyi film", "kötü oyuncular", "senaryo iyi", "film kötü"]
# sözlükte olmayan kelime yoksa kodla() doğrudan çalışır

Gerçek projelerde bu adım, önceden eğitilmiş bir modelin (BERT) üzerine ince ayarla yapılır.

Uygulama Sondalama ve tahmin

Verilen encoder ve cumle_vektoru ile eğitim cümlelerinin vektörlerini hesapla ve LogisticRegression(C=10, max_iter=1000) eğit. Eğitim doğruluğunu yazdır. Ardından test cümlelerini kodlayıp tahminleri .tolist() ile ve test doğruluğunu yazdır.

Başlangıç kodu

model.py
import numpy as np

def softmax(z, eksen=-1):
    e = np.exp(z - z.max(axis=eksen, keepdims=True))
    return e / e.sum(axis=eksen, keepdims=True)

metinler = ["film çok iyi", "çok kötü bir film", "iyi", "oyuncular iyi ama senaryo kötü", "kötü"]
sozluk = {"<pad>": 0}
for c in metinler:
    for k in c.split():
        sozluk.setdefault(k, len(sozluk))

def kodla(c, n=5):
    ids = [sozluk[k] for k in c.split()][:n]
    return ids + [0] * (n - len(ids))

X = np.array([kodla(c) for c in metinler])
pad = X == 0

def dikkat(Q, K, V, pad):
    d = Q.shape[-1]
    skor = Q @ K.transpose(0, 2, 1) / np.sqrt(d)
    skor = np.where(pad[:, None, :], -1e9, skor)
    A = softmax(skor)
    return A @ V, A

def layer_norm(x, eps=1e-5):
    return (x - x.mean(-1, keepdims=True)) / np.sqrt(x.var(-1, keepdims=True) + eps)

rng = np.random.default_rng(0)
d = 8
E = rng.normal(size=(len(sozluk), d)) * 0.5
Wq, Wk, Wv = rng.normal(size=(3, d, d)) * 0.5

def encoder(X, pad):
    H = E[X]
    Y, A = dikkat(H @ Wq, H @ Wk, H @ Wv, pad)
    return layer_norm(H + Y)

def cumle_vektoru(H, pad):
    m = (~pad)[:, :, None]
    return (H * m).sum(axis=1) / m.sum(axis=1)

from sklearn.linear_model import LogisticRegression
y = np.array([1, 0, 1, 0, 0])
test = ["iyi film", "kötü oyuncular", "senaryo iyi", "film kötü"]
y_test = np.array([1, 0, 1, 0])

# buraya yaz

Örnek çözüm

model.py
import numpy as np

def softmax(z, eksen=-1):
    e = np.exp(z - z.max(axis=eksen, keepdims=True))
    return e / e.sum(axis=eksen, keepdims=True)

metinler = ["film çok iyi", "çok kötü bir film", "iyi", "oyuncular iyi ama senaryo kötü", "kötü"]
sozluk = {"<pad>": 0}
for c in metinler:
    for k in c.split():
        sozluk.setdefault(k, len(sozluk))

def kodla(c, n=5):
    ids = [sozluk[k] for k in c.split()][:n]
    return ids + [0] * (n - len(ids))

X = np.array([kodla(c) for c in metinler])
pad = X == 0

def dikkat(Q, K, V, pad):
    d = Q.shape[-1]
    skor = Q @ K.transpose(0, 2, 1) / np.sqrt(d)
    skor = np.where(pad[:, None, :], -1e9, skor)
    A = softmax(skor)
    return A @ V, A

def layer_norm(x, eps=1e-5):
    return (x - x.mean(-1, keepdims=True)) / np.sqrt(x.var(-1, keepdims=True) + eps)

rng = np.random.default_rng(0)
d = 8
E = rng.normal(size=(len(sozluk), d)) * 0.5
Wq, Wk, Wv = rng.normal(size=(3, d, d)) * 0.5

def encoder(X, pad):
    H = E[X]
    Y, A = dikkat(H @ Wq, H @ Wk, H @ Wv, pad)
    return layer_norm(H + Y)

def cumle_vektoru(H, pad):
    m = (~pad)[:, :, None]
    return (H * m).sum(axis=1) / m.sum(axis=1)

from sklearn.linear_model import LogisticRegression
y = np.array([1, 0, 1, 0, 0])
test = ["iyi film", "kötü oyuncular", "senaryo iyi", "film kötü"]
y_test = np.array([1, 0, 1, 0])

C = cumle_vektoru(encoder(X, pad), pad)
model = LogisticRegression(C=10, max_iter=1000).fit(C, y)
print(model.score(C, y))
Xt = np.array([kodla(c) for c in test])
Ct = cumle_vektoru(encoder(Xt, Xt == 0), Xt == 0)
print(model.predict(Ct).tolist())
print(model.score(Ct, y_test))

Beklenen çıktı

1.0
[1, 0, 0, 0]
0.75

Soru ve cevaplar

Dersin sorularını cevaplarıyla birlikte inceleyebilirsin. Kendini denemek istersen dersi interaktif olarak çöz.

1 Doğrusal sondalamada hangi parametreler eğitilir?

  • Yalnızca üstteki doğrusal sınıflandırıcınınkiler Doğru cevap
  • Tüm encoder
  • Yalnızca gömme tablosu
  • Hiçbiri

Açıklama: Encoder dondurulur; yalnızca üst katman öğrenir.

2 Sondalama modelini eğit.

Soru
model = LogisticRegression(max_iter=1000).____(C, y)
Cevap
model = LogisticRegression(max_iter=1000).fit(C, y)

Açıklama: fit eğitir; predict tahmin eder.

3 Eşleştir.

Kavram Anlamı
encoder Donmuş
LogisticRegression Eğitilen üst katman
test cümleleri Görülmemiş veri
olumsuzlama Eğitim gerektirir

Uzman bölümündeki tüm dersler