İçeriğe geç
academia.sh

Ders 07 / 24

Eğitim Kararlılığı

Eğimin katmanlardan geçerken sönmesinin ve patlamasının sayıyla ölçülmesi: doygun etkinleştirmeyle ilk katmanın eğim büyüklüğü tek gizli katmanda 1,274e-02 iken altı katmanda 5,539e-05'e, yani 232 kat aşağı iner ve son katmana oran 18,8'den 3977,2'ye çıkar; doğrultulmuş doğrusal birimle aynı derinlikte oran 0,7022'de kalır, ilklendirme kazancı 16'ya çıkarıldığında ise 134,99 kat büyür. Öğrenme adımı 10'da üç gizli katmanlı ağın eğim büyüklüğü 2,800e+07'ye fırlıyor, 24 birimin 15'i ölüyor ve iki koşum da tam olarak taban çizgisini, 0,7579'u veriyor. Eğim kırpma 450 güncellemenin 400'ünü kırpıp eğitimi kurtarıyor ama sınama 0,6984'e, tabanın altına düşüyor; kırpma ile çizelge birlikte kaybı 0,2722'ye indiriyor ve koşum farkını 0,0516'ya, on üç aboneye çıkarıyor.

İçindekiler

Önceki ders üç adım kuralını iki katmanlı bir ağda karşılaştırdı. Orada eğim geri gelirken bir kez zincirlendi, bu yüzden her katman benzer büyüklükte bir eğim gördü. Katman sayısı arttığında bu doğru olmaktan çıkar: çıkıştaki hata girişe doğru ilerlerken her katmanda bir çarpanla süzülür ve o çarpanların çarpımı ilk katmana ne kaldığını belirler. Çarpanlar birden küçükse çarpım sıfıra iner, birden büyükse taşar.

Bu ders o çarpımı ölçer. İki uç ayrı ayrı sayılır — sönen eğim ve patlayan eğim — sonra iki düzeltme denenir: eğim kırpma ve öğrenme adımı çizelgesi. Ölçü yine ikilidir: eğitimin kurtarılması ile ayrılmış küme sayısının düzelmesi aynı şey değildir.

  • SA54. Küme, bölme, tohum ve ölçek önceki derstekiyle aynıdır; tablo kurgudur, eğitim kümesi 300 satıra küçültülmüştür ve taban çizgisi sınamada 0,7579.
  • SA55. Her gizli katman 8 birimlidir: bir katman 113, iki katman 185, dört katman 329, altı katman 473 parametre eder.
  • SA56. Eğim büyüklüğü bir katmandaki eğim girdilerinin karelerinin ortalamasının koküdür; katmanlar farklı sayıda ağırlık taşıdığı için toplam değil ortalama alınır.
  • SA57. Ölçüm ilklendirmeden hemen sonra, tek bir 60 satırlık toplu üzerinde yapılır; sorulan şey eğitimin sonucu değil, eğimin katmanlar arasında nasıl dağıldığıdır. İki etkinleştirme yan yana durur: sigmoit (doygun) ve doğrultulmuş doğrusal birim (doygunsuz). Kazanç, ilklendirme aralığının genişliğini belirleyen çarpandır.
  • SA58. Kararlılık denemesinde ağ üç gizli katmanlıdır, 30 tur ve 20 toplu boyutuyla 450 güncelleme yapar ve yalın iniş kullanır. Denenen ayar 5’tir; bu bir arama değildir.
  • SA59. Eğim kırpma eşiği 0,10’dur ve bütün ağın eğim büyüklüğüne bir kerede uygulanır: büyüklük eşiği aşarsa eğim aynı oranla küçültülür, yön korunur. Çizelge her altı turda öğrenme adımını yarıya indirir.
  • SA60. Ölü birim hiçbir eğitim satırında sıfırdan büyük çıktı vermeyen birimdir; üç gizli katmanda toplam 24 birim vardır.

Eğim Katmanlardan Geçerken

Kurulum önceki dersinkiyle aynıdır; tek fark ileri geçişin ve geri yayılımın etkinleştirmeyi bir değişken olarak almasıdır. Sigmoitin türevi çıktının kendisinden hesaplanır, doğrultulmuş doğrusal birimin türevi sıfır ya da birdir.

# kararlilik.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)
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 ileri(kat, x, etkin="dogrultulmus"):
    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])]
        elif etkin == "sigmoit":
            a = [sikistir(t) for t in z]
        else:
            a = [t if t > 0 else 0.0 for t in z]
    iz.append(a)
    return iz


def egim(kat, X, Y, idx, etkin="dogrultulmus"):      # GERI YAYILIM
    G, kayip = sifir(kat), 0.0
    tur = (lambda v: v * (1 - v)) if etkin == "sigmoit" else (lambda v: v > 0)
    for i in idx:
        iz = ileri(kat, X[i], etkin)
        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:
                d = [sum(d[k] * W[k][j] for k in range(len(W))) * tur(a[j])
                     for j in range(len(a))]
    for W in G:
        for w in W:
            w[:] = [v / len(idx) for v in w]
    return G, kayip / len(idx)


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


def bicim(derin, gizli=8):                  # derin adet gizli katman, sonra tek cikti
    return [(len(ALAN), gizli)] + [(gizli, gizli)] * (derin - 1) + [(gizli, 1)]


print(f"egitim {len(EGT)} (756'dan kucultuldu), sinama {len(SIN)}, sutun {len(ALAN)}")
print("gizli katman ve parametre: " + ", ".join(
    f"{d} -> {sum(len(w) for W in ilklendir(TOHUM, bicim(d)) for w in W)}"
    for d in (1, 2, 3, 4, 6)))
print(f"taban {TABAN:.4f}; karsilastirma cizgileri dogrusal model {DOGRUSAL:.4f}, "
      f"karar agaci {AGAC:.4f}")
egitim 300 (756'dan kucultuldu), sinama 252, sutun 12
gizli katman ve parametre: 1 -> 113, 2 -> 185, 3 -> 257, 4 -> 329, 6 -> 473
taban 0.7579; karsilastirma cizgileri dogrusal model 0.8016, karar agaci 0.7857

Sönen ve Patlayan Eğimin Sayısı

Her derinlikte ağ ilklendirilir, tek bir toplu üzerinde eğim hesaplanır ve ilk katmanın eğim büyüklüğü ile son katmanınki yan yana basılır. Son sütun, aynı ailedeki tek katmanlı ağa göre ilk katmanın kaç katına indiğini verir.

def buyukluk(W):                            # kareler ortalamasinin koku
    return math.sqrt(sum(v * v for w in W for v in w) / sum(len(w) for w in W))


print(f"{'etkinlestirme':>14} {'kazanc':>7} {'derinlik':>9} {'ilk katman':>12} "
      f"{'son katman':>12} {'son/ilk':>12} {'ilke gore':>10}")
ILK = {}
for etkin, kazanc in (("sigmoit", 1.0), ("dogrultulmus", 2.0), ("dogrultulmus", 16.0)):
    for derin in (1, 2, 4, 6):
        kat = ilklendir(TOHUM + 1, bicim(derin), kazanc)
        G, _ = egim(kat, XE, YE, range(60), etkin)
        b = [buyukluk(W) for W in G]
        ILK.setdefault((etkin, kazanc), b[0])
        print(f"{etkin:>14} {kazanc:>7} {derin:>9} {b[0]:>12.3e} {b[-1]:>12.3e} "
              f"{b[-1] / b[0]:>12.1f} {b[0] / ILK[(etkin, kazanc)]:>10.4f}")
 etkinlestirme  kazanc  derinlik   ilk katman   son katman      son/ilk  ilke gore
       sigmoit     1.0         1    1.274e-02    2.393e-01         18.8     1.0000
       sigmoit     1.0         2    2.820e-03    4.822e-02         17.1     0.2213
       sigmoit     1.0         4    1.930e-04    1.318e-01        682.6     0.0151
       sigmoit     1.0         6    5.539e-05    2.203e-01       3977.2     0.0043
  dogrultulmus     2.0         1    9.817e-02    5.694e-01          5.8     1.0000
  dogrultulmus     2.0         2    5.689e-02    2.176e-01          3.8     0.5796
  dogrultulmus     2.0         4    2.513e-02    5.219e-01         20.8     0.2560
  dogrultulmus     2.0         6    6.893e-02    3.273e-01          4.7     0.7022
  dogrultulmus    16.0         1    3.065e-01    1.707e+00          5.6     1.0000
  dogrultulmus    16.0         2    5.330e-01    2.059e+00          3.9     1.7387
  dogrultulmus    16.0         4    1.769e+00    3.761e+01         21.3     5.7719
  dogrultulmus    16.0         6    4.138e+01    1.813e+02          4.4   134.9930

İlk dört satır sönen eğimin sayısıdır. Doygun etkinleştirmeyle ilk katmanın gördüğü eğim büyüklüğü tek katmanda 1,274e-02, altı katmanda 5,539e-05 — son sütuna göre 0,0043, yani 232 kat aşağıda; son katmana oran ise 18,8’den 3977,2’ye çıkıyor. Altı katmanlı ağın son katmanı tek katmanlı ağınkiyle aynı büyüklükte eğim görüyor, kaybolan yalnızca girişe yakın katmanların payıdır. Bu ağ eğitilirse 473 parametrenin büyük bölümü ilklendirildiği yerde kalır.

Orta dört satırda aynı derinlikler doygunsuz etkinleştirmeyle ölçülüyor ve altı katmanda oran 0,7022; sönme neredeyse yok. Söndüren derinlik değil, çarpanın büyüklüğüdür. Son dört satır ters uçtur: kazanç 16’ya çıkarıldığında çarpanlar birden büyük olur ve çarpım yukarı kaçar. Altı katmanda ilk katmanın eğim büyüklüğü tek katmanlınınkinin 134,99 katıdır. Sönen eğim ağırlıkları dondurur, patlayan eğim onları tek bir güncellemede uçurur.

Kırpma ve Çizelge Neyi Düzeltiyor

Patlama yalnız ilklendirmeden gelmez; büyük bir öğrenme adımı da aynı sonucu üretir. Aşağıdaki blok üç gizli katmanlı bir ağı önce güvenli bir adımla, sonra iki yüz kat büyük bir adımla eğitiyor ve iki düzeltmeyi tek tek ve birlikte deniyor.

def norm(G):                                # butun agin egim buyuklugu
    return math.sqrt(sum(v * v for W in G for w in W for v in w))


def olu(kat):                               # hicbir egitim satirinda etkinlesmeyen birim
    canli = [[False] * len(W) for W in kat[:-1]]
    for x in XE:
        iz = ileri(kat, x)
        for L in range(len(kat) - 1):
            for j, v in enumerate(iz[L + 1]):
                if v > 0:
                    canli[L][j] = True
    return sum(not c for W in canli for c in W)


def egit(adim, tohum, kirp=0.0, cizelge=False, derin=3, tur=30, toplu=20):
    kat, kirpma, ennorm, iz = ilklendir(tohum, bicim(derin), 2.0), 0, 0.0, []
    for t in range(tur):
        a = adim * 0.5 ** (t // 6) if cizelge else adim
        s, top = sira(t), 0.0
        for b in range(0, len(s), toplu):
            G, k = egim(kat, XE, YE, s[b:b + toplu])
            n = norm(G)
            ennorm = max(ennorm, n)
            if kirp and n > kirp:           # yon korunur, buyukluk esige cekilir
                kirpma += 1
                for W in G:
                    for w in W:
                        w[:] = [v * kirp / n for v in w]
            for W, gW in zip(kat, G):
                for w, g in zip(W, gW):
                    for j in range(len(w)):
                        w[j] -= a * g[j]
            top += k * toplu
        iz.append(top / len(s))
    return kat, iz[-1], kirpma, ennorm


AYAR = (("adim 0,05", 0.05, 0.0, False), ("adim 10 ciplak", 10.0, 0.0, False),
        ("adim 10 kirpma", 10.0, 0.10, False), ("adim 10 cizelge", 10.0, 0.0, True),
        ("adim 10 ikisi", 10.0, 0.10, True))
print(f"{'ayar':>16} {'kayip 2 kosum':>16} {'sinama 2 kosum':>16} {'olu':>7} "
      f"{'kirpilan':>9} {'en buyuk egim':>14}")
OZ = {}
for ad, adim, kirp, cz in AYAR:
    kk = [egit(adim, TOHUM + s, kirp, cz) for s in (1, 2)]
    OZ[ad] = [sum((ileri(k, x)[-1][0] > 0.5) == (y > 0.5)
                  for x, y in zip(XS, YS)) / len(XS) for k, _, _, _ in kk]
    print(f"{ad:>16} {kk[0][1]:>7.4f} {kk[1][1]:>8.4f} {OZ[ad][0]:>8.4f} {OZ[ad][1]:>7.4f} "
          f"{olu(kk[0][0]):>6}/24 {kk[0][2]:>5}/450 {kk[0][3]:>14.3e}")
print(f"\ntaban cizgisi {TABAN:.4f}, agin sayisi {OZ['adim 0,05'][0]:.4f}, "
      f"ayni agin ikinci kosumu {OZ['adim 0,05'][1]:.4f}")
for ad in ("adim 10 ciplak", "adim 10 kirpma", "adim 10 ikisi"):
    print(f"{ad:>16} kosum farki {abs(OZ[ad][0] - OZ[ad][1]):.4f} "
          f"({round(abs(OZ[ad][0] - OZ[ad][1]) * len(SIN))} abone)")
            ayar    kayip 2 kosum   sinama 2 kosum     olu  kirpilan  en buyuk egim
       adim 0,05  0.3666   0.3776   0.7817  0.7778      0/24     0/450      4.599e+00
  adim 10 ciplak  0.6210   0.6210   0.7579  0.7579     15/24     0/450      2.800e+07
  adim 10 kirpma  0.4333   0.3578   0.6984  0.6944      1/24   400/450      7.982e+00
 adim 10 cizelge  0.5287   0.5287   0.7579  0.7579     15/24     0/450      2.800e+07
   adim 10 ikisi  0.2722   0.2473   0.7698  0.7183      0/24   422/450      6.445e+00

taban cizgisi 0.7579, agin sayisi 0.7817, ayni agin ikinci kosumu 0.7778
  adim 10 ciplak kosum farki 0.0000 (0 abone)
  adim 10 kirpma kosum farki 0.0040 (1 abone)
   adim 10 ikisi kosum farki 0.0516 (13 abone)

İkinci satır patlamanın eğitim içindeki halidir. Eğim büyüklüğü bir noktada 2,800e+07‘ye fırlıyor, o güncelleme ağırlıkları uçuruyor ve 24 birimin **15’i** bir daha hiçbir eğitim satırında etkinleşmiyor. Sonuç iki koşumda da aynı: 0,7579, tam olarak taban çizgisi. Ağ artık herkese “şüpheli değil” diyor. İki ilklendirmenin aynı sayıyı vermesi burada iyi haber değildir — ikisi de aynı ölü noktaya düşmüştür.

Dördüncü satır çizelgenin tek başına ne yaptığını söylüyor: hiçbir şey. Adım altı turda bir yarılanıyor ama patlama ilk turda oluyor. Bir çizelge, kendisinden önce gerçekleşmiş hasarı geri almaz.

Üçüncü satırda eğim kırpma işini yapıyor: 450 güncellemenin 400’ü kırpılıyor, gördüğü en büyük eğim 7,982’ye iniyor ve ölü birim 15’ten 1’e düşüyor. Ama sınama sayısı 0,6984, tabanın belirgin biçimde altında. Kırpma eğitimi kurtardı, modeli kurtarmadı. Beşinci satırda ikisi birlikte kaybı tablonun en düşüğüne, 0,2722’ye indiriyor; sınama 0,7698’e çıkıyor ama ikinci koşumda 0,7183’e düşüyor — 0,0516, on üç abone. En geniş koşum açıklığı, en iyi görünen ayarda.

Üçlü şudur: taban çizgisi 0,7579, ağın sayısı 0,7817, ikinci koşum 0,7778. Güvenli adımdaki sığ ayar kurtarılmış derin ayarların hepsinden yüksek ve hiçbiri doğrusal modelin 0,8016’sına yaklaşmıyor.

Özet

  • Doygun etkinleştirmeyle ilk katmanın eğim büyüklüğü altı katmanda tek katmanlının 0,0043 katına, yani 232 kat aşağı iniyor; son katmana oran 18,8’den 3977,2’ye çıkıyor.
  • Doygunsuz etkinleştirmeyle aynı derinlikte oran 0,7022’de kalıyor; kazanç 16’da ise aynı ölçü 134,99 kata çıkıp patlıyor. Söndüren derinlik değil, çarpanın büyüklüğüdür.
  • Öğrenme adımı 10’da eğim büyüklüğü 2,800e+07’ye fırlıyor, 24 birimin 15’i ölüyor ve iki koşum da tam olarak taban çizgisini veriyor; çizelge tek başına bunu düzeltmiyor.
  • Eğim kırpma 450 güncellemenin 400’ünü kırpıp ölü birimi 1’e indiriyor ama sınama 0,6984’e düşüyor; kırpma ile çizelge birlikte en düşük kaybı ve en geniş koşum açıklığını üretiyor.

Sonraki Adım

Bu iki derste ağ hep aynı yönde bozuldu: eğitim kaybı düştükçe ayrılmış küme sayısı düşme eğilimindeydi. 300 satır ve birkaç yüz parametreyle bunun adı bellidir. Sonraki ders o adı bir sayıya bağlar. Ağırlık cezası M27/K01 ve M27/K03’te ölçüldü ve tekrarlanmayacak; eklenecek olan ağa özgü iki yöntemdir — eğitim sırasında birimlerin bir bölümünü rastgele susturan seyreltme ve turu erkenden kesen erken durdurma. İkincisinde asıl soru yöntem değil kaynaktır: durma turu hangi kümeden okunuyor.

İ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