Ders 15 / 24
Dikkat Mekanizması
Dizinin uzak bir adımına doğrudan bakmanın ne kazandırdığının ve okunan ağırlıkların ne kadarının açıklama olduğunun ölçülmesi: en sık sınıf tabanı 0,6333 iken aynı dikkat ağının iki koşumu ayrılmış kümede 0,8889 ve 0,9944 veriyor, aradaki 0,1056 yalnız ilklendirme tohumundan geliyor; birinci koşum işaret adımına ağırlığın yalnız 0,2721'ini gönderip en büyük ağırlığı örneklerin 0,3444'ünde doğru adıma koyarken 0,8889 doğruluk üretiyor, ikinci koşum ise 0,9691 ve 1,0000 veriyor. Adım çıkarma sınamasında ağırlık ile etkinin uyumu birinci koşumda 0,5889'da kalıyor ve ağırlığı 0,5'i aşan 180 örneğin 43'ünde o adımın çıkarılması tahmini 0,05'ten az oynatıyor.
İçindekiler
Kapı birimleri bir soruyu çözdü. Yinelemeli bir ağda uzak bir adımdan gelen bilginin yolda silinmesi engellendi ve taşınabilen bağımlılık uzunluğu ölçüldü. Çözümün biçimi ise değişmedi: bilgi hâlâ adım adım ilerliyor, her adımda tek bir gizli duruma yazılıyor ve dizinin sonunda o tek durumdan okunuyordu. Kapı, durumun içine neyin gireceğini düzenledi; durumun kendisini çoğaltmadı.
Bu dersin sorusu bir adım geridedir. Dizinin uzak bir adımına doğrudan bakmak ne kazandırır — çıktı bütün adımları aynı anda görüp hangisine ne kadar ağırlık vereceğini kendisi seçebilseydi hangi sayı oynardı. İkinci soru birincinin hemen ardından gelir ve bu dersin asıl ölçüsüdür: seçilen ağırlıklar okunduğunda ağın niçin o cevabı verdiği anlaşılır mı.
- MI46. Dizi kurgusu bu derste yeniden kurulur ve kurgudur: abone başına on iki adımlık
sayaç okuma dizisi, tohum 20260218, 720 dizi, bölme 360/180/180.
mimariler/04’ün dizisinde işaret hep ilk dönemdeydi; ağırlıkların doğru adıma düşüp düşmediği ancak işaretin yeri diziden diziye değiştiğinde ölçülebilir, bu yüzden kurgu bu ölçüye göre kurulur. - MI47. Okumalar, abonenin kendi düzeyi ve dönemsel bileşeni çıkarıldıktan sonra kalan sapma olarak yazılmıştır. Adım 0 her abonede aynı kalibrasyon okumasıdır ve değeri 0,0’dır.
- MI48. Her dizide bir işaret adımı vardır; ikinci ile on birinci adım arasında bulunur. Etiket yalnız o adımın okumasının 0,35’i aşıp aşmadığına bağlıdır. Öbür on bir adım etikete hiç girmez.
- MI49. Girdi adım başına iki kanaldır: okuma ve işaret göstergesi. Ağ hangi adımın işaretli olduğunu görür, etiketi görmez.
- MI50. Taban çizgisi en sık sınıftır: her diziye çoğunluk etiketini vermek. M27/K01–K03’ün tablo tabanı 0,7579 başka bir görevin sayısıdır ve buraya taşınmaz.
- MI51. Dikkat katmanı ders içinde yazılır ve modeldir. Sorgu tek ve öğrenilir; anahtar ile değer doğrusal izdüşümle üretilir; ağırlıklar yumuşak enbüyükle normalleştirilir.
- MI52. Eğitim tam toplu eğim inişidir: 200 tur, öğrenme adımı 0,6. Eğim inişi yordamı M27/K03
dogrusal-modellerkonusunda kuruldu ve tekrarlanmaz. - MI53. Her sayı iki koşumla basılır ve koşumlar yalnız ilklendirme tohumunda ayrılır. Bu kursun üçüncü sayısı budur.
- MI54. Nedensellik ölçüsü adım çıkarmadır: bir adım dikkat dağılımından düşürülür, kalan ağırlıklar yeniden normalleştirilir ve çıktı olasılığının ne kadar oynadığı basılır.
Dizi Kurgusu ve Tabanı
Görev kasten dar seçilmiştir. Etiketi belirleyen tek bir adım vardır ve o adım işaretlidir; ağın yapması gereken tek şey işaretli adımı bulup okumasını eşikle karşılaştırmaktır. Böyle bir görevde “doğru adıma mı baktı” sorusunun kesin bir cevabı olur, çünkü doğru adım veriyi üreten kurguda yazılıdır.
# ORTAK — MODELDIR. KURGU dizi kumesi: abone basina 12 adimlik sayac okuma dizisi. import math TOHUM, M32, ADIM = 20260218, 0xFFFFFFFF, 12 BOLGE = [("kuzey", 0.28, 21), ("guney", 0.22, 17), ("dogu", 0.18, 26), ("bati", 0.14, 14), ("merkez", 0.18, 23)] def uretec(t): x = ((t ^ (t >> 16)) * 2246822507) & M32 x = ((x ^ (x >> 13)) * 3266489909) & M32 s = [(x ^ (x >> 16)) & M32] def sonraki(): s[0] = (s[0] * 1664525 + 1013904223) & M32 return s[0] / 4294967296 return sonraki def ayrik(u, w): t = 0.0 for i, x in enumerate(w): t += x if u < t: return i return len(w) - 1 def dizi_kur(n, tohum): D = [] for i in range(n): r = uretec(tohum + i) b = BOLGE[ayrik(r(), [x[1] for x in BOLGE])] oku = [0.0] + [round((r() + r() + r() - 1.5) * 1.9, 3) for _ in range(ADIM - 1)] m = 2 + int(r() * (ADIM - 2)) D.append({"oku": oku, "isaret": m, "y": 1 if oku[m] > 0.35 else 0, "bolge": b[0]}) return D VERI = dizi_kur(720, TOHUM) EGT, DOG, SIN = VERI[:360], VERI[360:540], VERI[540:] oran = sum(x["y"] for x in SIN) / len(SIN) TABAN = max(oran, 1 - oran) print(f"dizi {len(VERI)}, uzunluk {ADIM}, bolme {len(EGT)}/{len(DOG)}/{len(SIN)}") print(f"pozitif oran egitim {sum(x['y'] for x in EGT) / len(EGT):.4f}, " f"ayrilmis {oran:.4f}") print(f"taban cizgisi (en sik sinif) {TABAN:.4f}") print(f"esigi asan adimi olan dizi orani " f"{sum(any(x['oku'][t] > 0.35 for t in range(2, ADIM)) for x in VERI) / len(VERI):.4f}") print(f"en buyuk okuma isaret adimina dusuyor mu " f"{sum(max(range(2, ADIM), key=lambda t: x['oku'][t]) == x['isaret'] for x in SIN) / len(SIN):.4f}")
dizi 720, uzunluk 12, bolme 360/180/180 pozitif oran egitim 0.3806, ayrilmis 0.3667 taban cizgisi (en sik sinif) 0.6333 esigi asan adimi olan dizi orani 0.9903 en buyuk okuma isaret adimina dusuyor mu 0.0611
Son iki satır görevin gerçekten dizinin içine bakmayı gerektirdiğini gösterir. Dizilerin 0,9903’ünde eşiği aşan en az bir adım vardır, yani “herhangi bir yerde yüksek okuma var mı” sorusu neredeyse her dizide evet der ve hiçbir şey ayırt etmez. En büyük okumaya bakmak da işe yaramaz: dizinin en yüksek adımı ile işaret adımı ayrılmış kümenin yalnız 0,0611’inde çakışır. Ağın seçmesi gereken adım ne en büyüktür ne de sabit bir yerdedir.
Taban çizgisi 0,6333’tür. Ayrılmış kümedeki pozitif oran 0,3667 olduğu için her diziye olumsuz etiketi vermek bu sayıyı verir. Bu, öğrenmeyen en yalın yordamdır ve bundan sonraki her sayı onunla yan yana okunur.
Sorgu, Anahtar ve Değer
Dikkat üç izdüşümle tanımlanır. Her adım kendi girdisinden bir anahtar ve bir değer üretir; çıktıyı üretecek taraf bir sorgu taşır. Sorgu ile anahtarın iç çarpımı o adımın ne kadar ilgili olduğunu veren bir puandır, puanlar yumuşak enbüyükten geçirilerek toplamı bire eşit ağırlıklara çevrilir ve çıktı, değerlerin bu ağırlıklarla ortalamasıdır. İç çarpım anahtar boyutunun kareköküne bölünür; ile bölme, boyut büyüdükçe puanların da büyüyüp yumuşak enbüyüğü doyurmasını engeller.
Sınıflandırmada sorgunun bir adımdan gelmesi gerekmez; tek bir öğrenilen sorgu yeterlidir. Ağ “hangi adım bu karar için önemli” sorusunu bir kez sorar ve dizinin tamamından tek bir özet alır. Gizli durum yoktur, yineleme yoktur, adımlar arasında sıra bağı yoktur.
DK = DV = 3 OL = 1.0 / math.sqrt(DK) GIR = [([[x["oku"][t], 1.0 if t == x["isaret"] else 0.0] for t in range(ADIM)], x["y"], x["isaret"]) for x in VERI] EG, SG = GIR[:360], GIR[540:] def ileri(P, X, atla=None): K = [[P["Wk"][i][0] * x[0] + P["Wk"][i][1] * x[1] for i in range(DK)] for x in X] V = [[P["Wv"][i][0] * x[0] + P["Wv"][i][1] * x[1] for i in range(DV)] for x in X] s = [sum(P["q"][i] * k[i] for i in range(DK)) * OL for k in K] d = [t for t in range(ADIM) if t != atla] mx = max(s[t] for t in d) e = [math.exp(s[t] - mx) if t in d else 0.0 for t in range(ADIM)] z = sum(e) a = [u / z for u in e] c = [sum(a[t] * V[t][i] for t in d) for i in range(DV)] return K, V, a, c, sum(P["w"][i] * c[i] for i in range(DV)) + P["b"] def egit(tohum, tur=200, adim=0.6): r = uretec(tohum) g = lambda: (r() + r() + r() - 1.5) * 0.9 P = {"Wk": [[g(), g()] for _ in range(DK)], "Wv": [[g(), g()] for _ in range(DV)], "q": [g() for _ in range(DK)], "w": [g() for _ in range(DV)], "b": 0.0} for _ in range(tur): gWk = [[0.0, 0.0] for _ in range(DK)] gWv = [[0.0, 0.0] for _ in range(DV)] gq, gw, gb = [0.0] * DK, [0.0] * DV, 0.0 for X, y, _m in EG: K, V, a, c, o = ileri(P, X) d = 1.0 / (1.0 + math.exp(-max(-30.0, min(30.0, o)))) - y for i in range(DV): gw[i] += d * c[i] gb += d da = [sum(d * P["w"][i] * V[t][i] for i in range(DV)) for t in range(ADIM)] orta = sum(a[t] * da[t] for t in range(ADIM)) for t in range(ADIM): ds = a[t] * (da[t] - orta) * OL for i in range(DK): gq[i] += ds * K[t][i] gWk[i][0] += ds * P["q"][i] * X[t][0] gWk[i][1] += ds * P["q"][i] * X[t][1] for i in range(DV): gWv[i][0] += d * a[t] * P["w"][i] * X[t][0] gWv[i][1] += d * a[t] * P["w"][i] * X[t][1] n = len(EG) for i in range(DK): P["q"][i] -= adim * gq[i] / n P["Wk"][i][0] -= adim * gWk[i][0] / n P["Wk"][i][1] -= adim * gWk[i][1] / n for i in range(DV): P["w"][i] -= adim * gw[i] / n P["Wv"][i][0] -= adim * gWv[i][0] / n P["Wv"][i][1] -= adim * gWv[i][1] / n P["b"] -= adim * gb / n return P def dogruluk(P, G): return sum((ileri(P, X)[4] > 0) == (y == 1) for X, y, _ in G) / len(G) AG = [egit(TOHUM + 1), egit(TOHUM + 2)] print(f"parametre sayisi {DK * 2 + DV * 2 + DK + DV + 1}, tur 200, " f"egitim ornegi {len(EG)}") print(f"taban cizgisi (en sik sinif) {TABAN:.4f}") for i, P in enumerate(AG): print(f"dikkat agi kosum {i + 1} egitim {dogruluk(P, EG):.4f} " f"ayrilmis {dogruluk(P, SG):.4f}") print(f"iki kosum arasindaki fark {abs(dogruluk(AG[0], SG) - dogruluk(AG[1], SG)):.4f}")
parametre sayisi 19, tur 200, egitim ornegi 360 taban cizgisi (en sik sinif) 0.6333 dikkat agi kosum 1 egitim 0.9028 ayrilmis 0.8889 dikkat agi kosum 2 egitim 0.9889 ayrilmis 0.9944 iki kosum arasindaki fark 0.1056
Üç sayı tablodadır. Taban 0,6333; dikkat ağı ayrılmış kümede 0,8889 ve 0,9944. On dokuz parametre uzunluğu on iki olan bir dizide doğru adımı bulmayı öğrenmekte ve tabanın en az 0,2556 üstüne çıkmaktadır. Aynı işi yinelemeli bir ağ ancak on iki adım boyunca durum taşıyarak yapabilirdi.
Üçüncü sayı ikinciden daha çok şey söyler. İki koşum aynı kapasiteyi, aynı veriyi ve aynı tur bütçesini paylaşır; yalnız ilklendirme tohumları ayrıdır. Aradaki fark 0,1056’dır — bu ağın ayrılmış küme sayısının yaklaşık dokuzda biri, ağın ne olduğundan değil, o koşumda nereden başladığından gelmektedir. Kursun kuralı burada doğrudan okunur: bir ağın sayısı kapasitesinden değil eğitiminden gelebilir.
Ağırlıklar Nereye Düşüyor
Dikkatin ürettiği ağırlık vektörü ağın içindeki tek okunabilir ara üründür: her adım için bir sayı verir ve toplamları bire eşittir. Bu okunabilirlik, ağırlıkların sık sık “modelin neye baktığı” diye sunulmasının nedenidir. Kurgu bu iddiayı sınamaya elverişlidir, çünkü doğru adım bilinmektedir.
def dikkat_olcu(P, G): kutle, isabet = 0.0, 0 for X, _y, m in G: a = ileri(P, X)[2] kutle += a[m] isabet += max(range(ADIM), key=lambda t: a[t]) == m return kutle / len(G), isabet / len(G) print(f"tekduze dagilimda bir adimin agirligi {1 / ADIM:.4f}") print(f"{'':16}{'isaret adimina dusen':>21}{'en buyuk agirlik':>18}{'ayrilmis':>10}") for i, P in enumerate(AG): k, s = dikkat_olcu(P, SG) print(f"kosum {i + 1:<10}{k:>21.4f}{s:>18.4f}{dogruluk(P, SG):>10.4f}") X0, _y0, m0 = SG[0] a0 = ileri(AG[0], X0)[2] a1 = ileri(AG[1], X0)[2] print(f"tek ornek, isaret adimi {m0}") print("kosum 1 agirliklari " + " ".join(f"{u:.2f}" for u in a0)) print("kosum 2 agirliklari " + " ".join(f"{u:.2f}" for u in a1))
tekduze dagilimda bir adimin agirligi 0.0833
isaret adimina dusen en buyuk agirlik ayrilmis
kosum 1 0.2721 0.3444 0.8889
kosum 2 0.9691 1.0000 0.9944
tek ornek, isaret adimi 11
kosum 1 agirliklari 0.00 0.00 0.10 0.00 0.01 0.01 0.00 0.29 0.31 0.00 0.10 0.18
kosum 2 agirliklari 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.97
İkinci koşum beklenen davranışı gösterir: ağırlığın 0,9691’i işaret adımına düşer ve en büyük ağırlık ayrılmış kümenin tamamında doğru adımdadır. Tekdüze bir dağılımda bir adımın payı 0,0833 olduğuna göre bu, tabanın on bir katından fazlasıdır.
Birinci koşum aynı görevi 0,8889 doğrulukla çözer, ama ağırlığın yalnız 0,2721’ini işaret adımına gönderir ve en büyük ağırlığı örneklerin 0,3444’ünde doğru adıma koyar. Tek örnek satırı bunun nasıl mümkün olduğunu gösterir: işaret adımı on birinci adımdır, koşum 1 oraya 0,18 verir ve kalanı yedinci ile sekizinci adımlara dağıtır. Ağ, işaret kanalını kısmen kullanıp geri kalan ağırlığı okuması yüksek adımlara yayan bir uzlaşma bulmuştur ve bu uzlaşma vakaların çoğunda doğru cevabı üretmektedir. Doğruluk 0,8889 iken ağırlıkların doğru adıma isabeti 0,3444’tür; iki sayı arasında hiçbir zorunlu bağ yoktur.
Yüksek Ağırlık Nedensellik Değildir
Bir ağırlığın büyük olması, o adımın çıktıyı belirlediği anlamına gelmez. İkisinin aynı şey olup olmadığı ancak bir müdahaleyle sınanabilir: adım dikkat dağılımından düşürülür, kalan ağırlıklar yeniden normalleştirilir ve çıktı olasılığının ne kadar oynadığına bakılır. Bu, ağırlığın büyüklüğünden bağımsız bir ölçüdür.
def olasilik(P, X, atla=None): o = ileri(P, X, atla)[4] return 1.0 / (1.0 + math.exp(-max(-30.0, min(30.0, o)))) def nedensellik(P, G, esik=0.05): uyum, yuksek, yuksek_etkisiz, orta_etki = 0, 0, 0, 0.0 for X, _y, _m in G: a = ileri(P, X)[2] p0 = olasilik(P, X) etki = [abs(olasilik(P, X, t) - p0) for t in range(ADIM)] ta = max(range(ADIM), key=lambda t: a[t]) uyum += ta == max(range(ADIM), key=lambda t: etki[t]) orta_etki += etki[ta] if a[ta] > 0.5: yuksek += 1 yuksek_etkisiz += etki[ta] < esik n = len(G) return uyum / n, orta_etki / n, yuksek, yuksek_etkisiz print(f"{'':10}{'agirlik-etki uyumu':>19}{'en agir adimin etkisi':>23}" f"{'agirlik>0,5':>13}{'ama etki<0,05':>15}") for i, P in enumerate(AG): u, e, y, ye = nedensellik(P, SG) print(f"kosum {i + 1:<4}{u:>19.4f}{e:>23.4f}{y:>13d}{ye:>15d}")
agirlik-etki uyumu en agir adimin etkisi agirlik>0,5 ama etki<0,05 kosum 1 0.5889 0.3318 81 27 kosum 2 1.0000 0.4081 180 43
Birinci koşumda en ağır adım ile en etkili adım örneklerin yalnız 0,5889’unda aynıdır. Yani ağırlık sıralamasını okuyup “model buraya baktı” diyen biri, on örnekten dördünde ağın çıktısını gerçekte belirleyen adımı kaçırır. İkinci koşumda uyum 1,0000’dır. Aynı mimari, aynı veri, aynı bütçe; ağırlıkların açıklama değeri koşumdan koşuma değişmektedir. Ağırlıklara bakan biri hangi koşumda olduğunu ağırlıklardan anlayamaz — her iki koşum da yoğunlaşmış, düzenli görünen dağılımlar üretir.
Son sütun ikinci koşumun kendi içinde de bir sınır olduğunu gösterir. Ayrılmış kümenin tamamında en büyük ağırlık 0,5’i aşar, ama bu 180 örneğin 43’ünde o adımın çıkarılması tahmin olasılığını 0,05’ten az oynatır. Neden açıktır: dizinin geri kalan adımları da düşük okumalar taşıyorsa, işaret adımı düşürüldüğünde ortalama aynı tarafta kalır ve karar değişmez. Yüksek ağırlık burada “bu adım karara gitti” demek değil, “bu adım okundu” demektir.
Buradan çıkan kural şudur: dikkat ağırlıkları hata ayıklamada işe yarar bir ara üründür, tek başlarına bir gerekçe belgesi değildir. Yanına ya bir çıkarma sınaması ya da koşum değişkenliği yazılmayan ağırlık ölçülmemiş bir sayıdır.
Özet
- Dizi kurgusu bu derste kuruldu ve kurgudur: 720 dizi, uzunluk 12, bölme 360/180/180, tohum 20260218; etiket yalnız işaret adımının okumasına bağlıdır.
- Taban çizgisi en sık sınıftır ve 0,6333’tür; on dokuz parametreli dikkat ağı ayrılmış kümede 0,8889 ve 0,9944 verir, iki koşum arasındaki fark 0,1056’dır.
- Dikkat, sorgu ile anahtarın iç çarpımını ile ölçekleyip yumuşak enbüyükten geçirir ve değerlerin ağırlıklı ortalamasını üretir; gizli durum ve yineleme yoktur.
- Ağırlıkların nereye düştüğü doğrulukla aynı şey değildir: birinci koşum 0,8889 doğrulukla işaret adımına ağırlığın 0,2721’ini gönderir ve en büyük ağırlığı 0,3444 isabetle koyar.
- Adım çıkarma sınamasında ağırlık ile etkinin uyumu birinci koşumda 0,5889’dur ve ikinci koşumda ağırlığı 0,5’i aşan 180 örneğin 43’ünde o adımın çıkarılması tahmini 0,05’ten az oynatır.
Sonraki Adım
Bu derste tek bir sorgu, tek bir ağırlık dağılımı üretti ve dizi tek bir özete indirildi. Kurgunun görevi buna elverişliydi: etiket tek bir adımdan okunuyordu ve adımların sırası hiç işe karışmıyordu. İki soru açık kalıyor. Birincisi, aynı dizide birden çok ilgi kalıbı varsa — biri işaret adımını, öbürü genel düzeyi arıyorsa — tek dağılım ikisini taşıyabilir mi. İkincisi ve daha keskini: dikkat bütün adımlara aynı anda baktığına göre adımların sırasını nereden bilecek. Sonraki ders sorguyu çoğaltır, baş sayısının kattığı farkı ölçer ve konum kodlaması çıkarıldığında sıra bilgisinin ne kadarının kaldığını aynı tabana karşı basar.
İlerlemeni kaydetmek ve not almak için Giriş yap
Notlarım
Not almak için giriş yapmalısın.