İçeriğe geç
academia.sh

Ders 10 / 14

Görüntü Sınıflandırma

Uçtan uca eğitimin ve öğrenme aktarımının alanın tabanına karşı ölçülmesi: en sık sınıf 0,5312 ve ortalama görüntü 0,5500 iken 1.169 parametreli ağ 144 pikselde iki koşumda da 0,6000, 305 parametreli ağ havuzlanmış 36 sayıda 0,6687 ve 0,7063 okuyor; ikisi de eğitim kümesini tamamen ezberliyor. Yirmi etiketle sıfırdan eğitim 0,5188 ve 0,5250 ile alanın tabanının altında kalırken kurgu bir kaynak görevden üretilen önceden eğitilmiş modelin dondurulması 0,6312 ve 0,5500, ince ayarı 0,5938 ve 0,5625 veriyor. Altmış etikette üstünlük kapanıyor, yüz altmışta sıfırdan eğitim 0,6125 ve 0,6875 ile öne geçiyor; dondurmanın iki koşumu arasındaki 0,0812'lik açıklık aktarımın kattığı farktan büyüktür.

İçindekiler

Önceki dersin en yüksek sayısı bir modelden gelmedi. Görüntü başına normalleştirilmiş temsilde, eşik üstü piksellerin sınırlayıcı kutusunu çıkarıp yüksekliğiyle genişliğini karşılaştıran üç satırlık bir kural sınamada 0,9250 okudu. O kuralı yazabilmek için görevin geometrisini bilmek gerekiyordu: etiketin bloğun yönü olduğunu, bloğun tek olduğunu, gürültünün eşiğin altında kaldığını.

Bu ders o bilgiyi geri alır. Kural silinir, yerine etiketli örneklerden öğrenen bir model konur ve iki soru sorulur. Birincisi, model alanın tabanını ne kadar geçiyor. İkincisi, etiket sayısı yirmiye indiğinde ne oluyor — ve başka bir görevde eğitilmiş bir modelin taşıdığı temsil, kaç etiketli örneğe bedel.

  • BG9. Görüntü kurgusu önceki dersteki ile aynıdır: 12x12 tek kanallı gri düzeyli görüntü, tek dikdörtgen blok, etiket bloğun yönü, tohum 20260218, bölme 160/80/160.
  • BG10. Alanın tabanı iki yordamdır: en sık sınıf ve ortalama görüntü. İkincisi ham piksellerde ölçülür ve bu kümede 0,5500 verir.
  • BG11. Model bir gizli katmanlı küçük bir ağdır ve ders içinde yazılır. Sekiz gizli birim, çıkış sigmoit, güncelleme örnek başına, yüz tur.
  • BG12. Her kurulum iki kez koşulur. İkinci koşumda yalnız başlangıç değerleri ve karıştırma sırası değişir; veri, bölme, tur sayısı ve öğrenme adımı aynıdır.
  • BG13. Havuzlama ve evrişim burada kurulmaz. 2x2 ortalama havuzlama M27/K05’te ölçülmüş bir işlemdir ve bu derste yalnız bir girdi temsili olarak kullanılır.
  • BG14. Kaynak görev kurgudur ve hedef görevden ayrıdır: başka 240 görüntü, “blok geniş mi” sorusu. Önceden eğitilmiş model bu görevden kendi elimizle üretilir; hedef görevin hiçbir etiketini ve hiçbir görüntüsünü görmez.
  • BG15. Dondurma gizli katmanın kaynaktan alınıp değiştirilmemesi, ince ayar aynı katmanın hedef görevde eğitilmeye devam etmesidir. İkisinde de çıkış katmanı yeniden kurulur.

Alanın Tabanı ve Temsil

# veri.py — MODELDIR. Onceki dersin goruntu kurgusu aynen surer: 12x12 tek
# kanalli gri duzeyli goruntu, tek dikdortgen blok, etiket blogun yonu.
TOHUM, M32, BOY = 20260218, 0xFFFFFFFF, 12
EN_KUCUK, EN_BUYUK, GIZ = 2, 6, 8


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 goruntu(no):
    r = uretec(TOHUM + 700000 + no)
    zemin, karsitlik = 30 + int(r() * 70), 20 + int(r() * 36)
    yuk = EN_KUCUK + int(r() * (EN_BUYUK - EN_KUCUK + 1))
    gen = EN_KUCUK + int(r() * (EN_BUYUK - EN_KUCUK + 1))
    while gen == yuk:
        gen = EN_KUCUK + int(r() * (EN_BUYUK - EN_KUCUK + 1))
    i = int((r() + r() + r()) / 3 * (BOY - yuk + 1))
    j = int((r() + r() + r()) / 3 * (BOY - gen + 1))
    g = [[0] * BOY for _ in range(BOY)]
    for a in range(BOY):
        for b in range(BOY):
            v = zemin + (karsitlik if i <= a < i + yuk and j <= b < j + gen else 0)
            v += int(r() * 61) - 30
            g[a][b] = 0 if v < 0 else (255 if v > 255 else v)
    return g, (i, j, yuk, gen), (1 if gen > yuk else 0)


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


HAM = [goruntu(i) for i in range(400)]
VERI = [HAM[i] for i in karistir(400, TOHUM + 40000)]
EGT, DOG, SIN = VERI[:160], VERI[160:240], VERI[240:]


def duz(g):
    return [v for s in g for v in s]


def norm_t(g):                                   # goruntu basina normallestirme
    x = duz(g)
    m = sum(x) / len(x)
    sd = (sum((v - m) ** 2 for v in x) / len(x)) ** 0.5
    return [(v - m) / sd for v in x]


def ozet(g):                                     # normallestir, 2x2 ortalama havuzla
    x = norm_t(g)
    return [sum(x[(2 * a + p) * BOY + 2 * b + q] for p in (0, 1) for q in (0, 1)) / 4
            for a in range(6) for b in range(6)]


def ortalama_goruntu(egt, sin):
    """Alanin tabani: sinif ortalamalari, karar en yakin ortalamadir."""
    M = {}
    for e in (0, 1):
        alt = [x for x, y in egt if y == e]
        M[e] = [sum(a[i] for a in alt) / len(alt) for i in range(len(alt[0]))]

    def uzak(x, e):
        return sum((x[i] - M[e][i]) ** 2 for i in range(len(x)))
    return sum(1 for x, y in sin if (1 if uzak(x, 1) < uzak(x, 0) else 0) == y) / len(sin)


ENSIK = max(sum(e for _, _, e in SIN), len(SIN) - sum(e for _, _, e in SIN)) / len(SIN)
TABAN = ortalama_goruntu([(duz(g), e) for g, _, e in EGT],
                         [(duz(g), e) for g, _, e in SIN])
print(f"bolme {len(EGT)}/{len(DOG)}/{len(SIN)}, girdi {BOY * BOY} piksel; "
      f"2x2 havuzlamadan sonra {len(ozet(EGT[0][0]))} sayi")
print(f"alanin tabani, en sik sinif : {ENSIK:.4f}")
print(f"alanin tabani, ortalama goruntu: {TABAN:.4f}")
bolme 160/80/160, girdi 144 piksel; 2x2 havuzlamadan sonra 36 sayi
alanin tabani, en sik sinif : 0.5312
alanin tabani, ortalama goruntu: 0.5500

Ortalama görüntü yordamı iki sınıfın ortalama görüntüsünü tutar ve yeni görüntüyü hangisine daha yakınsa oraya yazar. Toplam 288 sayı saklar, hiçbir yineleme yapmaz, hiçbir ayar değişkeni istemez. Bu alanın en aptal yordamıdır ve 0,5500 okur; en sık sınıfın 0,5312’sinden 0,0188 yüksek. Bundan sonraki her sayı bu ikisiyle birlikte okunur.

Bu derste doğrulama kümesine bakılmıyor. Tur sayısı, öğrenme adımı ve gizli birim sayısı bütün kurulumlarda aynı tutuluyor; hiçbir süpürme yapılmıyor. Bunun nedeni ölçünün ne olduğudur: sorulan soru “en iyi ağ hangisi” değil, “girdi temsilini ya da başlangıç ağırlıklarını değiştirmek aynı bütçede sayıyı ne kadar oynatıyor”. Ayar bütçesi kurulumlar arasında değişseydi fark ayardan mı temsilden mi geldiği okunamazdı.

Uçtan Uca Eğitim

# ag.py — MODELDIR. Bir gizli katmanli kucuk bir ag, ders icinde yazilir.
# Cikis sigmoit, guncelleme ornek basina, kayip capraz duzensizlik.
import math


def kur(D, tohum):
    r, a = uretec(tohum), (1 / D) ** 0.5
    return [[[(r() * 2 - 1) * a for _ in range(D)] for _ in range(GIZ)], [0.0] * GIZ,
            [(r() * 2 - 1) * (1 / GIZ) ** 0.5 for _ in range(GIZ)], [0.0]]


def ileri(P, x):
    W, b, v, c = P
    h = [max(0.0, b[k] + sum(W[k][i] * x[i] for i in range(len(x)))) for k in range(GIZ)]
    z = c[0] + sum(v[k] * h[k] for k in range(GIZ))
    return h, (1 / (1 + math.exp(-z)) if z > -30 else 0.0)


def egit(P, veri, tur, gadim, tohum, gizli=True):
    W, b, v, c = P
    r, n, D = uretec(tohum), len(veri), len(veri[0][0])
    for _ in range(tur):
        s = list(range(n))
        for i in range(n - 1, 0, -1):
            j = int(r() * (i + 1))
            s[i], s[j] = s[j], s[i]
        for idx in s:
            x, y = veri[idx]
            h, p = ileri(P, x)
            for k in range(GIZ):
                if gizli and h[k] > 0.0:
                    dh = (p - y) * v[k]
                    b[k] -= gadim * dh
                    for i in range(D):
                        W[k][i] -= gadim * dh * x[i]
                v[k] -= gadim * (p - y) * h[k]
            c[0] -= gadim * (p - y)
    return P


def dogruluk(P, veri):
    return sum(1 for x, y in veri if (ileri(P, x)[1] >= 0.5) == (y == 1)) / len(veri)


def kume(don, veri):
    return [(don(g), e) for g, _, e in veri]


print(f"{'girdi':<22}{'parametre':>10}{'kosum':>7}{'egitim':>8}{'sinama':>8}")
print(f"{'en sik sinif':<22}{0:>10}{'-':>7}{'-':>8}{ENSIK:>8.4f}")
print(f"{'ortalama goruntu':<22}{2 * BOY * BOY:>10}{'-':>7}{'-':>8}{TABAN:>8.4f}")
for ad, don, D in (("144 piksel", norm_t, BOY * BOY), ("36 sayi (havuzlanmis)", ozet, 36)):
    E, S = kume(don, EGT), kume(don, SIN)
    for t in (0, 1):
        P = egit(kur(D, TOHUM + 11 + t), E, 100, 0.05, TOHUM + 511 + t)
        print(f"{ad if t == 0 else '':<22}{D * GIZ + 2 * GIZ + 1 if t == 0 else '':>10}"
              f"{t + 1:>7}{dogruluk(P, E):>8.4f}{dogruluk(P, S):>8.4f}")
girdi                  parametre  kosum  egitim  sinama
en sik sinif                   0      -       -  0.5312
ortalama goruntu             288      -       -  0.5500
144 piksel                  1169      1  1.0000  0.6000
                                      2  1.0000  0.6000
36 sayi (havuzlanmis)        305      1  1.0000  0.6687
                                      2  1.0000  0.7063

Dört satırın hepsinde eğitim doğruluğu 1,0000. Yüz altmış görüntü 144 boyutlu bir uzayda birbirine benzemez; ağ hepsini ayrı ayrı ezberleyecek kadar geniştir ve ezberlemek, yönün ne olduğunu öğrenmekten kolaydır. Sınama sayıları bunun karşılığıdır: 0,6000 ve 0,6000.

Girdiyi 144 sayıdan 36 sayıya indirmek — 2x2 pencerelerin ortalamasını almak — sınama sayısını 0,6687 ve 0,7063‘e çıkarıyor. Parametre sayısı 1.169’dan 305’e düşüyor. Fark bir eniyileme kazancı değil, bir varsayımdır: havuzlama “bir pikselin tek başına değeri değil, komşularıyla birlikte ortalaması önemlidir” der ve bu kurguda doğrudur, çünkü blok tek bir pikselle değil bitişik bir bölgeyle tanımlıdır.

İki koşum arasındaki açıklık havuzlanmış girdide 0,0376‘dır. Aynı ağın, aynı verinin ve aynı bütçenin yalnız başlangıç değerleri değişerek açtığı bu aralık, havuzlamanın kattığı 0,0875’lik farkın yarısı kadardır. Elle yazılmış eşik kuralının 0,9250’si hâlâ çok uzaktadır ve bu ağın kusuru değil, ölçünün kendisidir: kural görevin geometrisini biliyor, ağ onu yüz altmış örnekten çıkarmak zorunda.

Öğrenme Aktarımı

# aktarim.py — MODELDIR. Onceden egitilmis model KURGU bir kaynak gorevden
# kendi elimizle uretilir: kaynak gorev "blok genis mi" sorusudur, hedef
# gorevin hicbir etiketini gormez ve hedef goruntulerin hicbirini kullanmaz.
KAYNAK = [goruntu(1000 + i) for i in range(240)]
KVERI = [(ozet(g), 1 if k[3] >= 4 else 0) for g, k, _ in KAYNAK]
ON = [egit(kur(36, TOHUM + 21 + t), KVERI, 100, 0.05, TOHUM + 521 + t) for t in (0, 1)]
print(f"kaynak gorev: {len(KVERI)} goruntu, etiket 1 orani "
      f"{sum(y for _, y in KVERI) / len(KVERI):.4f}, kaynak gorevde dogruluk "
      f"{dogruluk(ON[0], KVERI):.4f} ve {dogruluk(ON[1], KVERI):.4f}")


def aktar(P, tohum):
    """Gizli katman kaynaktan alinir; cikis katmani yeniden kurulur."""
    r, (W, b, _, _) = uretec(tohum), P
    return [[s[:] for s in W], b[:],
            [(r() * 2 - 1) * (1 / GIZ) ** 0.5 for _ in range(GIZ)], [0.0]]


E36, S36 = kume(ozet, EGT), kume(ozet, SIN)
print(f"\n{'etiket':>7}{'sifirdan':>19}{'dondurma':>19}{'ince ayar':>19}")
print(f"{'':>7}{'kosum 1  kosum 2':>19}{'kosum 1  kosum 2':>19}{'kosum 1  kosum 2':>19}")
for n in (20, 60, 160):
    satir = f"{n:>7}"
    for kurulum in ("sifirdan", "dondurma", "ince ayar"):
        for t in (0, 1):
            if kurulum == "sifirdan":
                P = kur(36, TOHUM + 31 + t)
            else:
                P = aktar(ON[t], TOHUM + 41 + t)
            P = egit(P, E36[:n], 100, 0.05, TOHUM + 531 + t,
                     gizli=(kurulum != "dondurma"))
            satir += f"{dogruluk(P, S36):>9.4f}" if t else f"{dogruluk(P, S36):>10.4f}"
    print(satir)
print(f"alanin tabani: en sik sinif {ENSIK:.4f}, ortalama goruntu {TABAN:.4f}")
kaynak gorev: 240 goruntu, etiket 1 orani 0.6292, kaynak gorevde dogruluk 1.0000 ve 0.9958

 etiket           sifirdan           dondurma          ince ayar
          kosum 1  kosum 2   kosum 1  kosum 2   kosum 1  kosum 2
     20    0.5188   0.5250    0.6312   0.5500    0.5938   0.5625
     60    0.6188   0.6625    0.5938   0.6250    0.6188   0.6250
    160    0.6125   0.6875    0.6000   0.5625    0.6188   0.6562
alanin tabani: en sik sinif 0.5312, ortalama goruntu 0.5500

Önceden eğitilmiş model burada bir depodan indirilmiyor, kurgu bir kaynak görevden üretiliyor. Kaynak görev, hedeften farklı 240 görüntü üzerinde “blok geniş mi” sorusudur ve bu görevin etiketi boldur. Gizli katmanın orada öğrendiği şey, bloğun yatay uzanımını okumaktır.

Yirmi etiketle sıfırdan eğitim 0,5188 ve 0,5250 okuyor: en sık sınıfın 0,5312’sinin ve ortalama görüntünün 0,5500’ünün altında. Aktarım aynı yirmi etiketle dondurmada 0,6312 ve 0,5500, ince ayarda 0,5938 ve 0,5625 veriyor. Ortalamalar üzerinden aktarımın kattığı fark dondurmada +0,0687, ince ayarda +0,0562.

Altmış etikette üstünlük kapanıyor (sıfırdan 0,6406, dondurma 0,6094, ince ayar 0,6219), yüz altmışta sıfırdan eğitim 0,6500 ile öne geçiyor ve dondurma 0,5812’de kalıyor. Sorunun ikinci yarısı — kaç örnekle — bu üç satırdan okunur: aktarımın üstünlüğü yirmi ile altmış etiket arasında tükeniyor. Kırk etiketlik bir aralık, bu kurguda önceden eğitilmiş bir modelin bütün değeridir.

Nedeni kaynak görevin ne öğrettiğindedir. “Blok geniş mi” sorusu gizli katmana bloğun yatay uzanımını okumayı öğretir; hedef görev ise yatay uzanımın dikey uzanımdan büyük olup olmadığını sorar. Kaynak, gereken iki ölçünün birini taşır, karşılaştırmayı taşımaz. Dondurulmuş bir katman veri arttıkça yerinde sayar, çünkü öğrenebileceği şey kaynak görevde donmuştur. M27/K05’in öğrenme aktarımı dersinde aynı desen bir tabloda ölçülmüştü: taban 0,6444 iken yirmi etiketle sıfırdan 0,7194, dondurma 0,8417, ince ayar 0,8083; ve dondurma dört ölçümde de düz durmuştu. Görüntüde ölçülen desen aynı, aradaki farklar daha küçüktür.

Bir sayı bu tablonun okunmasını sınırlıyor. Dondurmanın yirmi etiketteki iki koşumu 0,6312 ile 0,5500, aralarındaki açıklık 0,0812. Bu, aktarımın kattığı 0,0687’lik farktan büyüktür. Tek bir koşumun sayısını yazmak aktarımı olduğundan güçlü ya da olduğundan zayıf gösterirdi; iki koşum, farkın işaretine güvenilebileceğini ama büyüklüğüne güvenilemeyeceğini söylüyor.

Özet

  • Alanın tabanı bu görevde en sık sınıf 0,5312 ve ortalama görüntü 0,5500’dür; ikincisi 288 sayı saklar ve hiçbir yineleme yapmaz.
  • 1.169 parametreli ağ 144 pikselde iki koşumda da 0,6000 okur; 305 parametreli ağ havuzlanmış 36 sayıda 0,6687 ve 0,7063 okur. Dördü de eğitim kümesini 1,0000 ile ezberler.
  • Havuzlamanın kattığı 0,0875’lik fark temsilden gelir; aynı ağın iki koşumu arasındaki açıklık 0,0376’dır ve bu farkın yarısı kadardır.
  • Yirmi etiketle sıfırdan eğitim 0,5188 ve 0,5250 ile alanın tabanının altında kalır; kurgu bir kaynak görevden üretilen modelin dondurulması +0,0687, ince ayarı +0,0562 katar.
  • Altmış etikette üstünlük kapanır, yüz altmışta sıfırdan eğitim 0,6500 ile öne geçer ve dondurma 0,5812’de kalır.
  • Dondurmanın yirmi etiketteki iki koşumu arasındaki 0,0812’lik açıklık, aktarımın kattığı farktan büyüktür.

Sonraki Adım

Bu iki derste soru hep aynıydı: görüntüde ne var. Cevap tek bir sayıydı ve modelin bloğu bulması gerekmiyordu, yalnız yönünü söylemesi yeterliydi. Oysa kurgunun içinde bir kutu duruyor: her görüntüde bloğun satırı, sütunu, yüksekliği ve genişliği yazılı. Sonraki ders soruyu değiştirir — nesne nerede. Bu, yeni bir ölçüt gerektirir, çünkü iki kutunun ne kadar tuttuğunu doğruluk söyleyemez. Ve alanın tabanı da değişir: her görüntüye bakmadan aynı kutuyu söyleyen bir yordamın o ölçütte kaç aldığı, bu kursun en şaşırtıcı sayısıdır.

İ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