İçeriğe geç
academia.sh

Ders 03 / 24

İleri Yayılım

Ara katmanın genişliğinin iki maliyet sayısı ve bir karşılık sayısıyla ölçülmesi: 12 girdili bir ağda ara katman 2'den 32 birime çıktığında parametre sayısı 29'dan 449'a (15,5 kat), örnek başına çarpma 26'dan 416'ya (16,0 kat), yüz turluk eğitimin toplam çarpması 780.000'den 12.480.000'e büyüyor. Karşılık bunun yanında küçük kalıyor: on koşumun sınama bandı 0,7540-0,7857, yani sekiz abone; her genişliğin iyi koşumları arasındaki fark beş abone ve tek bir genişlikte iki koşum arasındaki en büyük fark da beş abone. Doğrulamadan seçilen genişlik 4 birim, yani 57 parametre, ve o adayın sınama sayısı 0,7540 ile taban çizgisinin altında; ikinci koşumu 0,7738.

İçindekiler

İki derste ağ hep aynı kaldı: on iki girdi, sekiz birim, tek çıktı. Ara katmanın kaç birim taşıyacağı hiç seçilmedi ve seçilseydi neyin değişeceği ölçülmedi. Bu ders o seçime iki maliyet sayısı ve bir karşılık sayısı bağlar.

Maliyet tarafı hesapla bulunur ve koşumdan koşuma değişmez: parametre sayısı — ağın bellekte tuttuğu ağırlık ve yanma adedi — ve örnek başına çarpma sayısı — bir abonenin ağdan bir kez geçmesi için yapılan çarpma adedi. İkisi de ileri geçişin yapısından okunur. Karşılık tarafı ise ancak ölçülerek bulunur ve bu kursun kuralı gereği iki koşumla yazılır.

  • SA15. Küme, bölme, tohum, on iki sütun ve 300 satıra küçültülmüş eğitim kümesi 0102’deki gibidir. Taban çizgisi sınama kümesinde 0,7579.
  • SA16. Ara katmanın etkinleştirmesi bu derste doğrultulmuş doğrusal birimdir ve sabit tutulur; 02 üç etkinleştirmeyi ölçtü, burada değişken yalnız genişliktir.
  • SA17. Çıkış katmanı sigmoittir, çünkü çıktının bir olasılık olması gerekir. Eşik 0,5’tir ve eşiğin bir karar olduğu M27/K03 dogrusal-modeller/04’te ölçüldü.
  • SA18. Parametre sayısı katman çiftleri üzerinden (aibi+bi)\sum (a_i b_i + b_i), örnek başına çarpma sayısı aibi\sum a_i b_i ile hesaplanır; aia_i girdi, bib_i çıktı genişliğidir. Toplama ve etkinleştirme çağrıları sayılmaz, çünkü ölçü çarpma adedidir.
  • SA19. Eğitimdeki toplam çarpma, örnek başına çarpmanın 300 satır ve 100 turla çarpımıdır; geri geçiş sayılmaz, ölçü yalnız ileri yayılımındır.
  • SA20. Denenen genişlik sayısı 5’tir (2, 4, 8, 16, 32) ve seçim doğrulama kümesinden, iki koşumun toplamına bakılarak yapılır. Tek bir koşuma bakarak seçmek bu kursta kabul edilmez.
  • SA21. Öğrenme adımı 0,3 ve tur sayısı 100’dür; 01’de doğrulamadan seçilen ayardır ve genişlik süpürmesi boyunca sabit tutulur.

İki Maliyet Sayısı

Bir katmanın maliyeti şeklinden okunur. On iki girdiden sekiz birime giden bir katman 96 ağırlık ve sekiz yanma taşır; sekiz birimden tek çıktıya giden katman sekiz ağırlık ve bir yanma. Toplam 113. Aynı hesap çarpma için de yapılır ve yanmalar dışarıda kalır, çünkü yanma eklenir, çarpılmaz.

# ileri_gecis.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)


BIRIM = (2, 4, 8, 16, 32)
OLCU = {}
print(f"{'birim':>6} {'sekil':>12} {'parametre':>10} {'carpma/ornek':>13} "
      f"{'egitimde toplam carpma':>23}")
for h in BIRIM:
    kat = [len(ALAN), h, 1]
    par = sum(a * b + b for a, b in zip(kat, kat[1:]))
    carp = sum(a * b for a, b in zip(kat, kat[1:]))
    OLCU[h] = (par, carp)
    print(f"{h:>6} {str(tuple(kat)):>12} {par:>10} {carp:>13} "
          f"{carp * len(XE) * 100:>23}")
p0, c0 = OLCU[BIRIM[0]]
p1, c1 = OLCU[BIRIM[-1]]
print(f"\nbirim {BIRIM[0]}'den {BIRIM[-1]}'ye: parametre {p0} -> {p1} "
      f"({p1 / p0:.1f} kat), carpma {c0} -> {c1} ({c1 / c0:.1f} kat)")
 birim        sekil  parametre  carpma/ornek  egitimde toplam carpma
     2   (12, 2, 1)         29            26                  780000
     4   (12, 4, 1)         57            52                 1560000
     8   (12, 8, 1)        113           104                 3120000
    16  (12, 16, 1)        225           208                 6240000
    32  (12, 32, 1)        449           416                12480000

birim 2'den 32'ye: parametre 29 -> 449 (15.5 kat), carpma 26 -> 416 (16.0 kat)

İki sütun da genişlikle doğru orantılı büyüyor, çünkü on iki girdi her birime ayrı ayrı bağlanıyor. Genişlik on altı katına çıktığında parametre 15,5, çarpma 16,0 katına çıkıyor. Son sütun ölçünün süre olmadığını gösteriyor: yüz turluk bir eğitim en dar ağda 780.000, en geniş ağda 12.480.000 çarpma yapıyor. Bu sayılar hangi makinede koşulduğuna bağlı değildir.

Dizey Çarpımı Elle

İleri geçiş iki adımın tekrarıdır: bir dizey çarpımı ve bir etkinleştirme. Dizey çarpımının her satırı bir birime aittir ve o birimin ağırlıklarını girdi vektörüyle eşleştirir. Elle yazıldığında maliyetin nereden geldiği görünür: iki iç içe döngü, dış döngü birim sayısı kadar, iç döngü girdi sayısı kadar döner.

def dogrultulmus(z):                        # sifirin altini sifira kesen etkinlestirme
    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


def ileri_izle(ag, x):                      # ayni gecis, her katman basilarak
    a, carpma = x, 0
    print(f"  girdi katmani      {len(a):>3} deger, ilk uc {[round(v, 3) for v in a[:3]]}")
    for k, (W, y) in enumerate(ag):
        carpma += len(W) * len(a)
        z = dizey_carp(W, y, a)
        a = [sikistir(z[0])] if k == len(ag) - 1 else [dogrultulmus(t) for t in z]
        ad = "cikis katmani" if k == len(ag) - 1 else f"ara katman {k + 1}"
        print(f"  {ad:<18} {len(a):>3} deger, ilk uc {[round(v, 3) for v in a[:3]]}")
    return a[0], carpma


for h in (4, 8):
    ag = ilklendir(TOHUM + 1, [len(ALAN), h, 1])
    print(f"ara katmanda {h} birim, sinama kumesinin ilk abonesi:")
    cikti, carpma = ileri_izle(ag, XS[0])
    print(f"  yapilan carpma {carpma}, tablodaki {OLCU[h][1]}, "
          f"cikti {cikti:.4f}, gercek etiket {int(YS[0])}")
ara katmanda 4 birim, sinama kumesinin ilk abonesi:
  girdi katmani       12 deger, ilk uc [-0.008, -0.63, 1.399]
  ara katman 1         4 deger, ilk uc [0.047, 0.0, 0.673]
  cikis katmani        1 deger, ilk uc [0.407]
  yapilan carpma 52, tablodaki 52, cikti 0.4068, gercek etiket 0
ara katmanda 8 birim, sinama kumesinin ilk abonesi:
  girdi katmani       12 deger, ilk uc [-0.008, -0.63, 1.399]
  ara katman 1         8 deger, ilk uc [0.047, 0.0, 0.673]
  cikis katmani        1 deger, ilk uc [0.492]
  yapilan carpma 104, tablodaki 104, cikti 0.4923, gercek etiket 0

Sayılan çarpma tablodaki hesapla birebir uyuşuyor: 52 ve 104. Geçişin şekli de görünüyor — 12 değer 4 değere, 4 değer 1 değere iniyor. Ara katmanın ikinci biriminin çıktısı 0,0; girdi ağırlıklı toplamı negatif kaldığı için doğrultulmuş birim onu kesmiş. Aynı abone için iki ağ 0,4068 ve 0,4923 veriyor; ikisi de 0,5 eşiğinin altında ve gerçek etiket 0 olduğu için ikisi de doğru.

Genişlik Ne Kadar Karşılık Veriyor

Maliyet on altı katına çıkarken karşılığın ne olduğu ancak eğitilerek bulunur. Beş genişlik, her biri iki koşum.

def egit(ag, X, Y, adim, tur):              # MODELDIR: tam toplu egim inisi
    n = len(X)
    for _ 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]
        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(t) for t in z]
                ara.append(a)
            d = [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
    return ag


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)


SONUC = {}
print(f"{'birim':>6} {'parametre':>10} {'kosum':>6} {'dogrulama':>10} {'sinama':>8}")
for h in BIRIM:
    SONUC[h] = []
    for kosum in (1, 2):
        ag = egit(ilklendir(TOHUM + kosum, [len(ALAN), h, 1]), XE, YE, 0.3, 100)
        SONUC[h].append((dogruluk(ag, XD, YD), dogruluk(ag, XS, YS)))
        print(f"{h:>6} {OLCU[h][0]:>10} {kosum:>6} {SONUC[h][-1][0]:>10.4f} "
              f"{SONUC[h][-1][1]:>8.4f}")
SEC = max(BIRIM, key=lambda h: sum(t[0] for t in SONUC[h]))
hepsi = [t[1] for h in BIRIM for t in SONUC[h]]
en_iyi = [max(t[1] for t in SONUC[h]) for h in BIRIM]
kosum_farki = max(abs(SONUC[h][0][1] - SONUC[h][1][1]) for h in BIRIM)
print(f"\ndogrulamadan secilen genislik {SEC} birim ({OLCU[SEC][0]} parametre)")
print(f"taban cizgisi {TABAN:.4f}, agin sayisi {SONUC[SEC][0][1]:.4f}, "
      f"ikinci kosum {SONUC[SEC][1][1]:.4f}")
print(f"on kosumun bandi {min(hepsi):.4f}-{max(hepsi):.4f} "
      f"({round((max(hepsi) - min(hepsi)) * len(XS))} abone)")
print(f"genisligin kattigi (her genisligin iyi kosumu) {min(en_iyi):.4f}-{max(en_iyi):.4f} "
      f"= {round((max(en_iyi) - min(en_iyi)) * len(XS))} abone")
print(f"tek genislikte en buyuk kosum farki {kosum_farki:.4f} "
      f"= {round(kosum_farki * len(XS))} abone")
 birim  parametre  kosum  dogrulama   sinama
     2         29      1     0.8135   0.7579
     2         29      2     0.8016   0.7659
     4         57      1     0.8254   0.7540
     4         57      2     0.8135   0.7738
     8        113      1     0.8214   0.7857
     8        113      2     0.8056   0.7698
    16        225      1     0.8135   0.7659
    16        225      2     0.7937   0.7778
    32        449      1     0.8056   0.7817
    32        449      2     0.8056   0.7698

dogrulamadan secilen genislik 4 birim (57 parametre)
taban cizgisi 0.7579, agin sayisi 0.7540, ikinci kosum 0.7738
on kosumun bandi 0.7540-0.7857 (8 abone)
genisligin kattigi (her genisligin iyi kosumu) 0.7659-0.7857 = 5 abone
tek genislikte en buyuk kosum farki 0.0198 = 5 abone

Son iki satır yan yana okunmalıdır. On altı kat parametre farkı, her genişliğin iyi koşumları arasında beş abone üretiyor. Tek bir genişlikte, hiçbir şey değiştirmeden yalnız başlangıç değerleri değişerek, en büyük fark yine beş abone. Genişliği ikiye katlamakla ağı yeniden eğitmek arasındaki fark bu ölçüde ayırt edilemiyor.

Doğrulama sütunu ayrı bir uyarı taşıyor. Seçim doğrulamadan yapıldığında kazanan 4 birim, yani beş adayın en darlardan biri; 57 parametreyle. O adayın sınama sayısı 0,7540 ve bu taban çizgisinin altında — en sık sınıfı söylemek 0,7579 veriyor. Aynı adayın ikinci koşumu 0,7738 veriyor; iki koşum arasında beş abone var ve doğrulama kümesi ikisi arasında seçim yapamıyor, çünkü doğrulamada da 0,8254 ile 0,8135 arasında oynuyor. Ayar bütçesinin şişirdiği farkı M27/K03 model-degerlendirme/07 ölçmüştü; buraya eklenen şey, aynı adayın kendi içindeki oynamasının seçimi bozmasıdır.

Özet

  • İleri geçiş bir dizey çarpımı ile bir etkinleştirmenin tekrarıdır. Dizey çarpımının her satırı bir birime aittir ve elle yazıldığında maliyet iki iç içe döngüden okunur.
  • Ara katman 2’den 32 birime çıktığında parametre 29’dan 449’a (15,5 kat), örnek başına çarpma 26’dan 416’ya (16,0 kat), yüz turluk eğitimin toplam çarpması 780.000’den 12.480.000’e büyüyor. Üç sayı da makineden bağımsızdır.
  • Tek abone izlendiğinde sayılan çarpma tablodaki hesapla birebir uyuşuyor: 4 birimde 52, 8 birimde 104; 12 değer önce ara katmanın genişliğine, sonra tek bir olasılığa iniyor.
  • Üçlü: taban çizgisi 0,7579, ağın sayısı 0,7540, ikinci koşum 0,7738. Doğrulamanın seçtiği genişlik 4 birimdir ve ilk koşumu taban çizgisinin altında kalır.
  • On altı kat parametre farkı beş abone, aynı genişlikte iki koşum arasındaki fark da beş abone ediyor; on koşumun tamamı 0,7540 ile 0,7857 arasında, sekiz abonelik bir bantta duruyor.

Sonraki Adım

Üç 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ırmanın kendisi bir seçimdir ve hiç tartışılmadı. Sonraki ders kayıp fonksiyonunu bir tercih olarak değil bir sayı olarak ele alır: aynı ağ, aynı veri, iki ayrı kayıpla eğitilirse iki ayrı sonuç veriyor mu ve fark kaç abone. Aynı derste ikinci bir ayrım kurulur — eğitimi yöneten kayıp ile başarımı bildiren ölçüt aynı şey değildir, ve kaybı düşüren bir değişiklik ölçütü kötüleştirebilir.

İ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