Ana içeriğe geç

Orta9 dk

Attention fikri

Önkoşul:Sekans modellerinin sınırı

Kanca

“I did not say he stole the money” — bu 7 kelimelik cümle, HANGİ kelimeye VURGU yaptığınıza göre 7 FARKLI anlama gelir. “Attention” (dikkat) kelimesi tam olarak buradan geliyor: bir çıktı üretirken, girdinin hangi parçalarına ne kadar “dikkat” edileceği.

Aynı cümle, 7 farklı vurgu, 7 farklı anlam

# "Attention" (dikkat) kelimesi, İNSAN dilinden ödünç alınmış bir kavramdır.
# Klasik bir İngilizce örnek: AYNI 7 kelimelik cümle, HANGİ kelimeye VURGU
# yapıldığına göre 7 FARKLI anlama gelir.
cumle = "I did not say he stole the money"
yorumlar = [
    ("I", "Başkası söyledi, BEN söylemedim."),
    ("did not", "Hiçbir şekilde söylemedim -- düz bir inkar."),
    ("say", "Söylemedim ama BAŞKA bir yolla ima ettim."),
    ("he", "Parayı O çalmadı, BAŞKASI çaldı dedim."),
    ("stole", "Parayı BAŞKA bir yolla (örn. ödünç) aldı dedim."),
    ("the", "BU parayı değil, BAŞKA bir parayı çaldı dedim."),
    ("money", "Parayı değil, BAŞKA bir şeyi çaldı dedim."),
]
print(f'Cümle: "{cumle}"\n')
for kelime, anlam in yorumlar:
    print(f'  VURGU "{kelime}"de olursa -> {anlam}')
print("\n7 kelime, 7 FARKLI anlam -- SADECE hangi kelimeye 'dikkat' ettiğine göre.")
print("ML'deki attention da AYNI fikri matematikselleştiriyor: bir çıktı üretirken,")
print("GİRDİNİN hangi kısımlarına ne kadar 'dikkat' edileceğini ÖĞRENİYOR.")
Cümle: "I did not say he stole the money"

  VURGU "I"de olursa -> Başkası söyledi, BEN söylemedim.
  VURGU "did not"de olursa -> Hiçbir şekilde söylemedim -- düz bir inkar.
  VURGU "say"de olursa -> Söylemedim ama BAŞKA bir yolla ima ettim.
  VURGU "he"de olursa -> Parayı O çalmadı, BAŞKASI çaldı dedim.
  VURGU "stole"de olursa -> Parayı BAŞKA bir yolla (örn. ödünç) aldı dedim.
  VURGU "the"de olursa -> BU parayı değil, BAŞKA bir parayı çaldı dedim.
  VURGU "money"de olursa -> Parayı değil, BAŞKA bir şeyi çaldı dedim.

7 kelime, 7 FARKLI anlam -- SADECE hangi kelimeye 'dikkat' ettiğine göre.
ML'deki attention da AYNI fikri matematikselleştiriyor: bir çıktı üretirken,
GİRDİNİN hangi kısımlarına ne kadar 'dikkat' edileceğini ÖĞRENİYOR.

Sezgi

8. derste gördük: RNN/LSTM tüm diziyi SABİT boyutlu tek bir vektöre sıkıştırmak zorunda — bu bir darboğaz. Attention’ın İLK fikri basit: sıkıştırma YERİNE, her kelimenin durumunu AYRI AYRI SAKLA, sonra ihtiyaca göre bunların arasından SEÇ.

Tek vektör yerine, tüm durumları sakla

# 8. derste RNN'in TÜM diziyi tek bir vektöre sıkıştırdığını gördük. Attention'ın
# İLK fikri basit: sıkıştırma YERİNE, TÜM ara durumları SAKLA.
KELIMELER = ["kral", "ülkeyi", "adaletle", "yönetti"]
BOYUT = 3
# Her kelimenin "hafızası" (gerçekte bir RNN/embedding'den gelir, burada öğretici
# amaçlı elle tasarlanmış):
encoder_durumlari = torch.tensor([
    [1.6, 0.6, 0.0],   # kral
    [1.1, 1.1, 0.0],   # ülkeyi (kral'a KISMEN benzer -- konuyla ilgili)
    [0.0, 0.0, 1.6],   # adaletle (FARKLI bir "eksende")
    [-0.6, 0.3, 0.6],  # yönetti
])
print(f"\n{len(KELIMELER)} kelimenin HER BİRİNİN gizli durumu SAKLANDI -- 8. dersteki gibi TEK bir vektöre indirgenmedi.")
print(f"Saklanan veri şekli: {tuple(encoder_durumlari.shape)} (kelime sayısı × boyut)")

4 kelimenin HER BİRİNİN gizli durumu SAKLANDI -- 8. dersteki gibi TEK bir vektöre indirgenmedi.
Saklanan veri şekli: (4, 3) (kelime sayısı × boyut)

“Seçmek” kelimesi burada yanıltıcı — attention aslında tek bir kelimeyi SEÇMEZ, HER kelimeye bir AĞIRLIK verir (0 ile 1 arası, toplamları 1) ve AĞIRLIKLI ORTALAMASINI alır. İlgisiz kelimeler ~0 ağırlık, ilgili kelimeler yüksek ağırlık alır.

Mekanizma

“kral ülkeyi adaletle yönetti” cümlesinde, “kral”a YAKIN bir sorgu (query) ile her kelimenin durumu arasındaki BENZERLİĞİ (nokta çarpım) hesaplayıp softmax’tan geçirelim:

Sorgu ile her kelime arasındaki benzerlik -> ağırlık

# Şimdi bir "sorgu" (query) -- örn. "özne kim?" sorusuna en yakın bir vektör --
# ile HER encoder durumu arasındaki BENZERLİĞİ (nokta çarpım) hesaplayalım.
sorgu = torch.tensor([1.7, 0.5, 0.1])  # "kral"a YAKIN bir sorgu

puanlar = encoder_durumlari @ sorgu
agirliklar = F.softmax(puanlar, dim=0)

print(f"\nDikkat puanları (ham nokta çarpım): {[round(v,3) for v in puanlar.tolist()]}")
print(f"Dikkat ağırlıkları (softmax sonrası): {[round(v,3) for v in agirliklar.tolist()]}")
print(f"Ağırlıkların toplamı: {agirliklar.sum().item():.4f}")
for k, a in zip(KELIMELER, agirliklar.tolist()):
    print(f"  {k:<10} ağırlık={a:.3f}")
print(f"\nEn yüksek ağırlık '{KELIMELER[agirliklar.argmax().item()]}'de -- sorgu, ona en YAKIN.")
print("'ülkeyi' de ANLAMLI bir ağırlık (0.337) alıyor -- konuyla İLGİLİ olduğu için.")

Dikkat puanları (ham nokta çarpım): [3.02, 2.42, 0.16, -0.81]
Dikkat ağırlıkları (softmax sonrası): [0.614, 0.337, 0.035, 0.013]
Ağırlıkların toplamı: 1.0000
  kral       ağırlık=0.614
  ülkeyi     ağırlık=0.337
  adaletle   ağırlık=0.035
  yönetti    ağırlık=0.013

En yüksek ağırlık 'kral'de -- sorgu, ona en YAKIN.
'ülkeyi' de ANLAMLI bir ağırlık (0.337) alıyor -- konuyla İLGİLİ olduğu için.

“kral” en yüksek ağırlığı (0.614) alıyor çünkü sorguya en yakın. Ama “ülkeyi” de ANLAMSIZ değil — 0.337 gibi ANLAMLI bir ağırlık alıyor çünkü konuyla İLGİLİ. “adaletle” ve “yönetti” ise neredeyse göz ardı ediliyor (0.035, 0.013).

Matematik

Dikkat puanı ve ağırlığı
puani=qki\text{puan}_i = q \cdot k_iai=softmax(puan)i=epuanijepuanja_i = \text{softmax}(\text{puan})_i = \frac{e^{\text{puan}_i}}{\sum_j e^{\text{puan}_j}}
SembolAnlamı
qqSorgu (query) — “neyi arıyorum?” vektörü
kik_iii. kelimenin durumu (encoder çıktısı)
puani\text{puan}_iqq ile kik_i arasındaki HAM benzerlik (nokta çarpım)
aia_iii. kelimenin NİHAİ dikkat ağırlığı (softmax sonrası, iai=1\sum_i a_i = 1)

Nokta çarpım, [Ek: Matematik Temelleri] bölümündeki “benzerliğin matematiği” dersiyle AYNI fikir — iki vektör ne kadar AYNI YÖNE bakıyorsa, çarpımları o kadar BÜYÜK.

Kod

Bu ağırlıklar, encoder durumlarının AĞIRLIKLI ORTALAMASINI almak için kullanılır — buna “bağlam vektörü” (context vector) denir:

Ağırlıklı ortalama: bağlam vektörü

# Dikkat ağırlıkları, encoder durumlarının AĞIRLIKLI ORTALAMASINI almak için kullanılır --
# buna "bağlam vektörü" (context vector) denir.
baglam_vektoru = agirliklar @ encoder_durumlari
print(f"\nBağlam vektörü: {[round(v,3) for v in baglam_vektoru.tolist()]}")
print("Bu vektör, 'kral' durumuna ÇOK yakın ama 'ülkeyi'den de BİRAZ etkilenmiş --")
print("TEK bir kelimeyi SEÇMEK yerine, İLGİLİ kelimelerin bir KARIŞIMINI oluşturuyor.")
print("\nBu, 8. dersteki 'tek vektöre sıkıştırma' sorununa cevap: artık TEK bir sabit vektör yok --")
print("her adımda, İHTİYACA göre YENİDEN hesaplanan, dinamik bir bağlam vektörü var.")

Bağlam vektörü: [1.346, 0.743, 0.064]
Bu vektör, 'kral' durumuna ÇOK yakın ama 'ülkeyi'den de BİRAZ etkilenmiş --
TEK bir kelimeyi SEÇMEK yerine, İLGİLİ kelimelerin bir KARIŞIMINI oluşturuyor.

Bu, 8. dersteki 'tek vektöre sıkıştırma' sorununa cevap: artık TEK bir sabit vektör yok --
her adımda, İHTİYACA göre YENİDEN hesaplanan, dinamik bir bağlam vektörü var.

Bu vektör “kral” durumuna ÇOK yakın ama “ülkeyi”den de BİRAZ etkilenmiş — 8. dersteki “tek sabit vektör” sorununa cevap: artık her adımda İHTİYACA göre YENİDEN hesaplanan, DİNAMİK bir bağlam vektörü var.

Nerede işe yarar

Bu basit fikir, Bahdanau (2014) ve Luong (2015) makine çevirisi makaleleriyle NLP’ye girdi ve 2017’de “Attention is All You Need” (18. ders) ile merkeze taşındı:

  • Sorgu (query), anahtar (key) ve değer (value) burada henüz AYRI vektörler değil — bu ayrım, 10. dersin (“Self-attention mekaniği: Q, K, V”) konusu. Burada sadece FİKRİ görüyoruz.
  • Ağırlıklar burada ELLE tasarlandı — gerçek bir modelde, sorgu/anahtar vektörleri EĞİTİM sırasında ÖĞRENİLİR, böylece model hangi kelimelere ne zaman dikkat edeceğini kendisi keşfeder.
  • Bu mekanizma, RNN’in İÇİNE eklenmiş bir “yama” olarak başladı (encoder-decoder attention) — 2017’de RNN’i TAMAMEN attention ile değiştirme fikri (self-attention) geldi.

Bu 2 hatayı yaparsın:

  1. Dikkat ağırlıklarının bir kelimeyi “seçtiğini” düşünmek — aslında HEPSİNİN ağırlıklı bir KARIŞIMINI alır, tek bir seçim yapmaz.
  2. Bu örnekteki sorgu/anahtar vektörlerinin ELLE tasarlandığını unutup, gerçek modellerde de “biri bunları yazdı” sanmak — hayır, EĞİTİMLE öğrenilirler.

Kendini test et

1. Attention mekanizması, 8. dersteki 'tek vektöre sıkıştırma' sorununu NASIL çözüyor?
  1. Vektörün boyutunu büyüterek
  2. Tüm ara durumları AYRI AYRI saklayıp, her adımda bunların AĞIRLIKLI ORTALAMASINI (ihtiyaca göre değişen) alarak -- tek bir SABİT vektöre güvenmek yerine (doğru cevap)
  3. Diziyi kısaltarak
  4. RNN katman sayısını artırarak

Neden: Notebook'ta encoder_durumlari (4, 3) şeklinde TÜM kelimelerin durumunu saklıyor; her sorgu için bağlam vektörü bu durumların ağırlıklı ortalamasıyla YENİDEN hesaplanıyor -- sabit tek vektör yok.

2. Notebook'taki örnekte 'kral' 0.614, 'ülkeyi' 0.337, 'adaletle' 0.035, 'yönetti' 0.013 ağırlık alıyor. Bu ne anlama gelir?
  1. Model sadece "kral" kelimesini kullanıyor, diğerlerini siliyor
  2. Sorgu 'kral'a en yakın olduğu için en yüksek ağırlığı o alıyor, ama 'ülkeyi' de konuyla İLGİLİ olduğu için ANLAMLI bir ağırlık alıyor -- bağlam vektörü ikisinin de karışımı (doğru cevap)
  3. Ağırlıklar rastgele atanmıştır
  4. 'adaletle' ve 'yönetti' kelimeleri cümleden çıkarılmalıdır

Neden: Softmax sonrası ağırlıklar TOPLAMI 1 olan bir olasılık dağılımı oluşturur; yüksek ağırlık "en çok dikkat edilen" anlamına gelir, sıfırlama değil -- bağlam vektörü baglam-vektoru bloğunda görüldüğü gibi TÜM kelimelerin ağırlıklı toplamıdır.

3. Bu derste sorgu (query) ve anahtar (key) vektörleri NASIL elde edildi, gerçek bir Transformer'da bu NASIL değişir?
  1. Aynı şekilde, elle tasarlanır
  2. Burada ÖĞRETİCİ amaçlı ELLE tasarlandı; gerçek bir modelde bu vektörler EĞİTİM sırasında öğrenilen ağırlık matrisleriyle (Q, K, V projeksiyonları) hesaplanır -- bu da 10. dersin konusu (doğru cevap)
  3. Gerçek modellerde de elle yazılır, bu yüzden aynı
  4. Sadece büyük modellerde öğrenilir, küçük modellerde elle yazılır

Neden: Kullanım bölümünde vurgulandığı gibi, buradaki encoder_durumlari ve sorgu vektörleri öğretici amaçlı elle seçildi; 10. ders ('Self-attention mekaniği: Q, K, V') bunların EĞİTİLEBİLİR ağırlık matrisleriyle nasıl üretildiğini gösterecek.

Özet

Özet

  • Attention fikri, "aynı cümle vurguya göre farklı anlama gelir" sezgisini matematikselleştirir.
  • Tüm ara durumları TEK bir vektöre sıkıştırmak yerine AYRI AYRI saklamak, 8. dersteki darboğazı çözer.
  • Dikkat ağırlıkları = sorgu ile her durum arasındaki benzerliğin (nokta çarpım) softmax'ı; toplamları her zaman 1.
  • Bağlam vektörü, bu ağırlıklarla alınan AĞIRLIKLI ORTALAMA -- her adımda İHTİYACA göre yeniden hesaplanır.
  • Burada sorgu/anahtar vektörleri elle tasarlandı -- 10. derste bunların EĞİTİMLE nasıl öğrenildiğini (Q, K, V) göreceğiz.
Sonraki adım: Self-attention mekaniği (Q, K, V) →