Makine Öğrenmesi
Meydan okuma 2
Transformer encoder tanımlarsın.
Meydan okuma: maskeli encoder
Bu meydan okumada yığın hâlinde çalışan, dolgu maskeli, pre-LN bir encoder bloğu yazacaksın:
def encoder_blogu(H, pad):
a = layer_norm(H)
H = H + dikkat(a, pad) # pre-LN
return H + ffn(layer_norm(H))
İyi bir encoder'ın sağlaması gereken özellik: dolgu bağımsızlığı. Bir cümlenin sonuna ne kadar dolgu eklenirse eklensin, gerçek konumların çıktısı değişmemelidir.
Uygulama Dolgu bağımsız encoder
Verilen yardımcılarla yığınlı dikkat(a, pad) (anahtar ekseninde maskeli) ve pre-LN encoder_blogu(H, pad) fonksiyonlarını yaz. Aynı 3 kelimelik cümleyi bir kez 3, bir kez 6 uzunluğunda (3 dolgu) ver. Çıktı şekillerini aynı satırda, ardından ilk üç konumun iki durumda aynı olduğunu np.allclose ile yazdır.
Örnek çözümü göster
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)
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
Wq, Wk, Wv = rng.normal(size=(3, d, d)) * 0.4
W1, W2 = rng.normal(size=(d, 4 * d)) * 0.3, rng.normal(size=(4 * d, d)) * 0.3
ffn = lambda a: np.maximum(0, a @ W1) @ W2
gercek = rng.normal(size=(1, 3, d))
H3, pad3 = gercek, np.zeros((1, 3), dtype=bool)
H6 = np.concatenate([gercek, rng.normal(size=(1, 3, d))], axis=1)
pad6 = np.array([[False] * 3 + [True] * 3])
def dikkat(a, pad):
Q, K, V = a @ Wq, a @ Wk, a @ Wv
skor = Q @ K.transpose(0, 2, 1) / np.sqrt(d)
skor = np.where(pad[:, None, :], -1e9, skor)
return softmax(skor) @ V
def encoder_blogu(H, pad):
H = H + dikkat(layer_norm(H), pad)
return H + ffn(layer_norm(H))
Y3, Y6 = encoder_blogu(H3, pad3), encoder_blogu(H6, pad6)
print(Y3.shape, Y6.shape)
print(np.allclose(Y3[0], Y6[0, :3]))
Uygulama Model boyutu hesaplayıcı
Bir encoder-only modelin parametre sayısını veren boyut(V, n_max, d, L, f) fonksiyonunu yaz: kelime + konum gömmesi, L katman (dikkat 4·(d²+d), FFN d·f+f+f·d+d, 2 LayerNorm 4d) ve son LayerNorm (2d). BERT-base'e yakın (30522, 512, 768, 12, 3072) ve küçük bir model (8000, 128, 256, 4, 1024) için sayıları aynı satırda yazdır. Ardından küçük modelde FFN boyutu 4d yerine 2d yapılınca parametrelerin kaçta kaçının kaldığını round(..., 3) ile yazdır.
Örnek çözümü göster
def boyut(V, n_max, d, L, f):
gomme = (V + n_max) * d
katman = 4 * (d * d + d) + (d * f + f + f * d + d) + 4 * d
return gomme + L * katman + 2 * d
print(boyut(30522, 512, 768, 12, 3072), boyut(8000, 128, 256, 4, 1024))
print(round(boyut(8000, 128, 256, 4, 512) / boyut(8000, 128, 256, 4, 1024), 3))
Kendini test et
-
Pre-LN ile post-LN arasındaki fark nedir?
- Pre-LN hiç normalleştirmez
- Post-LN maske kullanmaz
- Hiçbir fark yoktur
- Pre-LN normalleştirmeyi alt katmandan önce, artık yolunun dışında yapar
Cevabı göster
Pre-LN normalleştirmeyi alt katmandan önce, artık yolunun dışında yapar — Pre-LN'de artık yol (H + ...) normalleştirilmeden akar; derin ağlarda daha kararlıdır.
-
Pre-LN artık bağlantısını yaz.
H = H + dikkat(____(H), pad)
Cevabı göster
H = H + dikkat(layer_norm(H), pad)
-
Eşleştir.
- post-LN
- LN(H + f(H))
- pre-LN
- H + f(LN(H))
- dolgu maskesi
- Anahtar sütunlarını kapatır
- dolgu bağımsızlığı
- Gerçek çıktı değişmez
Sıradaki ders: Meydan okuma 3