İçeriğe geç
academia.sh

Ders 08 / 24

Düzenlileştirme

Ağa özgü iki düzenlileştirme yönteminin katkısının ve erken durdurmanın hangi kümeden okunduğunun ölçülmesi: çıplak ağın eğitim ile sınama arasındaki açığı 0,0887 iken 0,4 oranlı seyreltmede 0,0330'a iner ve sınama 0,7579'dan 0,7937'ye çıkar; aynı ayarın ikinci koşumu 0,7738 verir ve orada çıplak ağ seyreltmeli ağı geçer. Ağırlık cezası M27/K01 ve M27/K03'te süpürülmüştü, burada tek katsayıyla uygulanır ve açığı 0,0702'ye indirir. Erken durdurmada doğrulama kaybı onuncu ve on dördüncü turda dibi görür; durma turu eğitimden okunursa sınama 0,7579 ve 0,7817, doğrulamadan okunursa 0,7698 ve 0,7976, sınamadan okunursa 0,7738 ve 0,8016 çıkar — sınamadan okumanın şişmesi iki koşumda da 0,0040, yani bir abonedir.

İçindekiler

Önceki iki ders aynı yönü işaret etti: eğitim kaybı düştükçe ayrılmış küme sayısı düşme eğilimindeydi. Bu, adı konmuş bir durumdur — 300 satırlık bir eğitim kümesine birkaç yüz parametre düşünce ağ satırları ezberler. Aşırı uyumun kendisi M27/K01’in Genelleme konusunda ölçüldü ve burada tekrarlanmaz. Burada sorulan şey daha dar: ağa özgü hangi karşı önlemler var ve her biri kaç abone ediyor.

Ağırlık cezası bu soruya verilen ilk yanıt değildir ve bu kursta yeniden süpürülmez. M27/K01 genelleme/04 ceza katsayısını 0,001’den 1000’e taşıyıp ağırlık büyüklüğünün 10,040’tan 0,601’e indiğini, M27/K03 dogrusal-modeller/03 ise karesel, mutlak ve karma cezanın seyreklikte ayrıldığını ölçmüştü. Burada ceza tek bir katsayıyla ve yalnız karşılaştırma çizgisi olarak kullanılır. Dersin eklediği iki yöntem şudur: seyreltme ve erken durdurma.

Terim ayrımı: bu kurstaki seyreltme, eğitim sırasında gizli birimlerin bir bölümünü geçici olarak susturmaktır. M26/K06’nın Grafik konusundaki seyreltme bir çizim tekniğiydi ve nokta sayısını azaltıyordu; ikisinin ortak yanı yalnız adıdır.

  • SA61. Küme, bölme, tohum ve ölçek önceki derslerdeki gibidir; tablo kurgudur, eğitim kümesi 300 satıra küçültülmüştür ve taban çizgisi sınamada 0,7579.
  • SA62. Ağ bu derste 16 gizli birimlidir ve 225 parametre taşır. Genişletildi, çünkü seyreltmenin kapatacağı birim olması gerekiyor.
  • SA63. Eğitim 45 tur, toplu boyut 20, yalın iniş, öğrenme adımı 0,05’tir. Bu ayarlar aranmadı; önceki dersten geliyor.
  • SA64. Seyreltme her küçük topluda yeniden çekilen bir maskeyle uygulanır: kapatılan birimin çıktısı sıfır, kalanların çıktısı 1/(1p)1/(1-p) ile büyütülür. Ölçek eğitimde uygulandığı için çıkarımda hiçbir düzeltme gerekmez; ağ eğitim dışında maskesiz çalışır.
  • SA65. Maske küçük toplu başınadır, satır başına değil. Bu bir karardır ve maske sayısını 45 çarpı 15, yani 675’te tutar.
  • SA66. Ağırlık cezası katsayısı 0,01’dir ve eğime ceza çarpı ağırlık olarak eklenir. Yanmalar cezalandırılmaz: yanma karar sınırının konumunu taşır, eğriliğini değil.
  • SA67. Erken durdurma ölçütü doğrulama kaybıdır, doğruluk değil; doğruluk 252 satırlık bir kümede 0,0040’lık basamaklarla ölçer ve dibi belirsiz kalır.
  • SA68. Denenen ayar 5‘tir; bu bir arama değil, dört önlemin çıplak ağla yan yana konmasıdır. Karşılaştırma çizgileri M27/K03’ten gelir: doğrusal model 0,8016, karar ağacı 0,7857.

Ağa Özgü İki Yöntem

Kurulum önceki derslerdekiyle aynıdır; eklenen iki şey ileri geçişin bir maske alması ve geri yayılımın eğime bir ceza terimi koyabilmesidir. Maskelenmiş bir birimin çıktısı sıfır olduğu için eğimi de sıfırdır; kalan birimlerin eğimi maskedeki büyütme çarpanıyla ölçeklenir.

# duzenlilestirme.py — MODELDIR. Ayni KURGU abone tablosu, ayni tohum, ayni bolme;
# egitim kumesi bu konuda 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


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:
        continue
    no = 10001 + i
    r, v = uretec(TOHUM + 7000 + 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(
            b[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 + no)
    z = (0.052 * (ort - 20) + 0.85 * (min(v) == 0.0) + 0.026 * oyn + 0.24 * (hane >= 5)
         - 0.20 * (memnun >= 4) + b[3] + 0.9 * (no - 10001) / 1399
         + (r() + r() + r() - 1.5) * 1.30)
    x = {"hane": hane, "memnuniyet": memnun, "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 q in BOLGE:
        x["b_" + q[0]] = int(b[0] == q[0])
    VERI.append(x)

r, S = uretec(TOHUM + 90000), 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]
K = [VERI[i] for i in S]
EGT, DOG, SIN = K[:300], K[756:1008], K[1008:]      # egitim 756'dan 300'e KUCULTULDU
ALAN = ["ort_tuketim", "oynaklik", "hane", "memnuniyet", "donem", "sifir_okuma",
        "kisi_basi", "b_kuzey", "b_guney", "b_dogu", "b_bati", "b_merkez"]
ORT = {a: statistics.fmean(x[a] for x in EGT) for a in ALAN}
SAP = {a: max(1e-9, statistics.pstdev([x[a] for x in EGT])) for a in ALAN}


def olcekli(s):                             # OGRENME egitimden, UYGULAMA her kumeye
    return ([[(x[a] - ORT[a]) / SAP[a] for a in ALAN] for x in s],
            [float(x["supheli"]) for x in s])


XE, YE = olcekli(EGT)
XD, YD = olcekli(DOG)
XS, YS = olcekli(SIN)
TABAN = sum(y == 0.0 for y in YS) / len(YS)
AGAC, DOGRUSAL = 198 / len(SIN), 202 / len(SIN)     # M27/K03'un iki sayisi


def sikistir(z):
    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 ilklendir(tohum, bicim, kazanc=1.0):    # kazanc olcekli; her satirin son sutunu YANMA
    r, kat = uretec(tohum), []
    for g, c in bicim:
        a = math.sqrt(6.0 * kazanc / g)
        kat.append([[(r() * 2 - 1) * a for _ in range(g)] + [0.0] for _ in range(c)])
    return kat


def sifir(kat):
    return [[[0.0] * len(w) for w in W] for W in kat]


def maskele(kat, oran, tohum):              # SEYRELTME: kapatilan birim 0, kalan 1/(1-oran)
    r = uretec(tohum)
    return [[0.0 if r() < oran else 1.0 / (1.0 - oran) for _ in W] for W in kat[:-1]]


def ileri(kat, x, maske=None):
    a, iz = x, []
    for i, W in enumerate(kat):
        iz.append(a)
        z = [sum(p * q for p, q in zip(w, a)) + w[-1] for w in W]
        if i == len(kat) - 1:
            a = [sikistir(z[0])]
        else:
            a = [t if t > 0 else 0.0 for t in z]
            if maske:
                a = [v * m for v, m in zip(a, maske[i])]
    iz.append(a)
    return iz


def egim(kat, X, Y, idx, maske=None, ceza=0.0):      # GERI YAYILIM
    G, kayip = sifir(kat), 0.0
    for i in idx:
        iz = ileri(kat, X[i], maske)
        p = min(max(iz[-1][0], 1e-12), 1 - 1e-12)
        kayip -= Y[i] * math.log(p) + (1 - Y[i]) * math.log(1 - p)
        d = [p - Y[i]]
        for L in range(len(kat) - 1, -1, -1):
            W, a = kat[L], iz[L]
            for k, dk in enumerate(d):
                gk = G[L][k]
                for j, aj in enumerate(a):
                    gk[j] += dk * aj
                gk[-1] += dk
            if L:
                mk = maske[L - 1] if maske else None
                d = [sum(d[k] * W[k][j] for k in range(len(W)))
                     * (0.0 if a[j] <= 0 else (mk[j] if mk else 1.0))
                     for j in range(len(a))]
    for W in G:
        for w in W:
            w[:] = [v / len(idx) for v in w]
    if ceza:                                # AGIRLIK CEZASI: yanma cezalandirilmaz
        for W, gW in zip(kat, G):
            for w, g in zip(W, gW):
                for j in range(len(w) - 1):
                    g[j] += ceza * w[j]
    return G, kayip / len(idx)


def kayipla(kat, X, Y):
    t = 0.0
    for x, y in zip(X, Y):
        p = min(max(ileri(kat, x)[-1][0], 1e-12), 1 - 1e-12)
        t -= y * math.log(p) + (1 - y) * math.log(1 - p)
    return t / len(X)


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


def sira(tur):                              # toplu bolme sirasi her kosumda AYNI
    r, s = uretec(TOHUM + 500 + tur), list(range(len(XE)))
    for i in range(len(s) - 1, 0, -1):
        j = int(r() * (i + 1))
        s[i], s[j] = s[j], s[i]
    return s


KAT0 = ilklendir(TOHUM + 1, [(len(ALAN), 16), (16, 1)])
print(f"ag {len(ALAN)}-16-1, parametre {sum(len(w) for W in KAT0 for w in W)}, "
      f"egitim {len(EGT)}, dogrulama {len(DOG)}, sinama {len(SIN)}, tur 45, toplu 20")
print(f"taban {TABAN:.4f}; karsilastirma cizgileri dogrusal model {DOGRUSAL:.4f}, "
      f"karar agaci {AGAC:.4f}")
ag 12-16-1, parametre 225, egitim 300, dogrulama 252, sinama 252, tur 45, toplu 20
taban 0.7579; karsilastirma cizgileri dogrusal model 0.8016, karar agaci 0.7857

Seyreltme ve Ağırlık Cezası

Eğitim döngüsü tek bir işlevdedir ve iki önlemi de anahtarla alır. Ölçü üç sütundur: eğitim doğruluğu, sınama doğruluğu ve ikisi arasındaki açık. Açık aşırı uyumun doğrudan ölçüsüdür; bir düzenlileştirme yöntemi çalışıyorsa önce açığı daraltır.

def egit(tohum, oran=0.0, ceza=0.0, izle=False, adim=0.05, tur=45, toplu=20, gizli=16):
    kat, egri = ilklendir(tohum, [(len(ALAN), gizli), (gizli, 1)]), []
    for t in range(tur):
        s = sira(t)
        for bi, b in enumerate(range(0, len(s), toplu)):
            mk = maskele(kat, oran, TOHUM + 900 + t * 100 + bi) if oran else None
            G, _ = egim(kat, XE, YE, s[b:b + toplu], mk, ceza)
            for W, gW in zip(kat, G):
                for w, g in zip(W, gW):
                    for j in range(len(w)):
                        w[j] -= adim * g[j]
        if izle:                            # her turun sonunda ayrilmis kume okunur
            egri.append((kayipla(kat, XE, YE), kayipla(kat, XD, YD),
                         dogruluk(kat, XS, YS)))
    return kat, egri


AYAR = (("ciplak", 0.0, 0.0), ("seyreltme 0,2", 0.2, 0.0), ("seyreltme 0,4", 0.4, 0.0),
        ("agirlik cezasi", 0.0, 0.01), ("seyreltme 0,4 + ceza", 0.4, 0.01))
print(f"{'ayar':>21} {'egitim':>15} {'sinama':>15} {'acik':>7} {'kosum':>7}")
OZ = {}
for ad, oran, ceza in AYAR:
    kk = [egit(TOHUM + s, oran, ceza)[0] for s in (1, 2)]
    e = [dogruluk(k, XE, YE) for k in kk]
    OZ[ad] = [dogruluk(k, XS, YS) for k in kk]
    print(f"{ad:>21} {e[0]:>7.4f} {e[1]:>7.4f} {OZ[ad][0]:>7.4f} {OZ[ad][1]:>7.4f} "
          f"{e[0] - OZ[ad][0]:>7.4f} {abs(OZ[ad][0] - OZ[ad][1]):>7.4f}")
print(f"\ndenenen ayar {len(AYAR)}; taban {TABAN:.4f}, agin sayisi "
      f"{OZ['seyreltme 0,4'][0]:.4f}, ayni agin ikinci kosumu {OZ['seyreltme 0,4'][1]:.4f}")
print(f"karar agacini gecen kosum {sum(v > AGAC + 1e-9 for n in OZ.values() for v in n)}/10, "
      f"dogrusal modeli gecen {sum(v > DOGRUSAL + 1e-9 for n in OZ.values() for v in n)}/10")
                 ayar          egitim          sinama    acik   kosum
               ciplak  0.8467  0.8467  0.7579  0.7817  0.0887  0.0238
        seyreltme 0,2  0.8267  0.8300  0.7778  0.7937  0.0489  0.0159
        seyreltme 0,4  0.8267  0.8133  0.7937  0.7738  0.0330  0.0198
       agirlik cezasi  0.8400  0.8433  0.7698  0.7937  0.0702  0.0238
 seyreltme 0,4 + ceza  0.8233  0.8133  0.7897  0.7738  0.0337  0.0159

denenen ayar 5; taban 0.7579, agin sayisi 0.7937, ayni agin ikinci kosumu 0.7738
karar agacini gecen kosum 4/10, dogrusal modeli gecen 0/10

Açık sütunu düzenli davranıyor. Çıplak ağda eğitim ile sınama arasında 0,0887 var — yirmi iki abone. Seyreltme oranı 0,2’de bu 0,0489’a, 0,4’te 0,0330‘a iniyor. İki buçuk katlık daralma seyreltmenin işini yaptığını gösteriyor: her küçük toplu farklı birimlerle çalıştığı için hiçbir birim tek bir eğitim satırını tek başına ezberleyemiyor. Ağırlık cezası aynı açığı yalnız 0,0702’ye indiriyor; cezanın süpürülmediği bir ayarda bu beklenen bir sonuçtur ve süpürmenin ne kazandırdığı M27/K01’de ölçülmüştür.

Sınama sütunu ilk koşumda açığı doğruluyor: 0,7579’dan 0,7937’ye, on abone. Ama ikinci koşum bunu onaylamıyor. Orada çıplak ağ 0,7817, seyreltmeli ağ 0,7738 veriyor — sıralama tersine dönüyor. İlk koşuma bakan “seyreltme 0,4 çıplak ağı 0,0358 geçiyor” der, ikinci koşuma bakan “0,0079 geriden geliyor” der. İkisi de aynı kodu çalıştırmıştır. Son satır kursun ikinci iddiasını sürdürüyor: on koşumun dördü karar ağacını geçiyor, hiçbiri doğrusal modeli geçmiyor.

Erken Durdurma Hangi Kümeden Okunur

Erken durdurma bir ayar değil, bir okuma noktasıdır: eğitim kaç turda kesilecek. Asıl soru, turun hangi kümeye bakılarak bulunduğudur. Aşağıdaki blok üç kaynağı yan yana koyuyor.

for s in (1, 2):
    _, egri = egit(TOHUM + s, izle=True)
    dg = min(range(len(egri)), key=lambda t: egri[t][1])     # dogrulama kaybinin dibi
    sn = max(range(len(egri)), key=lambda t: egri[t][2])     # sinamanin tepesi
    print(f"kosum {s}: egitim kaybi 1. turda {egri[0][0]:.4f}, son turda {egri[-1][0]:.4f}; "
          f"dogrulama kaybi {egri[0][1]:.4f} -> {egri[-1][1]:.4f}")
    print(f"  durma turu egitimden okunursa 45: sinama {egri[-1][2]:.4f}")
    print(f"  durma turu dogrulamadan okunursa {dg + 1}: dogrulama kaybi "
          f"{egri[dg][1]:.4f}, sinama {egri[dg][2]:.4f}")
    print(f"  durma turu sinamadan okunursa {sn + 1}: sinama {egri[sn][2]:.4f}, "
          f"sisme {egri[sn][2] - egri[dg][2]:.4f} "
          f"({round((egri[sn][2] - egri[dg][2]) * len(SIN))} abone)")
kosum 1: egitim kaybi 1. turda 0.5183, son turda 0.3549; dogrulama kaybi 0.5244 -> 0.4505
  durma turu egitimden okunursa 45: sinama 0.7579
  durma turu dogrulamadan okunursa 10: dogrulama kaybi 0.4475, sinama 0.7698
  durma turu sinamadan okunursa 11: sinama 0.7738, sisme 0.0040 (1 abone)
kosum 2: egitim kaybi 1. turda 0.6826, son turda 0.3478; dogrulama kaybi 0.6677 -> 0.4244
  durma turu egitimden okunursa 45: sinama 0.7817
  durma turu dogrulamadan okunursa 14: dogrulama kaybi 0.4129, sinama 0.7976
  durma turu sinamadan okunursa 11: sinama 0.8016, sisme 0.0040 (1 abone)

İki kayıp eğrisi ayrışıyor. Eğitim kaybı kırk beş tur boyunca hiç yükselmiyor: birinci koşumda 0,5183’ten 0,3549’a iniyor. Doğrulama kaybı ise onuncu turda 0,4475 ile dibi görüp yukarı dönüyor ve son turda 0,4505’e çıkıyor. Eğitim kümesine bakarak durma turu seçilemez, çünkü orada duracak bir yer yoktur — eğrinin dibi hep son turdadır.

Doğrulama kümesinden okunan tur birinci koşumda 10, ikinci koşumda 14. Karşılıkları sınamada 0,7698 ve 0,7976; kırk beş tur koşulsaydı 0,7579 ve 0,7817 olurdu. Erken durdurmanın katkısı birinci koşumda 0,0119, ikincisinde 0,0159 — yani üç ile dört abone. Birinci koşumda çıplak ağ tam olarak taban çizgisine düşmüştü; erken durdurma onu tabanın üstüne çıkarıyor.

Son satırlar dersin asıl uyarısıdır. Sınama kümesine bakılarak seçilseydi tur her iki koşumda da 11 olurdu ve rapor edilen sayılar 0,7738 ile 0,8016 olurdu. Şişme 0,0040, yani bir abone. Küçüktür, ama ölçülmemiş bir kazançtır: sınama kümesi bir kez okunduğu anda ayrılmış olmaktan çıkar. Aynı mantık M27/K02’nin boru hattı dersinde bir dönüşümün bütün kümeden öğrenilmesi için kurulmuştu; erken durdurma turu da bir dönüşüm kadar bilgi taşır.

Özet

  • Ağırlık cezası M27/K01 ve M27/K03’te süpürülmüştü; burada tek katsayıyla uygulanıyor ve eğitim ile sınama arasındaki açığı 0,0887’den 0,0702’ye indiriyor.
  • Seyreltme aynı açığı 0,4 oranında 0,0330’a indiriyor; her küçük toplu farklı birimlerle çalıştığı için tek bir birim tek bir satırı ezberleyemiyor.
  • Ölçeklendirme eğitimde yapıldığı için çıkarımda düzeltme gerekmez; ağ eğitim dışında maskesiz çalışır.
  • Sınama sütunu ilk koşumda seyreltmeyi 0,0358 önde gösteriyor, ikinci koşumda 0,0079 geride; on koşumun dördü karar ağacını geçiyor, hiçbiri doğrusal modeli geçmiyor.
  • Doğrulama kaybı 10. ve 14. turda dibi görüyor; durma turu doğrulamadan okunduğunda sınama 0,7698 ve 0,7976, sınamadan okunduğunda 0,7738 ve 0,8016 çıkıyor — şişme her iki koşumda da 0,0040, bir abone.

Sonraki Adım

Bu dersin iki yöntemi de ağın çıktısına dokunuyordu: biri birimleri susturuyor, öbürü ağırlıkları küçültüyordu. Katmanların girdisine hiç dokunulmadı. Oysa girdi ölçekleme kurs boyunca kullanılan tek hazırlık adımıydı ve yalnız ilk katmana uygulandı; ikinci katmanın gördüğü sayılar eğitim ilerledikçe kayıyor ve kimse onları yerinde tutmuyor. Sonraki ders bunu bir ölçüye bağlar: katman girdileri her topluda yeniden ölçeklendiğinde ağ, normalleştirmesiz kararsız olan bir öğrenme adımında ne yapıyor. Aynı ders bir sızıntı kaynağı da açar, çünkü normalleştirme eğitimde ve çıkarımda aynı sayıyı kullanmaz.

İ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