CodeBlanks Logo Icon CodeBlanks

Scaled dot-product

Scaled dot-product attention, query-key çarpımını boyutun kareköküne böler.

Ölçekli nokta çarpım

Boyut d büyüdükçe iç çarpımların varyansı da büyür (d bağımsız terimin toplamı). Büyük skorlar softmax'ı tek bir elemana yığar ve gradyan söner. Çözüm skorları √d_k ile bölmektir:

def attention(Q, K, V):
    d_k = Q.shape[-1]
    A = softmax(Q @ K.T / np.sqrt(d_k), eksen=-1)
    return A @ V, A

Bu, transformer'ın temel formülüdür: Attention(Q, K, V) = softmax(QKᵀ/√d_k) V.

Ölçeklemenin etkisi

Rastgele vektörlerde iç çarpımın standart sapması yaklaşık √d'dir. Ölçeklemeden sonra skorlar d'den bağımsız olarak ~1 standart sapmalı kalır:

rng = np.random.default_rng(0)
for d in [4, 64, 1024]:
    q, k = rng.normal(size=(2, 10000, d))
    s = (q * k).sum(axis=1)
    print(d, round(s.std(), 1), round((s / np.sqrt(d)).std(), 2))

Ölçeksiz büyük skorlarda softmax neredeyse one-hot olur; bu, eğitimi başlangıçta kilitleyebilir.

Uygulama attention fonksiyonu

Ölçekli nokta çarpım attention(Q, K, V) fonksiyonunu yaz (çıktı ve ağırlık döndürsün). d = 4 ve 1024 için rastgele (10000, d) Q ve K'de iç çarpım standart sapmasını ölçeklemeden önce ve sonra round(..., 1) ile aynı satırda yazdır. Son olarak verilen küçük Q, K, V için çıktıyı np.round(..., 3) 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)
Qk = np.array([[1., 1.], [0., 2.]])
Kk = np.array([[1., 0.], [0., 1.]])
Vk = np.array([[10., 0.], [0., 10.]])

# 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)
Qk = np.array([[1., 1.], [0., 2.]])
Kk = np.array([[1., 0.], [0., 1.]])
Vk = np.array([[10., 0.], [0., 10.]])

def attention(Q, K, V):
    d_k = Q.shape[-1]
    A = softmax(Q @ K.T / np.sqrt(d_k), eksen=-1)
    return A @ V, A

for d in [4, 1024]:
    q, k = rng.normal(size=(2, 10000, d))
    s = (q * k).sum(axis=1)
    print(d, round(s.std(), 1), round((s / np.sqrt(d)).std(), 1))
print(np.round(attention(Qk, Kk, Vk)[0], 3))

Beklenen çıktı

4 2.0 1.0
1024 32.0 1.0
[[5.    5.   ]
 [1.956 8.044]]

Soru ve cevaplar

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

1 d_k = 64 iken skorlar kaça bölünür?

  • 4096
  • 2
  • 8 Doğru cevap
  • 64

Açıklama: ��64 = 8.

2 Skorları ölçekle.

Soru
A = softmax(Q @ K.T / np.____(d_k), eksen=-1)
Cevap
A = softmax(Q @ K.T / np.sqrt(d_k), eksen=-1)

Açıklama: Bölen √d_k'dir.

3 Değerleri eşleştir.

Kavram Anlamı
d_k = 16 √d = 4
d_k = 64 √d = 8
ölçeksiz büyük skor One-hot softmax
ölçekli skor std ≈ 1

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