Encoder bloğu
- Makine Öğrenmesi kursu
- Uzman
- Ders 15/44
- 7 dk
Transformer encoder bloğu tanımlarsın.
Encoder bloğunu kurmak
Dikkat katmanını artık bağlantı, LayerNorm ve FFN ile sarıp tam bir encoder bloğu yapıyoruz. Girişe konum kodu da eklenir:
def encoder(X, pad):
H = E[X] + konum_kodu(X.shape[1], d)
Y, A = dikkat(H @ Wq, H @ Wk, H @ Wv, pad)
H = layer_norm(H + Y)
H = layer_norm(H + np.maximum(0, H @ W1) @ W2)
return H, AÇıktı her kelime için bağlamlı bir vektördür; "iyi" kelimesinin temsili artık cümlenin geri kalanına da bağlıdır.
Cümle vektörü: maskeli ortalama
Sınıflandırma için her cümleden tek bir vektör gerekir. Basit bir yol, yalnızca gerçek kelimelerin ortalamasını almaktır (BERT bunun yerine [CLS] belirtecini kullanır):
m = (~pad)[:, :, None] # (5, 5, 1)
cumle = (H * m).sum(axis=1) / m.sum(axis=1) # (5, d)Dolguyu ortalamaya katmak, kısa cümlelerin vektörünü dolgunun temsiline doğru çekerdi.
Uygulama Encoder ve cümle vektörü
encoder(X, pad) fonksiyonunu tamamla ve maskeli ortalamayla cümle vektörlerini hesapla. H ve cümle vektörlerinin şeklini aynı satırda yazdır. Ardından "iyi" kelimesinin 1. cümledeki (konum 2) ve 3. cümledeki (konum 0) temsillerinin farklı olduğunu np.allclose ile, ve dolgunun cümle vektörünü etkilemediğini (dolgu gömmesini değiştirip yeniden hesaplayarak) np.allclose ile aynı satırda yazdır.
Başlangıç kodu
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)
def konum_kodu(n, d):
aci = np.arange(n)[:, None] / 10000 ** (np.arange(0, d, 2) / d)
PE = np.zeros((n, d))
PE[:, 0::2], PE[:, 1::2] = np.sin(aci), np.cos(aci)
return PE
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
W1 = rng.normal(size=(d, 4 * d)) * 0.3
W2 = rng.normal(size=(4 * d, d)) * 0.3
# buraya yazÖrnek çözüm
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)
def konum_kodu(n, d):
aci = np.arange(n)[:, None] / 10000 ** (np.arange(0, d, 2) / d)
PE = np.zeros((n, d))
PE[:, 0::2], PE[:, 1::2] = np.sin(aci), np.cos(aci)
return PE
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
W1 = rng.normal(size=(d, 4 * d)) * 0.3
W2 = rng.normal(size=(4 * d, d)) * 0.3
def encoder(X, pad):
H = E[X] + konum_kodu(X.shape[1], d)
Y, A = dikkat(H @ Wq, H @ Wk, H @ Wv, pad)
H = layer_norm(H + Y)
return layer_norm(H + np.maximum(0, H @ W1) @ W2)
def cumle_vektoru(H, pad):
m = (~pad)[:, :, None]
return (H * m).sum(axis=1) / m.sum(axis=1)
H = encoder(X, pad)
C = cumle_vektoru(H, pad)
print(H.shape, C.shape)
E[0] += 10
C2 = cumle_vektoru(encoder(X, pad), pad)
print(np.allclose(H[0, 2], H[2, 0]), np.allclose(C, C2))Beklenen çıktı
(5, 5, 8) (5, 8) False True
Soru ve cevaplar
Dersin sorularını cevaplarıyla birlikte inceleyebilirsin. Kendini denemek istersen dersi interaktif olarak çöz.
1 "film çok iyi" ve "iyi" cümlelerinde "iyi" kelimesinin encoder çıktısı aynı mı olur?
- Encoder kelimeye bakmaz
- Hayır; bağlam ve konum farklı olduğu için değişir Doğru cevap
- Evet, aynı kelime aynı vektördür
- Yalnızca dolgu farklıdır
Açıklama: Gömme aynıdır, ama dikkat ve konum kodu temsili bağlama göre değiştirir.
2 Yalnızca gerçek kelimeleri topla.
cumle = (H * m).sum(axis=1) / m.____(axis=1)
cumle = (H * m).sum(axis=1) / m.sum(axis=1)
Açıklama: Bölen, cümledeki gerçek kelime sayısıdır.
3 Eşleştir.
| Kavram | Anlamı |
|---|---|
H + Y |
Artık bağlantı |
konum_kodu |
Sıra bilgisi |
maskeli ortalama |
Cümle vektörü |
[CLS] |
BERT'in cümle belirteci |