CodeBlanks Logo Icon CodeBlanks

Multi-head

Multi-head attention, birden çok attention başlığını paralel çalıştırır.

Çok başlı dikkat

Tek bir dikkat başı tek bir ilişki türüne odaklanır. Çok başlı dikkat, d boyutlu temsili h parçaya böler; her baş kendi Q, K, V'siyle farklı bir ilişkiyi (dilbilgisi, eşgönderim, konum) öğrenir, sonuçlar birleştirilip bir çıktı dönüşümünden geçer:

# d_model = 512, h = 8  ->  her baş d_k = 64
# her baş: attention(X W_q^i, X W_k^i, X W_v^i)   (n, 64)
# birleşim: concat(baş_1..baş_8)                 (n, 512)
# çıktı:    birleşim @ W_o                       (n, 512)

Toplam hesap, tek bir 512 boyutlu başla yaklaşık aynıdır; ama model aynı anda birden çok bakış açısı kazanır.

Başlara bölme

Uygulamada başlar ayrı matrislerle değil, tek bir büyük projeksiyonun yeniden şekillendirilmesiyle hesaplanır: (n, d) → (h, n, d/h). Böylece tüm başlar tek bir toplu matris çarpımıyla işlenir:

n, d, h = 5, 8, 2
Q = X @ W_q                                  # (5, 8)
Qh = Q.reshape(n, h, d // h).transpose(1, 0, 2)   # (2, 5, 4)
skor = Qh @ Kh.transpose(0, 2, 1) / np.sqrt(d // h)   # (2, 5, 5)
Yh = softmax(skor) @ Vh                       # (2, 5, 4)
Y = Yh.transpose(1, 0, 2).reshape(n, d)       # (5, 8)

PyTorch'ta nn.MultiheadAttention(embed_dim, num_heads) bunların hepsini yapar.

Uygulama Çok başlı dikkat

Verilen X (5×8) ve ağırlıklarla 2 başlı dikkat hesapla: Q, K, V'yi başlara böl, ölçekli dikkat uygula, birleştir. Qh.shape, başların ağırlık matrisinin şekli ve birleşik çıktının şeklini aynı satırda yazdır. Ardından her başın ağırlık satırlarının toplamının 1 olduğunu np.allclose ile 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)

rng = np.random.default_rng(0)
n, d, h = 5, 8, 2
X = rng.normal(size=(n, d))
W_q, W_k, W_v = rng.normal(size=(3, d, d))

# 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)

rng = np.random.default_rng(0)
n, d, h = 5, 8, 2
X = rng.normal(size=(n, d))
W_q, W_k, W_v = rng.normal(size=(3, d, d))

bol = lambda M: M.reshape(n, h, d // h).transpose(1, 0, 2)
Qh, Kh, Vh = bol(X @ W_q), bol(X @ W_k), bol(X @ W_v)
A = softmax(Qh @ Kh.transpose(0, 2, 1) / np.sqrt(d // h), eksen=-1)
Y = (A @ Vh).transpose(1, 0, 2).reshape(n, d)
print(Qh.shape, A.shape, Y.shape)
print(np.allclose(A.sum(axis=-1), 1))

Beklenen çıktı

(2, 5, 4) (2, 5, 5) (5, 8)
True

Soru ve cevaplar

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

1 d_model = 768 ve 12 baş varsa her başın boyutu nedir?

  • 9216
  • 64 Doğru cevap
  • 768
  • 12

Açıklama: 768 / 12 = 64 (BERT-base'in ayarı).

2 Temsili başlara böl.

Soru
Qh = Q.reshape(n, h, d // h).____(1, 0, 2)
Cevap
Qh = Q.reshape(n, h, d // h).transpose(1, 0, 2)

Açıklama: NumPy'da transpose eksenlerin yeni sırasını alır.

3 Şekilleri eşleştir (n=5, d=8, h=2).

Kavram Anlamı
Q (5, 8)
Qh (2, 5, 4)
skor (2, 5, 5)
d // h 4

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