CodeBlanks Logo Icon CodeBlanks

Encoder

Encoder, girdiyi attention ve feed-forward katmanlarıyla işler.

Encoder

Encoder, giriş dizisinin tamamını görür ve her konum için bağlama duyarlı bir temsil üretir. Bloğu iki adımdır: öz-dikkat (konumlar bilgi alışverişi yapar) ve FFN (her konum ayrı ayrı dönüştürülür):

def ffn(x, W1, W2):
    return np.maximum(0, x @ W1) @ W2      # d -> 4d -> d

def encoder_blogu(x, Wq, Wk, Wv, W1, W2):
    d = x.shape[-1]
    A = softmax((x @ Wq) @ (x @ Wk).T / np.sqrt(d))
    x = layer_norm(x + A @ (x @ Wv))
    return layer_norm(x + ffn(x, W1, W2))

FFN'in ara boyutu genellikle d_model'in 4 katıdır; parametrelerin çoğu buradadır.

FFN konum başınadır

FFN'i satır satır uygulamakla tüm matrise bir kerede uygulamak aynı sonucu verir; çünkü aynı ağırlıklar her konuma ayrı ayrı uygulanır. Bu yüzden bir konumu değiştirmek FFN çıktısında yalnızca o satırı değiştirir:

y1 = ffn(x, W1, W2)
x2 = x.copy(); x2[0] += 5
y2 = ffn(x2, W1, W2)
print(np.allclose(y1[1:], y2[1:]))     # True: diğer satırlar aynı

Dikkat katmanında ise tek bir konumu değiştirmek tüm çıktıları etkiler.

Uygulama Encoder bloğu

Verilen yardımcılarla encoder_blogu fonksiyonunu tamamla. Çıktının şeklini yazdır. Sonra x'in yalnızca ilk satırını değiştirince FFN çıktısında diğer satırların aynı kaldığını, encoder bloğunun çıktısında ise değiştiğini np.allclose ile aynı satırda 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)

def layer_norm(x, eps=1e-5):
    m = x.mean(axis=-1, keepdims=True)
    v = x.var(axis=-1, keepdims=True)
    return (x - m) / np.sqrt(v + eps)

def ffn(x, W1, W2):
    return np.maximum(0, x @ W1) @ W2

rng = np.random.default_rng(0)
n, d = 4, 8
x = rng.normal(size=(n, d))
Wq, Wk, Wv = rng.normal(size=(3, d, d)) * 0.3
W1 = rng.normal(size=(d, 4 * d)) * 0.3
W2 = rng.normal(size=(4 * d, d)) * 0.3
x2 = x.copy()
x2[0] += 5

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

def layer_norm(x, eps=1e-5):
    m = x.mean(axis=-1, keepdims=True)
    v = x.var(axis=-1, keepdims=True)
    return (x - m) / np.sqrt(v + eps)

def ffn(x, W1, W2):
    return np.maximum(0, x @ W1) @ W2

rng = np.random.default_rng(0)
n, d = 4, 8
x = rng.normal(size=(n, d))
Wq, Wk, Wv = rng.normal(size=(3, d, d)) * 0.3
W1 = rng.normal(size=(d, 4 * d)) * 0.3
W2 = rng.normal(size=(4 * d, d)) * 0.3
x2 = x.copy()
x2[0] += 5

def encoder_blogu(x):
    A = softmax((x @ Wq) @ (x @ Wk).T / np.sqrt(d))
    x = layer_norm(x + A @ (x @ Wv))
    return layer_norm(x + ffn(x, W1, W2))

print(encoder_blogu(x).shape)
print(np.allclose(ffn(x, W1, W2)[1:], ffn(x2, W1, W2)[1:]), np.allclose(encoder_blogu(x)[1:], encoder_blogu(x2)[1:]))

Beklenen çıktı

(4, 8)
True False

Soru ve cevaplar

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

1 Encoder'da FFN konumlar arasında bilgi taşır mı?

  • Hayır, her konuma ayrı ayrı uygulanır Doğru cevap
  • Evet, tüm konumları karıştırır
  • Yalnızca komşu konumları
  • Yalnızca ilk konumu

Açıklama: Konumlar arası karışım yalnızca dikkatte olur.

2 FFN'in ara katmanında ReLU uygula.

Soru
return np.____(0, x @ W1) @ W2
Cevap
return np.maximum(0, x @ W1) @ W2

Açıklama: np.maximum eleman bazında karşılaştırır; np.max tek bir değer döndürür.

3 Etkileri eşleştir.

Kavram Anlamı
x[0] değişir → FFN Yalnızca satır 0 değişir
x[0] değişir → dikkat Tüm satırlar değişir
W1 d → 4d
W2 4d → d

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