İçeriğe geç
academia.sh

Ders 19 / 24

Üretici Modeller

Etiket olmadan çalışan iki üretici düzenin aynı kurgu dizi kümesinde ölçülmesi: ortalama diziyle geri kurma tabanı 2,9007 iken doğrusal otokodlayıcı bir örtük boyutta 1,2817 ve 1,2815, dört boyutta 0,7346 ve 0,7314 veriyor; iki koşumun hatası en fazla 0,0311 ayrılırken aynı koşumların bulduğu yönler 1,6330 ile 3,4005 arasında ayrılıyor. Çekişmeli düzende ayırt edicinin gerçek diziler üzerindeki doğruluğu 0,6133'ten 0,3467'ye inip 0,4600'e dönüyor ve iki koşumun ürettiği adım ortalamaları birbirinden 1,2707 uzaklaşıyor — her birinin gerçek kümeden sapmasından, 0,5321 ve 0,8877'den, daha fazla.

İçindekiler

Dokuz derste her mimari bir etiketi kestirdi ve ölçü hep aynı biçimdeydi: ayrılmış kümede kaç doğru. Bir ağın işi etiket kestirmek olmayabilir. Girdinin kendisini az sayıdan yeniden kurmak ya da girdiye benzeyen yeni diziler üretmek de bir görevdir, ve ikisinde de karşılaştırılacak bir etiket yoktur.

Bu dersin sorusu ölçüyle ilgilidir: etiket yokken hangi sayı yazılır. İki düzen ele alınır. Birincisi girdiyi bir örtük uzaydan geri kurar ve hatası doğrudan ölçülebilir. İkincisinde iki ağ birbirine karşı eğitilir ve ortada tek bir hata bile yoktur; orada ölçülen şey başarım değil, aynı düzenin iki koşumunun ne kadar ayrıldığıdır.

  • MI82. Bu payın dizi kurgusu mimariler/06’da kuruldu ve kurgudur. Bu derste dizi ham biçimiyle kullanılır: abone düzeyi, dönemsel bileşen ve önceki derslerin artığı. Önceki dersler diziyi sapma olarak ölçeklenmiş almıştı; sıkıştırılabilir yapı tam olarak orada çıkarılan bileşenlerdedir.
  • MI83. Sütunlar yalnız eğitim kümesinden ölçeklenir ve hata standart sapma birimindedir. Bu, M27/K04 boyut-azaltma’nın birimiyle aynıdır.
  • MI84. Taban çizgisi ortalama diziyle geri kurmadır ve bu, örtük boyutun sıfır olduğu durumdur. Öğrenmeyen en yalın geri kurma budur.
  • MI85. Geri kurma hatası yordamı M27/K04’te kuruldu ve burada tekrarlanmaz. Orada yönler eşdeğişim dizeyinden hesaplanıyordu ve sütun ortalamalarıyla geri kurmanın 3,3411’ine karşı iki bileşen 2,7762 vermişti. Burada yönler hesaplanmaz, eğim inişiyle öğrenilir.
  • MI86. Otokodlayıcı doğrusal bir kodlayıcı ve doğrusal bir çözücüdür; veri ortalandığı için yanma terimi yazılmaz. Ders içinde yazılır ve modeldir.
  • MI87. Çekişmeli düzen iki ağdır: üretici örtük bir vektörden dizi kurar, ayırt edici bir diziyi tek sayıya indirir. İkisi sırayla güncellenir.
  • MI88. Çekişmeli düzenin ölçüsü doğruluk değildir. Üretilen dizilerin adım ortalamaları ve saçılımları gerçek kümeninkilerle karşılaştırılır, ve iki koşumun birbirinden ne kadar ayrıldığı basılır.
  • MI89. Bu ders yalnız yapıyı ve ölçüyü ele alır. Hiçbir üretim uygulaması, sahtecilik ya da denetim atlatma yordamı yazılmaz; bu konular M24 ve M25’in savunma çerçevesine bırakılmıştır.
  • MI90. Her sayı iki koşumla basılır; koşumlar ilklendirme tohumunda ayrılır.

Otokodlayıcı ve Geri Kurma Hatası

Otokodlayıcı iki parçadır. Kodlayıcı on iki sayılık diziyi k sayıya indirir, çözücü o k sayıdan on ikiyi geri kurar, ve eğitim ikisini birlikte geri kurma hatasını küçültecek biçimde ayarlar. Etiket yoktur; hedef girdinin kendisidir.

# ORTAK — MODELDIR. `mimariler/06`'nin KURGU dizisi HAM biciminde kurulur:
# abone duzeyi + donemsel bilesen + onceki derslerin artigi.
import math

TOHUM, M32, ADIM = 20260218, 0xFFFFFFFF, 12


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 dizi_kur(n, tohum):
    D = []
    for i in range(n):
        r = uretec(tohum + i)
        r()
        artik = [0.0] + [round((r() + r() + r() - 1.5) * 1.9, 3) for _ in range(ADIM - 1)]
        r()
        s = uretec(tohum + 6000 + i)
        duzey = 21.0 + (s() + s() + s() - 1.5) * 6.0
        a, b = (s() + s() - 1.0) * 2.6, (s() + s() - 1.0) * 2.6
        aci = [2 * math.pi * t / ADIM for t in range(ADIM)]
        D.append([round(duzey + a * math.sin(aci[t]) + b * math.cos(aci[t]) + artik[t], 3)
                  for t in range(ADIM)])
    return D


VERI = dizi_kur(720, TOHUM)
EGT, SIN = VERI[:150], VERI[540:]
ORT = [sum(x[t] for x in EGT) / len(EGT) for t in range(ADIM)]
SAC = [max(1e-9, (sum((x[t] - ORT[t]) ** 2 for x in EGT) / len(EGT)) ** 0.5)
       for t in range(ADIM)]
ZE = [[(x[t] - ORT[t]) / SAC[t] for t in range(ADIM)] for x in EGT]
ZS = [[(x[t] - ORT[t]) / SAC[t] for t in range(ADIM)] for x in SIN]


def uzaklik(u, v):
    return sum((u[t] - v[t]) ** 2 for t in range(ADIM)) ** 0.5


SIFIR = [0.0] * ADIM
TABAN = sum(uzaklik(z, SIFIR) for z in ZS) / len(ZS)
print(f"dizi {len(VERI)}, uzunluk {ADIM}, egitim {len(EGT)}, ayrilmis {len(SIN)}")
print(f"ornek ham dizi {VERI[0]}")
print(f"taban cizgisi (ortalama diziyle geri kurma) {TABAN:.4f}")
dizi 720, uzunluk 12, egitim 150, ayrilmis 180
ornek ham dizi [21.188, 21.247, 19.977, 20.223, 21.497, 22.188, 24.826, 24.397, 24.089, 25.549, 22.073, 22.529]
taban cizgisi (ortalama diziyle geri kurma) 2.9007

Kurgunun altında üç bileşen vardır: abone düzeyi ve dönemsel bileşenin iki katsayısı. On iki sayı saklansa da dizinin taşıdığı bilgi bu üçün üstüne yalnız gürültü ekler. Otokodlayıcının bulması beklenen şey budur ve hangi k’da bulduğu ölçülebilir.

def otokodlayici(tohum, k, tur=300, adim=0.3):
    # veri sutun ortalamalariyla ortalandigi icin yanma terimi yazilmaz;
    # k=0 durumu tam olarak taban cizgisidir.
    r = uretec(tohum)
    g = lambda: (r() + r() + r() - 1.5) * 0.7
    W1 = [[g() for _ in range(ADIM)] for _ in range(k)]
    W2 = [[g() for _ in range(k)] for _ in range(ADIM)]
    n = len(ZE)
    for _ in range(tur):
        gW1 = [[0.0] * ADIM for _ in range(k)]
        gW2 = [[0.0] * k for _ in range(ADIM)]
        for z in ZE:
            h = [sum(W1[i][t] * z[t] for t in range(ADIM)) for i in range(k)]
            y = [sum(W2[t][i] * h[i] for i in range(k)) for t in range(ADIM)]
            d = [2.0 * (y[t] - z[t]) / ADIM for t in range(ADIM)]
            for t in range(ADIM):
                for i in range(k):
                    gW2[t][i] += d[t] * h[i]
            for i in range(k):
                dh = sum(d[t] * W2[t][i] for t in range(ADIM))
                for t in range(ADIM):
                    gW1[i][t] += dh * z[t]
        for i in range(k):
            for t in range(ADIM):
                W1[i][t] -= adim * gW1[i][t] / n
        for t in range(ADIM):
            for i in range(k):
                W2[t][i] -= adim * gW2[t][i] / n
    return {"k": k, "W1": W1, "W2": W2}


def geri_kur(P, z):
    h = [sum(P["W1"][i][t] * z[t] for t in range(ADIM)) for i in range(P["k"])]
    return [sum(P["W2"][t][i] * h[i] for i in range(P["k"])) for t in range(ADIM)]


def hata(P, Z):
    return sum(uzaklik(z, geri_kur(P, z)) for z in Z) / len(Z)


def yon_farki(A, B):
    # iki kosumun kodlayici yonlerinin normlanmis hallerine gore uzakligi
    f = 0.0
    for i in range(A["k"]):
        u, v = A["W1"][i], B["W1"][i]
        nu = sum(q * q for q in u) ** 0.5
        nv = sum(q * q for q in v) ** 0.5
        f += min(sum(abs(u[t] / nu - v[t] / nv) for t in range(ADIM)),
                 sum(abs(u[t] / nu + v[t] / nv) for t in range(ADIM)))
    return f / A["k"]


print(f"taban cizgisi (k=0) {TABAN:.4f}, tur 300, egitim {len(ZE)}")
print(f"{'k':>3}{'parametre':>11}{'egitim 1':>10}{'egitim 2':>10}{'ayrilmis 1':>12}"
      f"{'ayrilmis 2':>12}{'kosum farki':>13}{'yon farki':>11}")
for k in (1, 2, 3, 4):
    A, B = otokodlayici(TOHUM + 1, k), otokodlayici(TOHUM + 2, k)
    a, b = hata(A, ZS), hata(B, ZS)
    print(f"{k:>3}{2 * ADIM * k:>11}{hata(A, ZE):>10.4f}{hata(B, ZE):>10.4f}"
          f"{a:>12.4f}{b:>12.4f}{abs(a - b):>13.4f}{yon_farki(A, B):>11.4f}")
taban cizgisi (k=0) 2.9007, tur 300, egitim 150
  k  parametre  egitim 1  egitim 2  ayrilmis 1  ayrilmis 2  kosum farki  yon farki
  1         24    1.3001    1.2999      1.2817      1.2815       0.0003     1.6330
  2         48    1.0322    1.0278      1.0597      1.0576       0.0021     2.8634
  3         72    0.7936    0.7502      0.7949      0.7638       0.0311     3.4005
  4         96    0.7219    0.7123      0.7346      0.7314       0.0031     3.3412

Taban 2,9007. Tek bir örtük sayı hatayı 1,2817’ye, üç sayı 0,7949’a indiriyor; üçüncüden dördüncüye geçerken düşüş 0,06 kadar, çünkü kurgunun taşıdığı yapı üç bileşende bitiyor ve dördüncü yön büyük ölçüde gürültüye oturuyor. M27/K04 aynı ölçüyü hesaplanmış yönlerle almıştı; buradaki otokodlayıcı yönleri hesaplamıyor, eğim inişiyle arıyor ve tabanın 0,7346’ya kadar altına iniyor.

Son iki sütun bu kursun okumasıdır. İki koşumun hatası dört satırda da neredeyse aynı: en büyük ayrılık k=3’te 0,0311. Buna karşılık aynı iki koşumun bulduğu yönler 1,6330 ile 3,4005 arasında ayrılıyor — normlanmış on iki bileşenli yönler için bu büyük bir uzaklıktır. Otokodlayıcı bir altuzay buluyor ve o altuzay koşumdan koşuma tekrarlanıyor; altuzayın içindeki eksenler tekrarlanmıyor. Bir örtük boyutu adlandırmak isteyen biri, adlandırdığı şeyin tohumla birlikte değiştiğini bilmelidir.

Çekişmeli Düzen ve Kararsızlık

Çekişmeli düzende geri kurulacak bir girdi yoktur. Üretici örtük bir vektörden dizi kurar, ayırt edici gerçekle üretileni ayırmaya çalışır, ve üreticinin kaybı ayırt edicinin yanılmasıdır. İki ağın hedefi birbirinin tersidir; bu yüzden hiçbir tarafın kaybı tek başına iyiye gitmez ve “kayıp düştü” cümlesi burada bir ilerleme belirtisi değildir.

GZ, GG, DG, DUR = 3, 6, 6, (30, 60, 90, 120)


def cekismeli(tohum, tur=120, adim=0.6):
    r = uretec(tohum)
    g = lambda: (r() + r() + r() - 1.5) * 0.8
    U = {"W1": [[g() for _ in range(GZ)] for _ in range(GG)],
         "b1": [[0.0] for _ in range(GG)],
         "W2": [[g() for _ in range(GG)] for _ in range(ADIM)],
         "b2": [[0.0] for _ in range(ADIM)]}
    A = {"W1": [[g() for _ in range(ADIM)] for _ in range(DG)],
         "b1": [[0.0] for _ in range(DG)], "w": [[g()] for _ in range(DG)],
         "b": [[0.0]]}
    z, N, iz = uretec(tohum + 77), len(ZE), []

    def uret(v):                        # uretici: ortuk vektorden diziye
        h = [math.tanh(sum(U["W1"][i][j] * v[j] for j in range(GZ)) + U["b1"][i][0])
             for i in range(GG)]
        return h, [sum(U["W2"][t][i] * h[i] for i in range(GG)) + U["b2"][t][0]
                   for t in range(ADIM)]

    def ayirt(x):                       # ayirt edici: diziden tek sayiya
        u = [sum(A["W1"][i][t] * x[t] for t in range(ADIM)) + A["b1"][i][0]
             for i in range(DG)]
        return u, sum(A["w"][i][0] * u[i] for i in range(DG) if u[i] > 0) + A["b"][0][0]

    def inis(P, G):
        for ad in P:
            for i in range(len(P[ad])):
                for j in range(len(P[ad][i])):
                    P[ad][i][j] -= adim * G[ad][i][j]

    def bos(P):
        return {ad: [[0.0] * len(u) for u in P[ad]] for ad in P}

    for t in range(1, tur + 1):
        Z = [[(z() + z() + z() - 1.5) * 1.6 for _ in range(GZ)] for _ in range(N)]
        SAHTE = [uret(v)[1] for v in Z]
        gA = bos(A)
        for x, y in [(u, 1) for u in ZE] + [(u, 0) for u in SAHTE]:
            u, o = ayirt(x)
            d = (1.0 / (1.0 + math.exp(-max(-30.0, min(30.0, o)))) - y) / (2 * N)
            gA["b"][0][0] += d
            for i in range(DG):
                gA["w"][i][0] += d * max(0.0, u[i])
                du = d * A["w"][i][0] if u[i] > 0 else 0.0
                gA["b1"][i][0] += du
                for j in range(ADIM):
                    gA["W1"][i][j] += du * x[j]
        gU = bos(U)
        for v in Z:
            h, x = uret(v)
            u, o = ayirt(x)
            d = (1.0 / (1.0 + math.exp(-max(-30.0, min(30.0, o)))) - 1) / N
            dx = [sum(d * A["w"][i][0] * A["W1"][i][j] for i in range(DG) if u[i] > 0)
                  for j in range(ADIM)]
            for j in range(ADIM):
                gU["b2"][j][0] += dx[j]
                for i in range(GG):
                    gU["W2"][j][i] += dx[j] * h[i]
            for i in range(GG):
                dh = sum(dx[j] * U["W2"][j][i] for j in range(ADIM)) * (1 - h[i] * h[i])
                gU["b1"][i][0] += dh
                for j in range(GZ):
                    gU["W1"][i][j] += dh * v[j]
        inis(A, gA)
        inis(U, gU)
        if t in DUR:
            iz.append((t, sum(ayirt(x)[1] > 0 for x in ZE) / N,
                       sum(ayirt(x)[1] <= 0 for x in SAHTE) / N))
    ort = [sum(x[t] for x in SAHTE) / N for t in range(ADIM)]
    return iz, ort, [(sum((x[t] - ort[t]) ** 2 for x in SAHTE) / N) ** 0.5
                     for t in range(ADIM)]
GER_ORT = [sum(x[t] for x in ZE) / len(ZE) for t in range(ADIM)]
GER_SAC = [(sum((x[t] - GER_ORT[t]) ** 2 for x in ZE) / len(ZE)) ** 0.5
           for t in range(ADIM)]
K = [cekismeli(TOHUM + j) for j in (1, 2)]
print(f"{'tur':>5}" + "".join(f"{'k' + str(j + 1) + ' gercek':>12}{'k' + str(j + 1) + ' sahte':>11}"
                              for j in (0, 1)))
for i, (t, _g, _s) in enumerate(K[0][0]):
    print(f"{t:>5}" + "".join(f"{K[j][0][i][1]:>12.4f}{K[j][0][i][2]:>11.4f}"
                             for j in (0, 1)))


def sap(a, b):
    return sum(abs(a[t] - b[t]) for t in range(ADIM)) / ADIM


print(f"{'olcu':<28}{'kosum 1':>10}{'kosum 2':>10}{'iki kosum farki':>18}")
print(f"{'ortalamanin gercekten sapmasi':<28}{sap(K[0][1], GER_ORT):>10.4f}"
      f"{sap(K[1][1], GER_ORT):>10.4f}{sap(K[0][1], K[1][1]):>18.4f}")
print(f"{'sacilimin gercekten sapmasi':<28}{sap(K[0][2], GER_SAC):>10.4f}"
      f"{sap(K[1][2], GER_SAC):>10.4f}{sap(K[0][2], K[1][2]):>18.4f}")
  tur   k1 gercek   k1 sahte   k2 gercek   k2 sahte
   30      0.6133     0.8067      0.5200     1.0000
   60      0.3933     0.7800      0.6267     1.0000
   90      0.3467     0.6600      0.5800     1.0000
  120      0.4600     0.8533      0.6400     0.9333
olcu                           kosum 1   kosum 2   iki kosum farki
ortalamanin gercekten sapmasi    0.5321    0.8877            1.2707
sacilimin gercekten sapmasi     0.3669    0.5434            0.3418

İlk tablo düzenin kararsızlığını doğrudan gösterir. Birinci koşumda ayırt edicinin gerçek diziler üzerindeki doğruluğu 0,6133’ten 0,3467’ye iniyor ve sonra 0,4600’e dönüyor; bu arada üretilenleri tanıma oranı 0,8067 ile 0,8533 arasında gidip geliyor. İkinci koşumda ayırt edici üretilenlerin tamamını üç ölçümde de yakalıyor — orada üretici hiç ilerlemedi. Hangi turda durulduğu sonucu değiştirir ve durma noktasını söyleyecek tek yönlü bir eğri yoktur.

İkinci tablo bu dersin kapanış sayısıdır. İki koşumun ürettiği adım ortalamaları gerçek kümeden 0,5321 ve 0,8877 sapıyor, ama birbirinden 1,2707 sapıyor. İki koşum arasındaki uzaklık, her birinin hedefe uzaklığından büyüktür; yani iki koşum aynı yere doğru değil, iki ayrı yere gitmiştir. Otokodlayıcıda aynı karşılaştırma 0,0311’i geçmiyordu. Kararlılık farkı düzenin kapasitesinden değil, hedefinin biçiminden gelir: sabit bir hedefi küçültmek ile hareketli bir rakibi yanıltmak aynı problem değildir.

Özet

  • Etiket olmadan da ölçü vardır: otokodlayıcının tabanı ortalama diziyle geri kurmadır ve 2,9007’dir; bu taban, örtük boyutun sıfır olduğu durumdur.
  • Bir örtük boyut hatayı 1,2817’ye, üç boyut 0,7949’a indirir; dördüncü boyut yalnız 0,06 kadar ekler, çünkü kurgunun yapısı üç bileşende biter.
  • İki koşumun geri kurma hatası en fazla 0,0311 ayrılırken buldukları yönler 1,6330 ile 3,4005 arasında ayrılır: altuzay tekrarlanır, eksenler tekrarlanmaz.
  • Çekişmeli düzende ayırt edicinin gerçek diziler üzerindeki doğruluğu 0,6133 ile 0,3467 arasında oynar ve tek yönlü bir eğri vermez; ikinci koşumda üretici hiç ilerlemez.
  • İki koşumun ürettiği adım ortalamaları birbirinden 1,2707 ayrılır — her birinin gerçek kümeden sapmasından, 0,5321 ve 0,8877’den, daha fazla.

Sonraki Adım

On derste mimari seçildi. Evrişim girdinin ızgara yapısını, yineleme ve kapı birimleri sıra yapısını, dikkat ve çok başlı dikkat uzak adımlara doğrudan erişimi, gömme ayrık simgeleri, aktarım başka bir görevden gelen temsili, üretici düzenler ise etiketsiz bir hedefi kullandı. Her birinin kattığı fark tabanına karşı ölçüldü ve her sayının yanına ikinci koşumu yazıldı. Bu on dersin tamamının ortak bir yanı var ve hiç sorulmadı: hepsi elle yazılmış küçük bir eğitim döngüsünde koştu. Eğim her seferinde bu sayfada türetildi, veri belleğe sığdı, toplu boyut örneklem sayısına eşitti, tohum tek bir yerde duruyordu ve hiçbir koşumun kaydı tutulmadı. Sonraki konu mimariyi değil eğitimin düzeneğini ele alır: eğimin elle değil hesap çizgesinden türetilmesi, verinin toplu üretilmesi, belleğin toplu boyutla ilişkisi, koşumların yeniden üretilebilir kaydı ve ayar aramasının koşum değişkenliğiyle nasıl yanıldığı.

İ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