İçeriğe geç
academia.sh

Ders 04 / 24

Kayıp Fonksiyonları

Kayıp seçiminin ağın gördüğü eğimi ve ulaştığı sayıyı nasıl oynattığının ölçülmesi: ağ 0,99 diyip gerçek etiket 0 olduğunda çapraz düzensizliğin çıkış katmanına verdiği eğim 0,9900, kare hatanınki 0,0196 — oran 50,5. Aynı ağ iki kayıpla dört adayda eğitildiğinde doğrulama kare hatayı ve 25 turu seçiyor; o adayın sınama sayısı 0,7619, ikinci koşumu 0,7897, aradaki fark yedi abone. Kayıp seçiminin kattığı ise üç abone. Eğitim kaybı 0,4861'den 0,3279'a hep düşerken ve eğitim doğruluğu 0,78'den 0,86'ya çıkarken sınama doğruluğu 50. turda 0,7937 ile tepe yapıp 0,7817'ye iniyor; aynı koşumda yakalanan şüpheli 1'den 25'e çıkıyor.

İçindekiler

Üç derste ağın çıktısı hep bir olasılık oldu ve o olasılık hep aynı biçimde hedefle karşılaştırıldı: fark alınıp geriye verildi. Bu karşılaştırma bir seçimdir. Geriye verilen sayı kayıp fonksiyonunun çıkış katmanına göre eğimidir ve kayıp değişince o sayı da değişir.

Kayıp iki ayrı işi birden yapar: eğitim sırasında ağın hangi yöne gideceğini söyler, eğitim bittiğinde ise başarımı bildiren sayı olarak okunmaya çalışılır. İkincisi için tasarlanmamıştır ve dersin ikinci ölçüsü bunu gösterir.

  • SA22. Küme, bölme, tohum, on iki sütun ve 300 satıra küçültülmüş eğitim kümesi 0103’teki gibidir; ağ 12–8–1, 113 parametre. Taban çizgisi sınama kümesinde 0,7579.
  • SA23. Sınıflandırma kayıpları çapraz düzensizlik ve kare hatadır. İkisi de aynı sigmoit çıktısı üzerinden hesaplanır; değişen yalnız çıkış katmanına verilen eğimdir.
  • SA24. Çapraz düzensizliğin çıkış eğimi aya-y’dir; sigmoidin türevi kaybın türeviyle sadeleşir. Kare hatanın eğimi 2(ay)a(1a)2(a-y)\,a(1-a)’dır ve sigmoidin türevini taşımayı sürdürür.
  • SA25. Çapraz düzensizlikte olasılık taşma koruması için 101210^{-12} ile alttan sınırlanır. Sınır sayıyı etkilemez, çünkü ağın ürettiği hiçbir olasılık o değere yaklaşmıyor.
  • SA26. Bağlanım kayıpları bu derste eğitilmez, yalnız eğim davranışı hesapla gösterilir. M27/K03 model-degerlendirme/05 iki uydurmayı ölçtü: açıklanan değişim 0,4770 ile 0,4751.
  • SA27. Denenen aday sayısı 4’tür: iki kayıp ile iki tur bütçesi (25 ve 100). Seçim doğrulama kümesinden, iki koşumun toplamına bakılarak yapılır.
  • SA28. İkinci ölçüt yakalanan şüpheli sayısıdır: 0,5 eşiğinde işaretlenen gerçek şüpheliler, sınama kümesindeki 61 şüpheli üzerinden. Ölçüt tasarımı M27/K03 model-degerlendirme/02’de ölçüldü.

Kayıp Seçimi Eğimi Değiştirir

İki kayıp arasındaki fark kayıp değerinde değil, türevde görünür. Ağ bir aboneye 0,99 diyor ve gerçek etiket 0. Bu, olabilecek en kötü hatalardan biridir; kaybın buna verdiği tepki ölçülebilir.

# kayip.py — MODELDIR. Ayni KURGU abone tablosu, ayni tohum ve ayni bolme;
# egitim kumesi 01'deki gibi 300 satira kucultulmustur.
import math
import statistics

TOHUM, HAM, M32 = 20260218, 1400, 0xFFFFFFFF
BOLGE = [("kuzey", 0.28, 21, 0.00), ("guney", 0.22, 17, -0.10),
         ("dogu", 0.18, 26, 0.30), ("bati", 0.14, 14, -0.05),
         ("merkez", 0.18, 23, 0.05)]


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


ABONE, VERI = [], []
for i in range(HAM):
    r = uretec(TOHUM + i)
    b = BOLGE[ayrik(r(), [x[1] for x in BOLGE])]
    hane = 1 + ayrik(r(), [0.06, 0.24, 0.30, 0.24, 0.11, 0.05])
    memnun = 1 + ayrik(r(), [0.08, 0.14, 0.27, 0.34, 0.17])
    if r() >= 0.046:
        ABONE.append({"no": 10001 + i, "bolge": b, "hane": hane, "memnuniyet": memnun})
for k in ABONE:
    r, v = uretec(TOHUM + 7000 + k["no"]), []
    for d in range(ayrik(r(), [0.05, 0.12, 0.21, 0.62])):
        v.append(0.0 if r() < 0.038 else math.floor(
            k["bolge"][2] * math.exp((r() + r() + r() - 1.5) * 0.62)
            * (1 - d * 0.05) * 100 + 0.5) / 100)
        r()
    if not v:
        continue
    ort, oyn, r = sum(v) / len(v), max(v) - min(v), uretec(TOHUM + 51000 + k["no"])
    z = (0.052 * (ort - 20) + 0.85 * (min(v) == 0.0) + 0.026 * oyn
         + 0.24 * (k["hane"] >= 5) - 0.20 * (k["memnuniyet"] >= 4) + k["bolge"][3]
         + 0.9 * (k["no"] - 10001) / 1399 + (r() + r() + r() - 1.5) * 1.30)
    x = {"hane": k["hane"], "memnuniyet": k["memnuniyet"], "donem": len(v),
         "ort_tuketim": round(ort, 2), "oynaklik": round(oyn, 2),
         "sifir_okuma": int(min(v) == 0.0), "supheli": int(z > 1.35)}
    x["kisi_basi"] = round(x["ort_tuketim"] / x["hane"], 3)
    for b in BOLGE:
        x["b_" + b[0]] = int(k["bolge"][0] == b[0])
    VERI.append(x)


def karistir(veri, tohum):
    r, s = uretec(tohum), list(range(len(veri)))
    for i in range(len(s) - 1, 0, -1):
        j = int(r() * (i + 1))
        s[i], s[j] = s[j], s[i]
    return [veri[i] for i in s]


K = karistir(VERI, TOHUM + 90000)
EGT, DOG, SIN = K[:756], K[756:1008], K[1008:]
ALAN = ["ort_tuketim", "oynaklik", "hane", "memnuniyet", "donem", "sifir_okuma",
        "kisi_basi", "b_kuzey", "b_guney", "b_dogu", "b_bati", "b_merkez"]
ORTALAMA = {a: statistics.fmean(x[a] for x in EGT) for a in ALAN}
SAPMA = {a: max(1e-9, statistics.pstdev([x[a] for x in EGT])) for a in ALAN}
TABAN = sum(x["supheli"] == 0 for x in SIN) / len(SIN)


def kume(veri):
    return ([[(x[a] - ORTALAMA[a]) / SAPMA[a] for a in ALAN] for x in veri],
            [float(x["supheli"]) for x in veri])


XE, YE = kume(EGT[:300])                    # KUCULTULMUS egitim kumesi
XD, YD = kume(DOG)
XS, YS = kume(SIN)


def sikistir(z):                            # S bicimli islev, tasma korumali
    if z >= 0:
        return 1.0 / (1.0 + math.exp(-z)) if z < 700 else 1.0
    e = math.exp(z) if z > -700 else 0.0
    return e / (1.0 + e)


def dogrultulmus(z):
    return z if z > 0.0 else 0.0


def ilklendir(tohum, kat):                  # kazanc olcekli ilklendirme, yanma sifir
    r, ag = uretec(tohum), []
    for a, b in zip(kat, kat[1:]):
        o = math.sqrt(2.0 / a)
        ag.append(([[(r() * 2 - 1) * o for _ in range(a)] for _ in range(b)], [0.0] * b))
    return ag


def dizey_carp(W, y, a):                    # DIZEY CARPIMI elle: her satir bir birim
    return [sum(w * v for w, v in zip(satir, a)) + yanma
            for satir, yanma in zip(W, y)]


def ileri(ag, x):                           # ILERI GECIS: katman katman
    a = x
    for k, (W, y) in enumerate(ag):
        z = dizey_carp(W, y, a)
        a = [sikistir(z[0])] if k == len(ag) - 1 else [dogrultulmus(t) for t in z]
    return a


KAYIP = {                                   # (kayip, cikis katmanindaki egim)
    "capraz duzensizlik": (
        lambda a, y: -(math.log(max(a, 1e-12)) if y else math.log(max(1 - a, 1e-12))),
        lambda a, y: a - y),
    "kare hata": (
        lambda a, y: (a - y) ** 2,
        lambda a, y: 2.0 * (a - y) * a * (1.0 - a)),
}
print(f"egitim {len(XE)}, dogrulama {len(XD)}, sinama {len(XS)}, "
      f"taban cizgisi {TABAN:.4f}\n")
print("siniflandirma, gercek etiket 0:")
print(f"{'cikti':>7} {'capraz kayip':>13} {'capraz egim':>12} {'kare kayip':>11} "
      f"{'kare egim':>10} {'oran':>7}")
for a in (0.01, 0.10, 0.50, 0.90, 0.99):
    ck, ce = KAYIP["capraz duzensizlik"]
    kk, ke = KAYIP["kare hata"]
    print(f"{a:>7.2f} {ck(a, 0.0):>13.4f} {ce(a, 0.0):>12.4f} {kk(a, 0.0):>11.4f} "
          f"{ke(a, 0.0):>10.4f} {ce(a, 0.0) / ke(a, 0.0):>7.1f}")
print("\nbaglanim, artik r:")
print(f"{'r':>7} {'kare kayip':>11} {'kare egim':>10} {'mutlak kayip':>13} "
      f"{'mutlak egim':>12} {'oran':>7}")
for r in (0.5, 1.0, 2.0, 5.0, 10.0):
    print(f"{r:>7.1f} {r * r:>11.4f} {2 * r:>10.4f} {r:>13.4f} {1.0:>12.4f} "
          f"{2 * r:>7.1f}")
egitim 300, dogrulama 252, sinama 252, taban cizgisi 0.7579

siniflandirma, gercek etiket 0:
  cikti  capraz kayip  capraz egim  kare kayip  kare egim    oran
   0.01        0.0101       0.0100      0.0001     0.0002    50.5
   0.10        0.1054       0.1000      0.0100     0.0180     5.6
   0.50        0.6931       0.5000      0.2500     0.2500     2.0
   0.90        2.3026       0.9000      0.8100     0.1620     5.6
   0.99        4.6052       0.9900      0.9801     0.0196    50.5

baglanim, artik r:
      r  kare kayip  kare egim  mutlak kayip  mutlak egim    oran
    0.5      0.2500     1.0000        0.5000       1.0000     1.0
    1.0      1.0000     2.0000        1.0000       1.0000     2.0
    2.0      4.0000     4.0000        2.0000       1.0000     4.0
    5.0     25.0000    10.0000        5.0000       1.0000    10.0
   10.0    100.0000    20.0000       10.0000       1.0000    20.0

Son satır sınıflandırmanın kararını veriyor. Ağ 0,99 deyip yanıldığında çapraz düzensizlik çıkış katmanına 0,9900 gönderiyor, kare hata 0,0196 — arada 50,5 kat var. Kare hatanın eğimi sigmoidin türevini taşıdığı için ağ ne kadar emin yanılıyorsa düzeltme o kadar zayıflıyor. 02’de ölçülen doygunluk burada kayıp üzerinden bir kez daha karşımıza çıkıyor.

Bağlanım tablosu aynı mantığı ters yönde gösteriyor. Artık 10 birimken kare hatanın eğimi 20, mutlak hatanınki 1. Kare hata büyük artıkları öne çıkarır ve tek bir aykırı gözlem uydurmayı kendine çeker; mutlak hata her artığa aynı ağırlığı verir. Hangisinin doğru olduğu verinin değil, hatanın bedelinin sorusudur.

Aynı Ağ, İki Kayıp

Türev farkı sayıya dönüşüyor mu, ancak eğiterek anlaşılır. Aynı ağ, aynı başlangıç değerleri, aynı öğrenme adımı; değişen yalnız kayıp ve tur bütçesi.

def egit(ag, X, Y, adim, tur, kad, izle=()):    # MODELDIR: tam toplu egim inisi
    kay, cikis_egimi = KAYIP[kad]
    n, iz = len(X), []
    for t in range(tur):
        gW = [[[0.0] * len(W[0]) for _ in W] for W, _ in ag]
        gy = [[0.0] * len(y) for _, y in ag]
        toplam = 0.0
        for i in range(n):
            a, ara = X[i], [X[i]]
            for k, (W, y) in enumerate(ag):
                z = dizey_carp(W, y, a)
                a = [sikistir(z[0])] if k == len(ag) - 1 else [dogrultulmus(q) for q in z]
                ara.append(a)
            toplam += kay(ara[-1][0], Y[i])
            d = [cikis_egimi(ara[-1][0], Y[i])]
            for k in range(len(ag) - 1, -1, -1):
                W, a = ag[k][0], ara[k]
                for j, dj in enumerate(d):
                    if dj:
                        s = gW[k][j]
                        for p in range(len(a)):
                            s[p] += dj * a[p]
                        gy[k][j] += dj
                if k:
                    onceki = [0.0] * len(a)
                    for j, dj in enumerate(d):
                        if dj:
                            s = W[j]
                            for p in range(len(a)):
                                onceki[p] += dj * s[p]
                    d = [onceki[p] if a[p] > 0 else 0.0 for p in range(len(a))]
        for k, (W, y) in enumerate(ag):
            for j in range(len(W)):
                s, g = W[j], gW[k][j]
                for p in range(len(s)):
                    s[p] -= adim * g[p] / n
                y[j] -= adim * gy[k][j] / n
        if (t + 1) in izle:
            iz.append((t + 1, toplam / n, dogruluk(ag, XE, YE), dogruluk(ag, XD, YD),
                       dogruluk(ag, XS, YS), yakalanan(ag, XS, YS)))
    return ag, iz


def dogruluk(ag, X, Y):
    return sum((ileri(ag, x)[0] > 0.5) == (y > 0.5) for x, y in zip(X, Y)) / len(X)


def yakalanan(ag, X, Y):                    # 0,5 esiginde isaretlenen gercek supheli
    return sum(1 for x, y in zip(X, Y) if y > 0.5 and ileri(ag, x)[0] > 0.5)


ADAY = {}
print(f"{'kayip':<20} {'tur':>5} {'kosum':>6} {'egt_kayip':>10} {'dogrulama':>10} "
      f"{'sinama':>8}")
for kad in KAYIP:
    for kosum in (1, 2):
        _, iz = egit(ilklendir(TOHUM + kosum, [12, 8, 1]), XE, YE, 0.3, 100, kad,
                     izle=(25, 100))
        for tur, kayip, _, dog, sin, _ in iz:
            ADAY.setdefault((kad, tur), []).append((dog, sin))
            print(f"{kad:<20} {tur:>5} {kosum:>6} {kayip:>10.4f} {dog:>10.4f} {sin:>8.4f}")
SEC = max(ADAY, key=lambda k: sum(t[0] for t in ADAY[k]))
print(f"\ndenenen aday {len(ADAY)}, dogrulamadan secilen: {SEC[0]}, {SEC[1]} tur")
print(f"taban cizgisi {TABAN:.4f}, agin sayisi {ADAY[SEC][0][1]:.4f}, "
      f"ikinci kosum {ADAY[SEC][1][1]:.4f}, fark "
      f"{round(abs(ADAY[SEC][0][1] - ADAY[SEC][1][1]) * len(XS))} abone")
en = {k: max(t[1] for t in ADAY[k]) for k in ADAY}
print(f"kayip secimi (her adayin iyi kosumu) {min(en.values()):.4f}-{max(en.values()):.4f} "
      f"= {round((max(en.values()) - min(en.values())) * len(XS))} abone")
kayip                  tur  kosum  egt_kayip  dogrulama   sinama
capraz duzensizlik      25      1     0.4341     0.8135   0.7778
capraz duzensizlik     100      1     0.3601     0.8214   0.7857
capraz duzensizlik      25      2     0.4152     0.8333   0.7778
capraz duzensizlik     100      2     0.3648     0.8056   0.7698
kare hata               25      1     0.1556     0.8135   0.7619
kare hata              100      1     0.1312     0.8214   0.7857
kare hata               25      2     0.1536     0.8373   0.7897
kare hata              100      2     0.1232     0.8056   0.7738

denenen aday 4, dogrulamadan secilen: kare hata, 25 tur
taban cizgisi 0.7579, agin sayisi 0.7619, ikinci kosum 0.7897, fark 7 abone
kayip secimi (her adayin iyi kosumu) 0.7778-0.7897 = 3 abone

Kayıp sütunları doğrudan karşılaştırılamaz, çünkü iki kayıp iki ayrı ölçekte sayı üretiyor: 0,4341’e karşı 0,1556. Karşılaştırılabilir olan sınama sütunudur ve iki kayıp arasındaki fark üç abone, aynı adayın iki koşumu arasındaki fark ise yedi abone.

Tur bütçesi eğim farkını görünür kılıyor. Yirmi beş turda kare hata 0,7619’da kalırken çapraz düzensizlik 0,7778’e ulaşıyor, yüz turda ikisi de 0,7857’ye çıkıyor. Kare hatanın zayıf eğimi öğrenmeyi durdurmuyor, geciktiriyor.

Kayıp Ölçüt Değildir

Şimdiye kadar kayıp yalnız eğitimi yönlendirdi. Aşağıdaki tablo aynı koşumu tur tur izliyor ve üç sayıyı yan yana koyuyor: eğitim kaybı, sınama doğruluğu ve yakalanan şüpheli sayısı.

IZ = (10, 25, 50, 100, 200)
print(f"sinama kumesindeki supheli sayisi {int(sum(YS))}")
print(f"{'kosum':>6} {'tur':>5} {'egt_kayip':>10} {'egitimde':>9} {'sinamada':>9} "
      f"{'yakalanan':>10}")
IZLER = {}
for kosum in (1, 2):
    _, iz = egit(ilklendir(TOHUM + kosum, [12, 8, 1]), XE, YE, 0.3, IZ[-1],
                 "capraz duzensizlik", izle=IZ)
    IZLER[kosum] = iz
    for tur, kayip, egt, _, sin, yak in iz:
        print(f"{kosum:>6} {tur:>5} {kayip:>10.4f} {egt:>9.4f} {sin:>9.4f} {yak:>10}")
for kosum in (1, 2):
    iz = IZLER[kosum]
    en_iyi = max(iz, key=lambda t: t[4])
    print(f"kosum {kosum}: kayip {iz[0][1]:.4f} -> {iz[-1][1]:.4f} (hep dusuyor), "
          f"sinama en yuksek {en_iyi[0]}. turda {en_iyi[4]:.4f}, "
          f"{IZ[-1]}. turda {iz[-1][4]:.4f}")
    print(f"         yakalanan supheli {iz[0][5]} -> {iz[-1][5]}, "
          f"en yuksek {max(t[5] for t in iz)}")
sinama kumesindeki supheli sayisi 61
 kosum   tur  egt_kayip  egitimde  sinamada  yakalanan
     1    10     0.4861    0.7800    0.7619          1
     1    25     0.4341    0.7933    0.7778          7
     1    50     0.3899    0.8133    0.7937         20
     1   100     0.3601    0.8400    0.7857         21
     1   200     0.3279    0.8600    0.7817         25
     2    10     0.4995    0.7967    0.7817         10
     2    25     0.4152    0.8233    0.7778         16
     2    50     0.3805    0.8233    0.7738         23
     2   100     0.3648    0.8367    0.7698         25
     2   200     0.3518    0.8400    0.7738         25
kosum 1: kayip 0.4861 -> 0.3279 (hep dusuyor), sinama en yuksek 50. turda 0.7937, 200. turda 0.7817
         yakalanan supheli 1 -> 25, en yuksek 25
kosum 2: kayip 0.4995 -> 0.3518 (hep dusuyor), sinama en yuksek 10. turda 0.7817, 200. turda 0.7738
         yakalanan supheli 10 -> 25, en yuksek 25

Kayıp sütunu iki koşumda da tek yönlüdür: hep düşüyor. Eğitim doğruluğu da tek yönlü, 0,78’den 0,86’ya. Sınama doğruluğu ise değil. Birinci koşumda 50. turda 0,7937 ile tepe yapıp 200. turda 0,7817’ye iniyor; ikinci koşumda tepe 10. turdadır ve sonrasında hep aşağı gidiyor. Kaybı düşürmeye devam eden turlar ayrılmış kümedeki doğruluğu kötüleştiriyor.

Son sütun ayrımı tamamlıyor. Yakalanan şüpheli sayısı iki koşumda da artıyor: 1’den 25’e ve 10’dan 25’e. Aynı eğitimin aynı anında bir ölçüt kötüleşirken bir başkası iyileşiyor. Onuncu turda ağ 61 şüphelinin yalnız birini yakalıyor ama doğruluğu 0,7619; 200. turda 25’ini yakalıyor ve doğruluğu 0,7817. “Ağ 50. turda en iyisiydi” cümlesi doğruluğu okuyan için doğru, yakalanan şüpheliyi okuyan için yanlıştır. Hangi turda durulacağı kaybın değil ölçütün ve ölçütün ardındaki bedelin sorusudur; o hesap M27/K03 model-degerlendirme/03’ün konusudur.

Özet

  • Kayıp seçimi kayıp değerinde değil türevde belirleyicidir. Ağ 0,99 deyip yanıldığında çapraz düzensizliğin çıkış eğimi 0,9900, kare hatanınki 0,0196 — oran 50,5.
  • Bağlanımda aynı mantık ters yönde işler: artık 10 birimken kare hatanın eğimi 20, mutlak hatanınki 1. Kare hata büyük artıkları öne çıkarır, mutlak hata hepsine eşit ağırlık verir.
  • Üçlü: taban çizgisi 0,7579, ağın sayısı 0,7619, ikinci koşum 0,7897. Kayıp seçiminin kattığı üç abone, aynı adayın koşum farkı yedi abone.
  • Kare hatanın zayıf eğimi öğrenmeyi durdurmuyor, geciktiriyor: 25 turda 0,7619 ile 0,7778 ayrılıyor, 100 turda ikisi de 0,7857’ye geliyor.
  • Kayıp ölçüt değildir. Eğitim kaybı 0,4861’den 0,3279’a hep düşerken sınama doğruluğu 50. turda tepe yapıp iniyor, yakalanan şüpheli ise 1’den 25’e çıkıyor.

Sonraki Adım

Dört derste eğim hep hazır geldi. Çıkış katmanındaki sayının nasıl bulunduğu bu derste yazıldı, ama o sayının ara katmanın ağırlıklarına nasıl dağıtıldığı hiç açılmadı. Sonraki ders o kutuyu açar: zincir kuralı ağ üzerinde katman katman uygulanır ve elde edilen eğim sayısal türevle karşılaştırılır. Ölçü iki sayıdır — elle hesaplanan eğim ile sayısal türev arasındaki en büyük fark, ve iki yöntemin kaç ileri geçiş tuttuğu.

İlerlemeni kaydetmek ve not almak için Giriş yap

Notlarım

Not almak için giriş yapmalısın.

Aramak için yazmaya başlayın.

↑↓ Esc gezin · aç · kapat