Attention katmanı
- Makine Öğrenmesi kursu
- Uzman
- Ders 14/44
- 7 dk
Multi-head attention katmanı eklersin.
Gömme ve dikkat katmanı
Kimlikler, bir gömme tablosundan (sözlük boyutu × d) satır seçilerek vektöre çevrilir. Ardından yığın hâlinde ölçekli dikkat uygulanır; şekiller (yığın, n, d) olur:
E = rng.normal(size=(len(sozluk), d)) * 0.5
H = E[X] # (5, 5, d)
skor = Q @ K.transpose(0, 2, 1) / np.sqrt(d) # (5, 5, 5)NumPy'da E[X], X'in her kimliği için E'nin o satırını alır: bu, nn.Embedding'in yaptığı işin aynısıdır.
Dolguyu maskelemek
Maske, anahtar (sütun) eksenine uygulanır: pad[:, None, :] şekli (yığın, 1, n) olur ve tüm sorgu satırlarına yayılır. Dolgu sütunlarının skoru −1e9 yapılınca ağırlıkları sıfırlanır:
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−∞ yerine −1e9 kullanmak, tamamen dolgu olan bir satırda NaN çıkmasını önler.
Uygulama Maskeli dikkat katmanı
Verilen dikkat şablonunu tamamla (maskeyi uygula). Gömme H = E[X] ile Q, K, V'yi hesaplayıp dikkati uygula. Çıktının ve ağırlıkların şeklini aynı satırda yazdır. Ardından üçüncü cümlenin ("iyi") ağırlık satırlarından ilkini np.round(..., 3) ile ve dolgu sütunlarına giden toplam ağırlığı round(..., 6) ile 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
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
# 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
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 dikkat(Q, K, V, pad):
skor = Q @ K.transpose(0, 2, 1) / np.sqrt(Q.shape[-1])
skor = np.where(pad[:, None, :], -1e9, skor)
A = softmax(skor)
return A @ V, A
H = E[X]
Y, A = dikkat(H @ Wq, H @ Wk, H @ Wv, pad)
print(Y.shape, A.shape)
print(np.round(A[2, 0], 3))
print(round(float(A[pad[:, None, :].repeat(5, axis=1)].sum()), 6))Beklenen çıktı
(5, 5, 8) (5, 5, 5) [1. 0. 0. 0. 0.] 0.0
Soru ve cevaplar
Dersin sorularını cevaplarıyla birlikte inceleyebilirsin. Kendini denemek istersen dersi interaktif olarak çöz.
1 E (10, 8) ve X (5, 5) ise E[X]'in şekli nedir?
- (5, 8)
- (5, 5)
- (5, 5, 8) Doğru cevap
- (10, 8)
Açıklama: Her kimlik 8 boyutlu bir vektöre dönüşür.
2 Maskeyi anahtar eksenine yay.
skor = np.where(pad[:, ____, :], -1e9, skor)
skor = np.where(pad[:, None, :], -1e9, skor)
Açıklama: None yeni bir eksen ekler: (yığın, 1, n).
3 Şekilleri eşleştir (yığın 5, n 5, d 8).
| Kavram | Anlamı |
|---|---|
E[X] |
(5, 5, 8) |
skor |
(5, 5, 5) |
pad[:, None, :] |
(5, 1, 5) |
E |
(9, 8) |